Scenario
- You want to unlock a system remotely during boot process.
- Your root partition is a LVM volume.
- Your LVM setup is fully encrypted with LUKS.
- You’re running Debian on the remote system.
How To
If your Linux is running on a disk with LUKS encryption and you’re annoyed to enter a passphrase by keyboard to unlock your LUKS root device on every boot, this guide might be right for you.
It shows how to unlock your root devices using a keyfile from an USB drive.
NOTE: The keyfile on your USB drive is stored UNENCRYPTED. If you lose your USB key you MUST delete the corresponding slot from the LUKS device and add a new one.
The guide is tested against Debian 9.6 (Stretch) which uses cryptsetup 1.7.3.
In my setup the root device is a logical volume located on a LVM volume group.
First, install your system with Debian and run the basic configuration.
During the installation process you add a passphrase as key to your LUKS device. This passphrase is required to add further keys to the device. I recommend to keep a passphrase as fallback option if you lose your new USB key. But an existing short passphrase should be replaced by a longer passphrase later (cryptsetup luksChangeKey <your_luks_device>).
To create an USB key to unlock LUKS, attach an USB device to your system an run the commands below:
- Get the name of your USB device just attached and set path to LUKS device and the mapper name used
dmesg | grep usb USB_DEVICE=/dev/sdb cat /etc/crypttab LUKS_DEVICE=/dev/sda3 LUKS_MAPPER_NAME=sda3_crypt
- Format your USB device and create a filesystem on it
# WARNING: Existing data on your USB device will be erased!!! fdisk ${USB_DEVICE} <<EOF o n p 1 +64M w EOF mkfs.ext4 ${USB_DEVICE}1 mkdir /root/usbkey-${LUKS_MAPPER_NAME} mount ${USB_DEVICE}1 /root/usbkey-${LUKS_MAPPER_NAME}
- Generate a keyfile from random data
dd if=/dev/urandom of=/root/usbkey-${LUKS_MAPPER_NAME}/${LUKS_MAPPER_NAME} bs=1M count=4
- Add the new keyfile to your device
cryptsetup luksAddKey ${LUKS_DEVICE} /root/usbkey-${LUKS_MAPPER_NAME}/${LUKS_MAPPER_NAME} # -> enter your existing passphrase here cryptsetup luksDump ${LUKS_DEVICE} umount /root/usbkey-${LUKS_MAPPER_NAME}
- Change unlock options for your LUKS device
blkid | grep ${USB_DEVICE}1 sed -i "s@^\(${LUKS_MAPPER_NAME} .*\) none luks@\1 /dev/disk/by-uuid/$(blkid | grep ${USB_DEVICE}1 | cut -d'"' -f2):/${LUKS_MAPPER_NAME} luks,keyscript=/lib/cryptsetup/scripts/passdev@" /etc/crypttab cat /etc/crypttab
- Your /etc/crypttab may look like this now:
sda3_crypt UUID=f9aefe4-13f0-1256-9309-8daeee9c127a /dev/disk/by-uuid/99821e18-abcd-de00-2156-e410836baba1:/sda3_crypt luks,keyscript=/lib/cryptsetup/scripts/passdev
- Don’t forget to update all init disks with new crypttab entry and reboot your system:
update-initramfs -k all -u reboot
The script passdev defined by keyscript pauses the boot and waits for a device with the given UUID (first part of 3rd field from /etc/crypttab).
When the device appears, it’s temporarilly mounted and the path defined in the second part of 3rd field from /etc/crypttab is used as the keyfile to unlock the LUKS device.
Notes
After LUKS is unlocked you should remove to USB key, cause the USB key device could may be accessed during normal system runtime by processes running with higher permissions as expected.
References
- man 8 cryptsetup
- man 5 crypttab
- https://askubuntu.com/questions/59487/how-to-configure-lvm-luks-to-autodecrypt-partition/90911#90911
- https://salsa.debian.org/cryptsetup-team/cryptsetup/blob/master/debian/README.Debian [added 19.11.2018]
- https://salsa.debian.org/cryptsetup-team/cryptsetup/blob/master/debian/README.initramfs [added 19.11.2018]
- https://salsa.debian.org/cryptsetup-team/cryptsetup/blob/master/debian/scripts/passdev.c [added 19.11.2018]