7

This question has been answered in the answer section, after six months of investigating :P


I've freshly installed Ubuntu 22.04 and used the ZFS+LUKS full drive encryption option from the installer.

I've been searching around on the web for a way to configure the drive to unlock automatically on boot when a usb key is detected (LUKS unlock key on the USB stick) instead of entering a decryption passphrase every time I boot the system.

I've found tons of guides, but none of their instructions seem to be applicable to the way 22.04 sets out the partitioning structures on the drive when using both ZFS and LUKS.

The closest guide i'm following is here: https://tqdev.com/2022-luks-with-usb-unlock

Everything seems to go well, until I get to the point where I have to add the key to the LUKS drive (step six) - because two drives are listed as LUKS drives.

root@bob-home-linux:~# sudo blkid --match-token TYPE=crypto_LUKS -o device
/dev/sdc2
/dev/zd0

I'm not sure how to proceed from here!

2
  • Please add the output for mount , and add the content of the files /etc/fstab and /etc/crypttab. Also I think your step 7 is fine, and is probably diffrent because you have a diffrent block device and/of filesystem
    – ofirule
    Jun 22, 2022 at 12:03
  • @ofirule information added for you Jun 23, 2022 at 23:42

2 Answers 2

1

It is hidden 'magic' in initramfs - in package zfs-initramfs to be exact.

Look in /usr/share/initramfs-tools/script/zfs and find the following line:

# Open and mount luks keystore for any pools using one

The behaviour is as follows:

After importing the pool (e.g. rpool) the unencrypted volume (zvol) in it is available as /dev/zvol/rpool/keystore.

This zvol device is still encrypted.

The crypttab entries for those luks-encrypted zvols (zfs list -t volume) are created on the fly during boot time into /cryptroot/crypttab.

The passphrases for those entries are then queried from the user.

The devices are then unlocked and will be mounted unencrypted at /run/rpool/keystore.

Since the rpool itself is encrypted and its keylocation points to this location the key for rpool can be loaded and the boot process can be continued.

Probably someone should document that properly ;)


As to your original question you could try to tweak the behaviour with the possible expansion points for initramfs in /etc/initramfs-tools/scripts/local-*/ to do the same thing and mount either the zvol yourself with the passphrase from your usb device or provide the key for rpool somehow directly.

1
  • Michael, thanks so much for your input - when I get a solid procedure going for enabling this, i'll most likely put a youtube video together and credit you (and others who have responded) to get this going. Dec 19, 2022 at 3:24
1

Video walkthrough:

  1. Install Ubuntu 22.04 desktop using ZFS and encryption using the Ubuntu installer. Ensure you record the encryption passphrase safely for use in a later step. I did not set up a recovery key in the installer, so I do not know whether these steps work when using a recovery key. YMMV.

  2. After installation, format a USB drive and create a new partition using the ext4 standard (I used the disks utility in Ubuntu). Call the partition 'linux-key'.

  3. Ensure that the USB drive is mounted. Use the 'files' application to verify that the USB is mounted in the left-hand column of the files window.

  4. Start a terminal and type the following commands to switch to root, then to the USB drive:

    sudo su
    cd /media/<yourusername>/linux-key
    ls -la
    
  5. You should an empty directory listing, showing the USB drive is empty.

    root@ubuntu:/media/bob/linux-key$ ls -la
    total 29
    drwx------  3 bob  bob   4096 Jan 25 15:07 .
    drwxr-x---+ 3 root root     3 Jan 25 15:08 ..
    drwx------  2 root root 16384 Jan 25 15:07 lost+found
    
  6. Type the following to show LUKS partitions in your system. The default partition that we need to modify is usually /dev/zd0. Ensure it is shown when running the command below.

    $ blkid --match-token TYPE=crypto_LUKS -o device
    /dev/sdc2
    /dev/zd0
    
  7. Create the new encryption keyfile.

    dd if=/dev/urandom bs=1 count=256 > linux.key
    
  8. Ensure the keyfile exists – you should see the file in the listing.

    $ ls -la
    -rw-rw-r--  1 root  root    256 Jan 25 15:10 linux.key
    
  9. Configure the keyfile to work with the partition, then enter the decryption passphrase configured earlier in the installer.

    cryptsetup luksAddKey /dev/zd0 linux.key
    
  10. Check successful key insertion by ensuring keyslot 1 has been populated.

    cryptsetup luksDump /dev/zd0;
    
        ...
        Area offset:32768 [bytes]
        Area length:258048 [bytes]
        Digest ID:  0
      1: luks2 <------------- the key you just added
        Key:        512 bits
        Priority:   normal
        Cipher:     aes-xts-plain64
        Cipher key: 512 bits
        PBKDF:      argon2id
        ...
    
  11. Adjust keyfile permissions

    chmod 400 linux.key
    
  12. Next, navigate to the initramfs scripts folder and open the file called 'zfs'. You can use any text editor that you wish. (I'm using nano in this example)

    cd /usr/share/initramfs-tools/scripts
    nano zfs
    
  13. Find the following line, and replace it with the following text.

    Find this line

    echo "keystore-${pool} ${ks} none luks,discard" >> "${TABFILE}"
    

    Replace with this

    echo "keystore-${pool} ${ks} none luks,discard,tries=10,keyscript=/scripts/usb-unlock" >> "${TABFILE}"
    
  14. Save and close the file.

  15. Create a new file called 'usb-unlock' in the same directory.

    nano usb-unlock
    
  16. Paste in the script from this gist - this checks for a USB drive partition called 'linux-key', searches for a file called linux.key and attempts to use that to decrypt the partition.

  17. Save and close the file.

  18. Adjust the permissions for the usb-unlock script

    chmod 755 usb-unlock
    
  19. List the script's directory. Ensure that the two files you've just worked with belong to the root user with a 755 permission set.

    $ ls -la  # you should see these files...
    -rwxr-xr-x  1 root root   550 Dec 22 20:38 usb-unlock
    -rwxr-xr-x  1 root root 31665 Dec 22 20:40 zfs
    
  20. Finally, update initramfs so it runs the script when you boot up.

    update-initramfs -u
    
  21. Reboot your machine, ensuring that the USB drive is inserted. If it is inserted, you should not need to type in your decryption passphrase. If it is missing, the script will fall back to asking for a passphrase that you have to type in.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.