This guide is aimed at helping those with a librebooted/corebooted system to take advantage of full disk encryption with LUKS2. By the end of this guide you should have a system with an encrypted boot and root partition which will lock your root partition on suspend.
If you follow this guide then all your data will be encrypted when your computer is off. Encrypting the boot partition according to this guide will also make your machine rootkit resistant. With an unencrypted boot partition, an attacker could insert malicious code to save and transmit your root key on boot - totally defeating the purpose of full disk encryption.
Note: You will have to use a less secure encryption method for the boot partition due to the current limitation of GRUB2. An attacker could, given sufficient time, brute force your boot partition to reveal the key. As long as you use a different key for your root partition, this brute force attack would not compromise your documents/programs. You should therefore use a much stronger and totally different key for your root partition.
Use case/Motivation: This guide is useful for anyone who wants to secure against:
Encrypting partitions on an existing machine will cause GRUB to fail until you’ve edited its configuration appropriately. If you’re coming from an existing system, you should keep a backup of your existing boot partition unencrypted. Doing this means that during reboot you can simply change the ‘set root’ directive to point to your backup. For example, if you create a new encrypted boot partition /dev/sda1 and backup your existing partition to /dev/sda3 then you can press ‘e’ at the grub menu and change the command:
set root=(ahci0,msdos1) # old
set root=(ahci0,msdos3) # new
You will then be able to boot normally by pressing F10. NOTE: the partition names in grub will depend on what type of disk you use.
The rest of this guide assumes that you’re prepared to totally wipe your disk and install trisquel. The guide also assumes you’ve prepared your trisquel live media and booted it up. Make sure to select the default boot entry when starting up the install media.
I recommend creating a separate boot and root partition. Grub2 currently (Oct 2021) supports luks2 encryption, which is great, but only the (not very strong) PBKDF2 algorithm. This means that you could create one single disk to cut down on password entries, but the entire disk would have to be less secure. Instead, we’ll create a purposely less secure /boot partition and a very secure root partition. Start by creating a boot partition of around 1GB, you don’t have to format it to anything as LUKS will overwrite it anyway. If you’re lost on how to do this, Gparted is a simple graphical program that comes with the parabola installer and will make things very easy. Now that you have your new boot partition, you can proceed. You can use Gparted from the trisquel live media. When you’re done partitioning, you should have /dev/sdx1 as a 1GB partition, and the rest of the free space should be set to a single unformatted partition.
Step 1: Create a LUKS2 formatted device with the PBKDF2 algorithm. You can play around with the iteration count. A higher iteration is more secure but will take GRUB a very long time to decrypt. The debian encrypted boot guide recommends a count of 500,000 which will still take GRUB a very long time (around 25 seconds) but is faster than the default 1000,000. Use whatever count makes you feel comfortable. I’ll use and arbitrarily low count. You’ll also want to use a different password than you intend to use (or already use) for your root partition. We don’t want someone to be able to get our root key by brute-forcing our less secure boot key.
sudo cryptsetup luksFormat /dev/sda1 --type luks2 --pbkdf pbkdf2 --pbkdf-force-iterations 200000
Step 2: Open the luks container. Format the mapped drive to ext4.
sudo cryptsetup luksOpen /dev/sda1 boot
sudo mkfs.ext4 -L boot /dev/mapper/boot
Note: If you wish to change the passphrase for the boot partition in the future then you’ll need to pass the same arguments to cryptsetup as when you created it. If you don’t pass any special arguments, the key will be changed to the distro’s default encryption and grub won’t be able to decrypt it. The command to use is:
cryptsetup luksChangeKey /dev/sda1 --type luks2 --pbkdf pbkdf2 --pbkdf-force-iterations 200000
The graphical installer that ships with trisquel can handle encrypting your root partition automatically. You can just follow the instructions in the installer without modification for the most part. When you get to the partitioning stage, you’ll need to deselect ‘erase disk and install trisquel’ and instead choose ‘something else.’
Step 1: Identify your boot partition in the partitions list. Make sure to select ‘/dev/mapper/boot’ rather than ‘/dev/sda1.’ The former is the virtual partition inside the luks container. Right click the partition and select the ‘change’ option.
Step 2: Apply the following changes and then press ‘ok’
Step 3: Set up your root partition. Select the remaining free space/the other partition you set up before. Select ‘change’ as before, but select use as ‘physical volume for encryption.’ The installer does most of the heavy lifting for you; so you can just use all of the defaults.
Step 4: After setting up the cryptodisk for you, the partitions list will update and you should see a new partition with the type ‘crypto.’ Select the new crypto partition, select ‘change,’ format to your favourite filesystem and set the mount point to ‘/’
Step 5: Click ‘Install Now’ and let the installer set everything up for you.
At this point, your system is bootable, but more work is still needed. You can reboot and do the rest of the work from your installed system.
The device holding the kernel (and the initramfs image) is unlocked by GRUB, but the root device needs to be unlocked again at initramfs stage, regardless whether it’s the same device or not. This is because GRUB boots with the given vmlinuz and initramfs images, but there is currently no way to securely pass cryptographic material (or Device Mapper information) to the kernel. Hence the Device Mapper table is initially empty at initramfs stage; in other words, all devices are locked, and the root device needs to be unlocked again.
Step 1: Here, we’re not trying to store the root key as we don’t want to jeopardize the integrity of our root device. Instead, we want to store the key for the boot device.
sudo mkdir -m0700 /etc/keys
sudo dd if=/dev/urandom bs=1 count=64 of=/etc/keys/boot.key conv=excl,fsync
sudo chmod 0077 /etc/keys/boot.key
sudo cryptsetup luksAddKey /dev/sda1 /etc/keys/boot.key
Step 2: Add your boot device to your crypttab.
sudo cryptsetup luksOpen /dev/sda1 boot_crypt
sudo vim /etc/crypttab
> boot_crypt /dev/sda1 /etc/keys/boot.key luks,discard,key-slot=1
Step 3: Add the crypt device to your fstab. Use ‘mount -a’ to test your fstab configuration. NOTE: you will not be able to mount the device until it has been unlocked and mapped, rebooting with your new crypttab should do this automatically.
sudo vim /etc/fstab
> /dev/mapper/boot_crypt /boot ext4 defaults 0 1
sudo mount -a
Step 4: On my install, files in the boot partition were sometimes set to read only. I don’t know why that is, but I would recommend at least changing grub.cfg to rw for root.
sudo chmod 600 /boot/grub/grub.cfg