Saturday, February 25, 2017

Getting Full Disk Encryption With RAID, LUKS, LVM & BTRFS to work on SuSE Leap 42.2

We recently switched to Full Disk Encryption (FDE) for our company laptops and since the whole thing wasn't as easy as we had expected we would like to share our path to success ;)

The Requirements

We use laptops with 2 SSD disks and our goal was to be able to somehow have the whole OS on encrypted storage backed by a RAID1. Why? Because encrypting /home sometimes isn't good enough considering various locations in /tmp and /var that might contain sensitive data (installed packages, cache, database files). Of course it is perfectly possible to solve this using some effort on configuration, but this is certainly not fool-proof and future upgrades might revert changes done by the administrator.

The Problem

As of February 2017 the SuSE Leap 42.2 installer does not support such a configuration. You can either have encrypted LVM or LUKS on a RAID but not both.

I know how to Linux! Just give me a Shell!

If you have spent some time learning linux you have undoubtedly come across all the tools needed for this task, so of course our first idea was to prepare the disk setup manually and just point the installer to the right logical volumes. That should be easy enough!

Boot the SuSE Leap image in "Rescue" mode or use a sysrescuecd of your choice:

# cfdisk /dev/nvme0n1 ## GPT, create 512 MB EFI System partition, create Linux RAID partition with the remaining space
# cfdisk /dev/nvme1n1 ## same as above
# mdadm --create /dev/md0 --raid-devices 2 --level 1 /dev/nvme0n1p2 /dev/nvme1n1p2 ## create RAID1
# cryptsetup --type plain --cipher=aes-xts-plain64 --hash=sha512 --key-size=512  luksFormat /dev/md0
# cryptsetup luksOpen /dev/md0 raid
# pvcreate /dev/mapper/raid
# vgcreate vg /dev/mapper/raid
# lvcreate -L 8G vg -n swap
# lvcreate -L +100%FREE vg -n root

Then reboot to the SuSE Leap installer

  • luksOpen the raid device in a terminal (ctrl+alt+F2)
  • Expert partitioner
  • Rescan devices
  • /dev/nvme0n1p1 -> format as FAT, mount at /boot/efi
  • /dev/mapper/vg-swap -> format as swap
  • /dev/mapper/vg-root -> format as BTRFS, mount at /
  • Install
Upon finishing the installation, the installer will try to reboot into your newly installed system which will fail miserably.

The Cause

After a lot of researching, asking (thank you very much Andrei Borzenkov for pointing this out and for your your help and efforts) and experimenting we found that the installer, prior to writing the initrd for the newly installed kernel, does not create an /etc/crypttab file. The system will not know that it should open or even look for encrypted volumes and thus does not boot.

The Glorious WorkaroundSolution

Knowing this it's enough to create a crypttab file once the installation has started and all devices are mounted under /mnt. So after confirming the start of the installation procedure, go back to your text shell, vim /mnt/etc/crypttab and fill in the following line (corresponding to your setup):

# cat /mnt/etc/crypttab
raid   /dev/disk/by-uuid/d66e7557-0422-409b-91dd-6e242db3049b none none
This will make the rest of the installation work fine, if all else is correct ;)

A Dash Extra

After this procedure you will need to enter your passphrase twice (once for grub and once when trying to mount /) when booting. This is impractical and can be avoided with a nice little trick: storing a keyfile inside the encrypted file system. We didn't come up with this idea, but got it from various sources on the internet. Since some of them contained conflicting or (maybe for SuSE Leap) unnecessary steps, here's what we did:

# dd bs=512 count=4 iflag=fullblock if=/dev/random of=/boot/keyfile
# cryptsetup luksAddKey  /dev/md0 /boot/keyfile 
# cat /etc/crypttab
raid    /dev/disk/by-uuid/d66e7557-0422-409b-91dd-6e242db3049b /boot/keyfile none
# cat /etc/dracut.conf.d/10-crypt.conf
install_items+="/boot/keyfile" ## note that the quotes are important here
# dracut ## rebuild the initrd
Reboot your machine and you should only have to enter your passphrase once at the grub prompt.