Cryptroot
Encrypted / filesystem
Ubuntu's 18.04 installer makes it possible to setup an encrypted root file system, but doesn't provide a way to automatically decrypt it. update-initramfs
skips /etc/crypttab entries for /, and the dracut scripts in the initrd ignore any /etc/crypttab that is installed. Additionally, putting the key directly into the initramfs is not a good idea since it would live in the clear on the /boot partition.
The script in /scripts/local-top/cryptroot
also ignores the cryptotops=key=/path/to/key
argument and will always read from stdin. To work around this it is necessary to also use a keyscript argument, but not cat directly since it special cases that and will fail to mount the root. /bin/cat
instead bypasses that check.
What worked for me:
cryptopts=key=/root.key,source=/dev/vda5,target=sda5_crypt,keyscript=/bin/cat,lvm=yes
However, It turns out that that if you set some config in /etc/initramfs-rools/initramfs.conf
and /etc/cryptsetup-initramfs/conf-hook
as well as create key files on the disk and update the /etc/crypttab
to point to them, then update-initramfs
will copy them into the initrd. However, it gives zero errors if things are not correctly to its liking, etc. If all goes well it will create /conf/conf.d/cryptroot
configuration file with essentially the same arguments above and with the keyfile in /cryptroot-keyfiles
. Very unintuitive and also has three drawbacks: the key is stored in plaintext on the root filesystem, it ends up putting the key material in the initrd also in plaintext, and the initrd is to now specific to this machine and can't be shared between multiple machines.
This does, however, show how to store the configuration in an initrd that can be provided with the config if the kernel options are a problem. It does make for a more complicated auxillary initrd since /conf/conf.d/cryptroot and /cryptroot-keyfiles/root.key have to be created:
mkdir -p test-initrd/cryptroot-keyfiles echo -n 'abcd@1234!' > test-initrd/cryptroot-keyfiles/sda5_crypt.key mkdir -p test-initrd/conf/conf.d/ echo 'target=sda5_crypt,source=/dev/sda5,rootdev,lvm=test--vg-root,discard,keyscript=cat,key=/cryptroot-keyfiles/sda5_crypt.key' > test-initrd/conf/conf.d/cryptroot ( cd test-initrd ; find . | cpio -H newc -ov ) > test-initrd.cpio . ./cryptroot-keyfiles ./cryptroot-keyfiles/sda5_crypt.key ./conf ./conf/conf.d ./conf/conf.d/cryptroot 2 blocks
PXE booting the keys
One way to deliver the keys to the kernel is via a PXE server. This has some security concerns since the keys will be transmitted in the clear, the keys are accessible to any other machines on the network, etc, but those can be worked around with filtering or moving to a more sophisticated attestation and key management system. This is just to show how to can be done.
The important trick is that iPXE can handle multiple initrd arguments and will download all of them. The generic initrd can be used by all the machines and the keys can be placed into device specific files. To create the key initrd, place the passphrase in a file with no newline and then use cpio to create the file in the tftp directory:
echo -n secretpassword > root.key echo root.key | cpio -H newc -o > hostname.cpio
Create a iPXE config file that will be served to the machine:
#!ipxe kernel ubuntu-18.04/vmlinuz-4.15.0-55-generic root=/dev/mapper/test--vg-root ro console=ttyS0 _rdinit=/bin/sh cryptopts=key=/root.key,source=/dev/sda5,target=sda5_crypt,keyscript=/bin/cat,lvm=yes initrd ubuntu-18.04/initrd.img-4.15.0-55-generic initrd keys/${net0.dhcp/hostname}.cpio boot
Heads as a bootloader
Heads is a better way to do this since it can interface with the TPM, the network and participate in a much richer attestation protocol. To be written.
External links
- dracut ignores crypttab keyfile (redhat 2011, fixed? then broken again in 2014)
- Debian encrypted root partition (2018)
- Why my encrypted LVM volume won't mount at boot time?
- initramfs cryptroot (http://forums.debian.net/viewtopic.php?t=74232)