Using a single passphrase to unlock multiple encrypted disks at boot
Debian based distributions:
Debian and Ubuntu ship a password caching script decrypt_keyctl with cryptsetup package.
decrypt_keyctl script provides the same password to multiple encrypted LUKS targets, saving you from typing it multiple times. It can be enabled in crypttab with keyscript=decrypt_keyctl
option. The same password is used for targets which have the same identifier in keyfile field. On boot password for each identifier is asked once.
An example crypttab:
<target> <source> <keyfile> <options>
part1_crypt /dev/disk/... crypt_disks luks,keyscript=decrypt_keyctl
part2_crypt /dev/disk/... crypt_disks luks,keyscript=decrypt_keyctl
The decrypt_keyctl
script depends on the keyutils
package (which is only suggested, and therefore not necessarily installed).
After you've updated your cryptab, you will also have to update initramfs to apply the changes. Use update-initramfs -u
.
Full readme for decrypt_keyctl is located in /usr/share/doc/cryptsetup/README.keyctl
Unfortunately, this currently doesn't work on Debian systems using systemd init due to a bug (other init systems should be unaffected). With this bug you're asked a second time for the password by systemd, making it impossible to unlock remotely via ssh. Debian crypttab man page suggests as a workaround to use initramfs
option to force processing in initramfs stage of boot. So to circumvent this bug an example for /etc/crypttab in Debian
<target> <source> <keyfile> <options>
part1_crypt /dev/disk/... crypt_disks luks,initramfs,keyscript=decrypt_keyctl
part2_crypt /dev/disk/... crypt_disks luks,initramfs,keyscript=decrypt_keyctl
Distributions which do not provide decrypt_keyctl script:
If decrypt_keyctrl isn't provided by your distribution, the device can be unlocked using a keyfile in encrypted root file system. This when root file system can be unlocked and mounted before of any other encrypted devices.
LUKS supports multiple key slots. This allows you to alternatively unlock the device using password if the key file is unavailable/lost.
Generate the key with random data and set its permissions to owner readable only to avoid leaking it. Note that the key file needs to be on the root partition which is unlocked first.
dd if=/dev/urandom of=<path to key file> bs=1024 count=1 chmod u=rw,g=,o= <path to key file>
Add the key to your LUKS device
cryptsetup luksAddKey <path to encrypted device> <path to key file>
Configure crypttab to use the key file. First line should be the root device, since devices are unlocked in same order as listed in crypttab. Use absolute paths for key files.
<target> <source> <keyfile> <options> root_crypt /dev/disk/... none luks part1_crypt /dev/disk/... <path to key file> luks
Another option is to use the /lib/cryptsetup/scripts/decrypt_derived
script, which is also part of cryptsetup in Debian/Ubuntu.
Instead of caching the key, you use the volume key of one disk as an additional password for the second disk. This requires adding a second password to the second (and third, etc) encrypted disk, but LUKS supports that. This solution therefore also works if your multiple encrypted disks do not use the same password.
Example to add the key from sda6crypt to sda5:
Add volume key of sda6crypt as additional password for sda5:
mkfifo fifo
/lib/cryptsetup/scripts/decrypt_derived sda6crypt > fifo &
cryptsetup luksAddKey /dev/sda5 fifo
rm fifo
Configure sda5crypt to be unlocked automatically in /etc/crypttab
ls -la /dev/disk/by-uuid/ | grep sda5
echo "sda5crypt UUID=<uuid> sda6crypt luks,initramfs,keyscript=/lib/cryptsetup/scripts/decrypt_derived" >> /etc/crypttab
This uses a named pipe (fifo
) to pass the key to avoid having to store the volume key in a temporary file on disk.
The keyscript
option only works if crypttab
is processed by Debian's original cryptsetup tools, the systemd reimplementation does not currently support it. If your system uses systemd (which is most systems), you need the initramfs
option to force processing to happen in the initrd by the cryptsetup tools, before systemd starts up.
Based on https://unix.stackexchange.com/a/32551/50793
Here is my workaround on debian, given the bug referenced above by @sebasth.
My setup is slightly different. I have an encrypted root partition and a bunch of raid disks. For me, I had to add a initramfs option to the crypttab:
<target> <source> <keyfile> <options>
part1_crypt /dev/disk/... crypt_disks plain,cipher=aes-xts-plain64,keyscript=decrypt_keyctl,initramfs
part2_crypt /dev/disk/... crypt_disks plain,cipher=aes-xts-plain64,keyscript=decrypt_keyctl,initramfs
This tells update-initramfs that I want to have these crypttab entries mounted in the initramfs. I checked my crypttab by running
cryptdisks_start part1_crypt
cryptdisks_start part2_crypt
Note that my raid disks are plain dm-crypt. This meant that I could not use the luks keyfile method that works around the systemd keyscript bug. For plain dm-crypt, I would have to store the passphrase in plaintext.
The package keyutils has to be installed and the encrypted disks have to be mounted before update-initramfs
is run ; otherwise it will throw errors. I had to look for the following lines when my initramfs was built:
update-initramfs -u -v | grep 'keyctl'
which showed the following two files:
/bin/keyctl
cryptkeyctl
being added to the initramfs.
Finally, I had to disable systemd handling my crypttab, to deal with the bug referenced above: systemd does not support the keyscript option in crypttab. For this, I added the kernel option
GRUB_CMDLINE_LINUX_DEFAULT="quiet luks.crypttab=no"
to /etc/default/grub and ran update-grub
. systemd now ignores crypttab, and all the encrypted partitions are loaded in the initramfs.
Because I have an encrypted root partition, cryptroot does not appear to cache my key. This means I have to enter my password twice; one for the root partition and once for my raid array.