Full disk encryption: How can I automatically unlock via a USB key on Silverblue?

Hello,

I have moved from an Arch Linux setup to Fedora Silverblue. On my previous Arch system, I had it set up so that I could unlock my full disk encryption by booting with a USB stick attached, with the USB stick containing a key file. If the USB stick was not connected, then I would be prompted for the passphrase like normal.

I set this up by following the Arch wiki’s instructions. To summarise, I had to add vfat as an early boot module for the initial ramdisk, and then had to edit my Systemd-boot configuration file to add the following kernel command-line arguments:

cryptdevice=PARTUUID=(DISK_ID):lvm cryptkey=PARTUUID=(USB_ID):vfat:(KEY_FILE_PATH)

Now I am on Fedora Silverblue with GRUB, and have no previous experience with either. I have also not used Fedora Workstation before. I did a default installation via the installer, with full disk encryption and automatic partitioning. I therefore have a very typical install.

Could anyone please tell me what I need to do to set up something similar?

I took a look in my /boot/ directory and found a GRUB configuration file there, but it seems to use different kernel command-line arguments, such as rd.luks.uuid instead of cryptdevice. I’m not sure if this is the right place to touch, as I believe there may be a GRUB configuration file elsewhere in /etc/ from which the /boot/ one gets generated? I’m also not sure exactly what I would need to change.

I can also see that the /etc/crypttab file contains an entry for the full disk encryption, and the crypttab man page contains some information on pointing to a key file, but it sounds like it just takes an absolute path and that there’s no way to specify a USB disk that isn’t already mounted.

Could anyone help me out here? Thanks in advance.

1 Like

Hey,

A few pointers to help you out, I’m on my phone right now so apologies if I don’t go into depth.

Fedora uses ‘dracut’ rather than ‘mkinitcpio’ to generate the initramfs file. The initramfs file itself on Silverblue is, by default, generated server side. If you require changes to the initramfs the man pages for rpm-ostree tell you how to generate them client side.

Again, on Silverblue the recommended method to change kernel parameter is via rpm-ostree.

Following the guidance in the wiki article you posted for the systemd hook it should work.

1 Like

Thanks a lot for your help. Unfortunately, I am still having trouble getting it to work.

Following your advice, I read a bit about the systemd hook, rpm-ostree, and dracut. I used rpm-ostree kargs --editor command (pretty cool feature!) to add a new kernel argument:

rd.luks.key=/keys/testkey:UUID=USB_ID_HERE

Obviously, USB_ID_HERE was replaced with the actual UUID, as given by blkid or lsblk.

Unfortunately, after rebooting into the new deployment, I was still asked for my passphrase. Looking at the logs, there was a message saying:

Failed to activate with key file ‘/keys//testkey’. ( Key file missing ?)

This suggests that it was at least looking for the key file, which is progress, but it’s failing to find it. Could this be because it’s using vfat? Or is there some other reason? I’m unsure how to proceed, so I’d appreciate some more assistance. Thanks.

1 Like

Just gave it a little play and it works for me when I point to the luks partition following the Arch Linux wiki.

rd.luks.key=LUKS_PARTITION_UUID=/keys/testkey:UUID=USB_ID_HERE

Note: This is the UUID encrypted partition itself not the mapped device and without the “UUID=”

Oddly enough, doing what you did and following the Dracut man pages didn’t work for me either.
Let me know how you get on.

1 Like

It worked! Thanks so much for your help. I really appreciate it.

It seems like there’s a documentation issue on the Dracut man page then, or for some reason it doesn’t apply in this context. I also had to specify rd.luks.options to set a timeout, so that I can enter a passphrase in case the USB key is not available.

This is solved now. Thanks again for your help. The final solution for anyone else coming across this thread:

  1. Format a USB drive with vfat.
  2. Generate a key file on that USB drive: Arch wiki
  3. Open a terminal.
  4. Run lsblk -f to get the UUID of the encrypted partition (look for “crypto”), as well as the UUID of the USB drive’s partition.
  5. Still in the terminal, run: rpm-ostree kargs --editor
  6. Using the editor, add the following kernel arguments:
    rd.luks.key=XXXXX=/path/to/key/file:UUID=ZZZZZ rd.luks.options=XXXXX=keyfile-timeout=5s
    (replace XXXXX with the encrypted partition’s UUID and replace ZZZZZ with the USB drive’s partition.
  7. Save the file and exit, and then wait for rpm-ostree to generate a new deployment.
  8. Reboot into the new deployment. If the USB drive is connected, it should automatically unlock the encrypted drive. If it isn’t connected, then you should be prompted for a passphrase after 5 seconds.
1 Like