I got myself stuck yesterday with GRUB running from an ext4 /boot/grub
, but with /boot
inside my LUKS LVM root partition, which meant GRUB couldn’t load the initramfs and kernel.
Luckily, it turns out that GRUB does know how to mount LUKS volumes (and LVM volumes), but all the instructions I could find talk about setting this up ahead of time (“Add GRUB_ENABLE_CRYPTODISK=y
to /etc/default/grub
“), rather than what the correct manual GRUB commands are to get things running on a failed boot.
These are my notes on that, in case I ever need to do this again, since there was one specific gotcha with using GRUB’s cryptomount
command (noted below).
Available devices were the raw disk (hd0)
, the /boot/grub
partition (hd0,msdos1)
, and the LUKS volume (hd0,msdos5)
:
grub> ls (hd0) (hd0,msdos1) (hd0,msdos5)
Used cryptomount
to open the LUKS volume (but without ()
s! It says it works if you use parens, but then you can’t use the resulting (crypto0)
):
grub> insmod luks grub> cryptomount hd0,msdos5 Enter password... Slot 0 opened.
Then you can load LVM and it’ll see inside the LUKS volume:
grub> insmod lvm grub> ls (crypto0) (hd0) (hd0,msdos1) (hd0,msdos5) (lvm/rootvg-rootlv)
And then I could boot normally:
grub> configfile $prefix/grub.cfg
After booting, I added GRUB_ENABLE_CRYPTODISK=y
to /etc/default/grub
and ran update-grub
. I could boot normally after that, though I’d be prompted twice for the LUKS passphrase (once by GRUB, then again by the initramfs).
To avoid this, it’s possible to add a second LUKS passphrase, contained in a file in the initramfs, as described here and works for Ubuntu and Debian too. The quick summary is:
Create the keyfile and add it to LUKS:
# dd bs=512 count=4 if=/dev/urandom of=/crypto_keyfile.bin # chmod 0400 /crypto_keyfile.bin # cryptsetup luksAddKey /dev/sda5 /crypto_keyfile.bin *enter original password*
Adjust the /etc/crypttab
to include passing the file via /bin/cat
:
sda5_crypt UUID=4aa5da72-8da6-11e7-8ac9-001cc008534d /crypto_keyfile.bin luks,keyscript=/bin/cat
Add an initramfs hook to copy the key file into the initramfs, keep non-root users from being able to read your initramfs, and trigger a rebuild:
# cat > /etc/initramfs-tools/hooks/crypto_keyfile <<EOF #!/bin/bash if [ "$1" = "prereqs" ] ; then cp /crypto_keyfile.bin "${DESTDIR}" fi EOF # chmod a+x /etc/initramfs-tools/hooks/crypto_keyfile # chmod 0700 /boot # update-initramfs -u
This has the downside of leaving a LUKS passphrase “in the clear” while you’re booted, but if someone has root, they can just get your dm-crypt
encryption key directly anyway:
# dmsetup table --showkeys sda5_crypt 0 155797496 crypt aes-cbc-essiv:sha256 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 8:5 2056
And of course if you’re worried about Evil Maid attacks, you’ll need a real static root of trust instead of doing full disk encryption passphrase prompting from an unverified /boot
partition. :)
© 2017, Kees Cook. This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 License.