58

My machine has an SSD, where I installed the system and an HDD, which I use as a storage for large and/or infrequently used files. Both are encrypted, but I chose to use the same passphrase for them. SSD is mounted at / and HDD at /usr/hdd (individual users each have a directory on it and can symlink as they like from home directory).

When the system is booted, it immediately asks for passphrase for the SSD, and just a couple seconds later for the one for HDD (it is auto-mounted). Given that both passphrases are the same, is there a way to configure the system to ask just once?

5
  • You could possibly write an expect script or similar that gets called to mount the disks instead of having the system do it. Instead, the system would call the script which would ask for the password, store it, and provide it to each of the mount operations.
    – h3rrmiller
    Commented Sep 14, 2017 at 19:04
  • If I understand your idea correctly, it cannot be applied to the SSD, since that's where the system boots from. But then it becomes pointless, as I still would need to type the passphrase for the HDD separately. Or no?
    – user116402
    Commented Sep 14, 2017 at 19:05
  • 1
    You can use /etc/crypttab to unlock the second drive.
    – jasonwryan
    Commented Sep 14, 2017 at 19:08
  • 2
    @jasonwryan if that can be expanded to an answer then ... answers should be posted as answers, not comments.
    – derobert
    Commented Sep 14, 2017 at 19:10
  • 1
    @derobert sometimes people don't have the time, or the inclination, to write up a good answer.
    – jasonwryan
    Commented Sep 15, 2017 at 7:13

4 Answers 4

60

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


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.

  1. 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>
    
  2. Add the key to your LUKS device

     cryptsetup luksAddKey <path to encrypted device> <path to key file>
    
  3. 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
    
20
  • 2
    To see what initramfs contains: lsinitramfs /boot/initrd.img-$(uname -r)
    – sebasth
    Commented Sep 16, 2017 at 11:53
  • 8
    Uh, sorry, now that I paid more attention to what update-initramfs said, I noticed this: E: /usr/share/initramfs-tools/hooks/cryptkeyctl failed with return 1.. After a bit of googling, I found out that I probably need keyutils package (really was not installed). Now update-initramfs succeeds and lsinitramfs does mention decrypt_keytls. Will update after the next boot (likely tomorrow).
    – user116402
    Commented Sep 16, 2017 at 12:38
  • 3
    Tried in Linux Mint 19 (based on Ubuntu 18.04): just having the same password for both devices in /etc/crypttab was enough for the system to ask for password just once on boot at first. But once I added the second device as a new PV to the root LV (with LVM), the system started to ask for the same password twice at boot (probably because it could not read the root partition any more until both devices were unlocked?). Using decrypt_keyctl works then, so the mentioned systemd bug must have been fixed meanwhile. Commented Jun 24, 2020 at 18:34
  • 1
    Tested the luks,initramfs,keyscript=decrypt_keyctl crypttab options on Ubuntu 20.04 and I can confirm that the initramfs option workaround works as described. Commented Nov 28, 2020 at 23:19
  • 1
    On Debian 12 decrypt_keyctl works without any workaround. Commented Sep 8, 2023 at 21:37
5

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

4
  • Gotta say this a beautiful solution Worked right off the bat no hiccups on debian 10 buster!
    – J-a-n-u-s
    Commented Jul 22, 2019 at 21:01
  • 1
    If your distribution provides decrypt_keyctl and that works for you, you should probably use that in favor of decrypt_derived. It also works with luks2 and doesn't remember the password for more than 60 seconds. If decrypt_keyctl does not work for you, I would say using decrypt_derived is preferable to using a regular keyfile.
    – JanKanis
    Commented Dec 31, 2020 at 15:19
  • 1
    As @JanKanis hinted, it looks like decrypt_derived is completely broken for LUKS2. Does anyone have more details on this? I just get /lib/cryptsetup/scripts/decrypt_derived: device sda3_crypt uses the kernel keyring. I need a way to unlock a disk which is connected later, after the 60 seconds.
    – bitinerant
    Commented Dec 31, 2020 at 18:33
  • @bitinerant decrypt_keyctl is a shellscript that uses the kernel keyring through keyctl. There is probably some way to change the timeout. Or you could write a script that retrieves the luks2 key from the kernel keyring.
    – JanKanis
    Commented Dec 31, 2020 at 22:13
3

Just in case this helps anyone out: this should just happen on most systemd based systems now.

On Fedora with Plymouth, this behavior just happens automatically with the default setup.

    * The "ask-password" framework used to query for LUKS harddisk
      passwords or SSL passwords during boot gained support for
      caching passwords in the kernel keyring, if it is
      available. This makes sure that the user only has to type in
      a passphrase once if there are multiple objects to unlock
      with the same one. Previously, such password caching was
      available only when Plymouth was used; this moves the
      caching logic into the systemd codebase itself. The
      "systemd-ask-password" utility gained a new --keyname=
      switch to control which kernel keyring key to use for
      caching a password in. This functionality is also useful for
      enabling display managers such as gdm to automatically
      unlock the user's GNOME keyring if its passphrase, the
      user's password and the harddisk password are the same, if
      gdm-autologin is used.

https://lists.freedesktop.org/archives/systemd-devel/2015-October/034509.html

2

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.

2
  • So, you did all this for nothing? You still have to enter multiple passwords. Commented Jan 27, 2020 at 14:40
  • No, once for the root partition and once for the 4 disk raid array. I cannot get it to just take one password for the root partition and raid array. There is probably a way to do this by editing the debian initramfs scripts.
    – user128063
    Commented Feb 12, 2020 at 2:42

You must log in to answer this question.