Slackware LVM over LUKS

This is mostly a post to document my process of setting up Full Disk Encryption (FDE) using the Linux Unified Key Setup (LUKS) and the Logical Volume Manager (LVM). Most major distributions already enable this process at installation, however Slackware does not and it must be done by hand. I am going to use an unencrypted boot partition. My boot manager does not currently support booting a LUKS container. Sometime in the future I will consider a rebuild of my laptop using grub2, which has support for LUKS and LVM.

Note: I am going to omit most of the installation steps and focus more on the procedures for getting LUKS/LVM up and running.

Boot the Slackware install media in UEFI mode then check which disks are visible:

root@slackware:/# lsblk
NAME MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda    8:0    0   40G  0 disk 
sr0   11:0    1  2.6G  0 rom  

The first thing we need to do is to overwrite ALL data on the entire disk with crypto-grade randomness. This will serve to mitigate cryptographic attacks, since it will be difficult to tell the random data from the encrypted data in your LUKS container.

cryptsetup open --type plain -d /dev/urandom /dev/sda erase_disk

Warning: Pay close attention to the disk you select, especially if you have multiple attached storage devices. This process will overwrite ALL data on the target disk.

Now fill the container with zeros.

root@slack # dd if=/dev/zero of=/dev/mapper/erase_disk bs=1M

Depending on the size of the disk you could be waiting for a while, but this method is significantly faster than using only dd and /dev/urandom to sanitize a disk.

Once it completes close the container.

root@slackware:/# cryptsetup close erase_disk

Use gdisk to setup two partitions. The unencrypted EFI boot partition and the LVM partition that will be encrypted. The recommended size for the boot partition varies by operating system, however I usually go with 513MB.

root@slackware:/# gdisk /dev/sda

Command (? for help): n
Partition number (1-128, default 1):
First sector (34-41943006, default = 2048) or (+-}size{KMGTP}:
Last sector (2048-41943006, default = 41943006) or {+-}size KMGTP}: 513M
Current type is ‘Linux filesystem’
Hex code or GUID (L to show codes, Enter = 8300): ef00
Changed type of partition to ‘EFI System’

Then create the LVM partition using the rest of the disk space.

Command (? for help): n
Partition number (2-128, default 2):
First sector (34-41943006, default = 1052672) or (+-3}size(KMGTP}:
Last sector (1052672-41943006, default = 41943006) or (+-}size{KMGTP?}:
Current tupe is ‘Linux filesystem’
Hex code or GUID (L to show codes, Enter = 8300): 8e00
Changed tupe of partition to ‘Linux LVM‘

Write the changes and exit. Then take a look at the devices.

root@slackware:/# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   40G  0 disk 
|-sda1   8:1    0  512M  0 part 
`-sda2   8:2    0 39.5G  0 part 
sr0     11:0    1  2.6G  0 rom  

Now setup the encrypted container on /dev/sda2. Use a strong password when prompted.

cryptsetup --cipher aes-xts-plain64 --key-size 512 \
--hash sha512 --iter-time 5000 -v luksFormat /dev/sda2

Open the container so we can setup LVM.

cryptsetup open --type luks /dev/sda2 slack

Looking at our devices again we can see our crypt container.

root@slackware:/# lsblk
NAME      MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda         8:0    0   40G  0 disk  
|-sda1      8:1    0  512M  0 part  
`-sda2      8:2    0 39.5G  0 part  
  `-slack 251:0    0 39.5G  0 crypt 
sr0        11:0    1  2.6G  0 rom

First step for LVM setup is to create our physical volume.

root@slackware:/# pvcreate /dev/mapper/slack

Then we create our volume group.

root@slackware:/# vgcreate slackvg /dev/mapper/slack

The Common Configuration Enumeration (CCE) recommends creating multiple partitions or logical volumes for system directories such as /tmp, /var/log, /home, etc. This segmentation enables the ability to select restrictive mount options, which helps to mitigate various file system attacks.

I tend to create six logical volumes: root, home, var, tmp, log, and swap

lvcreate -L 12G slackvg -n root
lvcreate -L  1G slackvg -n swap
lvcreate -L 20G slackvg -n home
lvcreate -L  2G slackvg -n var
lvcreate -L  1G slackvg -n tmp
lvcreate -L  1G slackvg -n log

Then format the swap space:

root@slackware:/# mkswap -L swap /dev/mapper/slackvg-swap

Format and install a filesystem. I am using xfs.

root@slackware:/# for i in /dev/mapper/slackvg-{root,tmp,var,home,log}; 
 do mkfs.xfs $i done

When we take a look at the logical volumes we get:

root@slackware:/# lvs
  LV   VG      Attr       LSize  Pool Origin
  home slackvg -wi-a----- 20.00g                                                    
  log  slackvg -wi-a-----  1.00g                                                    
  root slackvg -wi-a----- 12.00g                                                    
  swap slackvg -wi-a-----  1.00g                                                    
  tmp  slackvg -wi-a-----  1.00g                                                    
  var  slackvg -wi-a-----  2.00g

Now run setup. If you booted in UEFI mode, then when prompted, skip the LILO install. Then select yes, when the Slackware installer detects and asks to format the EFI partition.

Now finish the installation, but do not reboot. Exit to the command prompt and take a look at our disk configuration.

root@slackware:/# lsblk
NAME               MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda                  8:0    0   40G  0 disk  
|-sda1               8:1    0  512M  0 part  /mnt/boot/efi
`-sda2               8:2    0 39.5G  0 part  
  `-slack          251:0    0 39.5G  0 crypt 
    |-slackvg-swap 251:1    0    1G  0 lvm   [SWAP]
    |-slackvg-root 251:2    0   12G  0 lvm   /mnt
    |-slackvg-var  251:3    0    2G  0 lvm   /mnt/var
    |-slackvg-tmp  251:4    0    1G  0 lvm   /mnt/tmp
    |-slackvg-log  251:5    0    1G  0 lvm   /mnt/var/log
    `-slackvg-home 251:6    0   20G  0 lvm   /mnt/home
sr0                 11:0    1  2.6G  0 rom   

Double check the filesystem types and mount options

root@slackware:/# mount
/dev/initramfs on / type tmpfs (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
tmpfs on /dev/shm type tmpfs (rw)
/dev/mapper/slackvg-root on /mnt type xfs (rw)
/dev/mapper/slackvg-home on /mnt/home type xfs (rw)
/dev/mapper/slackvg-log on /mnt/var/log type xfs (rw)
/dev/mapper/slackvg-tmp on /mnt/tmp type xfs (rw)
/dev/mapper/slackvg-var on /mnt/var type xfs (rw)
/dev/sda1 on /mnt/boot/efi type vfat (rw)
/proc on /mnt/proc type none (rw,bind)
/sys on /mnt/sys type none (rw,bind)
/dev on /mnt/dev type none (rw,bind)

Notice that our filesystems are mounted under /mnt so we need to chroot before we continue.

root@slackware:/# chroot /mnt

Once everything looks correct, it is time to setup our Initial RAM Disk (initrd.gz) to support LUKS, LVM, and XFS. Slackware comes bundled with a script that helps to determine what you need:

 /usr/share/mkinitrd/mkinitrd_command_generator.sh

The shell script above can get you most of the way there, but I needed to tweak it a bit.

mkinitrd -c -k 4.4.14 -f xfs -r /dev/mapper/luksroot -m xfs -C /dev/sda2 -L -u

Note: I found that ‘luks’ gets prepended to the root device which you will only see once the system boots

Copy the initial ram disk to the efi directory and remove the huge kernel, it will not work with a ram disk.

cp /boot/initrd.gz /boot/efi/EFI/Slackware/
cp /boot/vmlinuz-generic-4.4.14 /boot/efi/EFI/Slackware
rm /boot/efi/EFI/Slackware/vmlinuz
cd /boot/efi/EFI/Slackware
mv vmlinuz-generic-4.4.14 vmlinuz

Edit elilo.conf to reflect your use case:

chooser=simple
delay=18
timeout=120
#
image=vmlinuz
        label=vmlinuz
        initrd=initrd.gz
        read-only
        append="root=/dev/mapper/luksroot vt.default_utf8=1 vga=normal ro"

Now when you reboot you will be eventually prompted for your password to unlock your LUKS container.

When you upgrade the kernel, generate a new initrd.gz and copy the new kernel and initrd to

/boot/efi/EFI/Slackware

Modify elilo.conf to reflect the new kernel. Keep the old kernel around until a successful boot with the new kernel.

Thanks for reading.

Start a discussion or ask a question.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: