Jörg Rödel's Blog

Linux and Confidential Computing

12 Aug 2021

Setting up Full Disk Encryption on openSUSE Tumbleweed

This article explains how to setup disk encryption on openSUSE Tumbleweed so that the the kernel and the initrd are also encrypted. The initrd will be set up to not ask for the password again.

DISCLAIMER: Backup all your data before trying out the instructions below. Data loss could occur if something goes wrong!

TL;DR

For the impatient reader, here is the list of commands to get disk encryption automatically set up in the initrd. Before starting make sure the these requirements are met:

  • Your system boots via UEFI
  • Full disk encryption is already set up and configured and the kernel and initrd are also on the encrypted partition
  • Tumbleweed is configured to boot via the EFI GRUB, which means GRUB runs as an EFI application

With these requirements met, the commands below will configure automatic key setup in the initrd. The important setting is $NAME, which contains the name of the encrypted volume. This name can be found with the lsblk command and is likely different on your system.

# lsblk
NAME                                                    MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda                                                       8:0    0   32G  0 disk  
├─sda1                                                    8:1    0  512M  0 part  /boot/efi
└─sda2                                                    8:2    0 31.5G  0 part  
  └─cr_scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-0-part2 254:0    0 31.5G  0 crypt 
    ├─system-root                                       254:1    0 29.5G  0 lvm   /
    └─system-swap                                       254:2    0    2G  0 lvm   [SWAP]
# NAME='cr_scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-0-part2'
# mkdir /etc/cryptsetup-keys.d
# chmod 700 /etc/cryptsetup-keys.d
# dd if=/dev/random bs=256 count=1 of=/etc/cryptsetup-keys.d/$NAME.key
# chmod 400 /etc/cryptsetup-keys.d/$NAME.key 
# cryptsetup luksAddKey /dev/sda2 /etc/cryptsetup-keys.d/$NAME.key
# echo 'install_items+=" /etc/cryptsetup-keys.d/* "' >> /etc/dracut.conf
# dracut -f
# echo "GRUB_CMDLINE_LINUX+=\" rd.luks.name=$NAME\"" >> /etc/default/grub
# update-bootloader

For more information on what these commands do and why, and how to install Tumbleweed with full disk encryption, read below.

Before We Start

Full disk encryption can be annoying with Linux, because in order to boot the user needs to enter the disk password twice. The first time is in Grub and later Linux will ask again for it. There are two ways around that:

  1. Add an unencrypted partition for /boot so that Grub can load the Linux kernel without needing a password. This is convenient, because the user only needs to enter the password once. On the other side this is not the most secure solution because an attacker with physical access to the machine can replace the kernel on the disk without notice.

  2. Encrypt everything, including /boot. This is more secure, as nobody without the disk encryption key can make changes to the kernel or initrd. On the other side, the disk password needs to be entered twice.

Fortunately cryptsetup and systemd offer an option to provide the encryption key in a key file during boot. This doesn’t harm security because the initrd is stored encrypted, so an attacker can’t easily gain the key.

But this means that the Grub binary itself needs to be stored unencrypted. On most modern systems this happens automatically when they are booted via UEFI. The Grub binary will be installed on the UEFI partition, which is still unencrypted.

The later sections explain how to set this up in openSUSE Tumbleweed, but first I will show how to set up full disk encryption during installation.

Install Tumbleweed to an Encrypted Disk

In the Tumbleweed installer the partitions of the system need to be specified at some point. The installer will provide a default configuration, like seen in the picture below.

1png

The default configuration will not set up disk encryption in any form, so click on Guided Setup to change the default. On the next screen (shown below), select Enable Logical Volume Management (LVM) and Enable Disk Encryption and enter a secure password for the disk.

2png

Using LVM has the benefit that all partitions (or rather logical volumes) can be put into one encrypted container. Entering one password will unlock the data partitions and the swap space. When the password is entered, click on Next to configure the filesystem options.

3png

In this screen you can configure the root file system type, a separate home partition and the size of the swap space. I did not change the defaults, but changes here do not affect encryption.

4png

When done, the final partition scheme should look like this. It contains the encrypted volume group and the volumes for the root filesystem and swap space.

After the installation is finished and the system boots for the first time, Grub will ask for the disk password. After the kernel is selected in the Grub menu, Linux will ask again for the same password to unlock its root filesystem.

The next section covers how to setup the system so that Linux will not ask for a password again.

Configure Automatic Key Setup in the Initrd

Setting up automatic key setup during boot requires to generate a new initrd and grub configuration file. But first we need the name of the encrypted volume. The lsblk command will show it:

# lsblk
NAME                                                    MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda                                                       8:0    0   32G  0 disk  
├─sda1                                                    8:1    0  512M  0 part  /boot/efi
└─sda2                                                    8:2    0 31.5G  0 part  
  └─cr_scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-0-part2 254:0    0 31.5G  0 crypt 
    ├─system-root                                       254:1    0 29.5G  0 lvm   /
    └─system-swap                                       254:2    0    2G  0 lvm   [SWAP]

In the output we can see that the name of the encrypted volume is cr_scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-0-part2. In your setup the name is likely different, but the following examples will use this name. The encrypted block device uses the physical block device sda2 as backing storage. So sda2 also contains the LUKS header.

Preparing the Disk Encryption Key

At boot, systemd will look into the /etc/cryptsetup-keys.d/ directory to find the keys for encrypted block devices. For each device a key file must exist which is named $NAME.key.

First of all, the directory needs to be created and configured with the right permissions:

# mkdir /etc/cryptsetup-keys.d
# chmod 700 /etc/cryptsetup-keys.d

Then the key file for the encrypted block device must be generated. In fact, every file would do, and cryptsetup will take whatever binary data it finds in the file. I used this command to generate a random key. Don’t forget to set the right permissions on the key file:

# dd if=/dev/random bs=256 count=1 of=/etc/cryptsetup-keys.d/cr_scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-0-part2.key
# chmod 400 /etc/cryptsetup-keys.d/cr_scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-0-part2.key 

When the file is generated the key must be added to the LUKS header of the backing device. In our case this is /dev/sda2:

# cryptsetup luksAddKey /dev/sda2 /etc/cryptsetup-keys.d/cr_scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-0-part2.key

This command will ask for the disk encryption password and add the generated key as an alternative key to the LUKS header.

Generating a new Initrd

Next, the key file needs to be included into the initrd. On openSUSE Tumbleweed the initrd is created with dracut. Tell dracut to add the key file directory to the initrd with this command:

# echo 'install_items+=" /etc/cryptsetup-keys.d/* "' >> /etc/dracut.conf

Note the leading and trailing whitespaces at the directory wildcard string. These are important and must not be omitted.

After that, regenerate the initrd with:

# dracut -f

In the last step the Grub configuration must be updated to add an additional kernel boot parameter.

Updating the Grub Configuration

The initrd will evaluate the kernel command line when deciding which devices to setup for decryption. For this, edit the /etc/default/grub file and add rd.luks.name=$NAME to the kernel command line parameters. Replace $NAME with the name of your encrypted block device. In the example used here, it looks like this:

# grep GRUB_CMDLINE_LINUX= /etc/default/grub
GRUB_CMDLINE_LINUX="rd.luks.name=cr_scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-0-part2"

When this is added, update the boot loader with:

# update-bootloader

Now the system is configured for automatic key setup during boot in the initrd. When you reboot the system there will be a password prompt from Grub, but Linux will not prompt for the password again.

Enjoy your disk encryption setup and don’t forget to have a lot of fun 😎