Unlocking LUKS volume with Nitrokey 3 on Debian 12.2

I successfully setup a Debian 12.2 fresh install with a LUKS volume that is unlocked by a NitroKey 3.

I use this great howto (and the comments): Unlock LUKS volume with a YubiKey – Guy Rutenberg

And this Debian bug report: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1029324

This one is also a great read: Unlocking LUKS2 volumes with TPM2, FIDO2, PKCS#11 Security Hardware on systemd 248

Summary

  • You need to use dracut instead of initramfs-tools to manage initrd (since the latter cannot use systemd-cryptsetup to unlock LUKS volumes with FIDO2 devices)
  • Then you just enroll your FIDO2 device
  • (Optional) Generate recovery keys (see 2nd howto)

Here a summary of all commands (as root) needed to set this up on a fresh install of Debian 12.2:

#
# Switch from initramfs-tools to Dracut to manage initrd
#
nano /etc/default/grub
# Change the line with GRUB_CMDLINE_LINUX_DEFAULT like this:
# GRUB_CMDLINE_LINUX_DEFAULT="quiet rd.auto=1"
update-grub
nano /etc/crypttab
# Change the line:
# vda5_crypt UUID=165e9c6c-6277-49b1-ac51-94158b504964 none luks,discard
# to:
# luks-165e9c6c-6277-49b1-ac51-94158b504964 UUID=165e9c6c-6277-49b1-ac51-94158b504964 none luks,discard
apt install dracut
apt purge cryptsetup-initramfs && apt autoremove -purge
dracut -f
# Test that the switch to dracut is working by rebooting 😀
reboot

#
# Enroll your FIDO2 device to unlock Luks volume
#
apt install fido2-tools
# Plug your FIDO2 device systemd-cryptenroll -fido2-device=list
# Check your FIDO2 device is listed
systemd-cryptenroll -fido2-device=auto /dev/vda5
nano /etc/crypttab
# Change the line:
# luks-165e9c6c-6277-49b1-ac51-94158b504964 UUID=165e9c6c-6277-49b1-ac51-94158b504964 none luks,discard
# to:
# luks-165e9c6c-6277-49b1-ac51-94158b504964 UUID=165e9c6c-6277-49b1-ac51-94158b504964 none luks,discard,fido2-device=auto
echo “hostonly=yes” > /etc/dracut.conf.d/10-hostonly.conf
dracut -f
# Test if everything works as expected ! 😀
reboot
2 Likes

Doing this with dracut on Fedora 37 should be no different, correct?

I am trying to do what you are doing with Debian on Qubes OS.

Here is a link fyi. I will try what you did out. Debian must have crypttab nomenclature that is different from Fedora. You made it look too easy.
luks-machineID UUID= is the key? Or rd.luks

Thanks for the nice tutorial. As tutorials are meant to be replicated, I just wanted to mention that TRIM setting is a controversial topic and has security implications to consider.

From what I know, you need a distribution using systemd (at least version 248) and using systemd-cryptsetup in the initrd to unlock the LUKS volume.

Fedora seems to have these prerequisites.

In crypttab, after you must change the line :
vda5_crypt UUID=XXX none luks,discard
to
luks-XXX UUID=XXX none luks,discard

Where XXX is the UUID of the partition. You can check the UUID of a partition with the blkid command.

From what I see, the crypttab file have the same nomenclature on Debian and Fedora.
You can compare the Fedora manpage for crypttab with the Debian one:
https://manpages.debian.org/bookworm/cryptsetup/crypttab.5.en.html

Thanks for the link, I didn’t know it was a controversial topic.
I didn’t touch the default Debian configuration that why discard is present.
But obviously you should consider using it or not, knowing the security implications.

I don’t use rd.luks. Just rd.auto to tell dracut to handle LUKS volumes.
But if you do just that, dracut will only try to unlock the LUKS volume by asking a password.
You need to add the hostonly=yes in your dracut configuration so that dracut -f includes your /etc/crypttab file into the initrd. This way during the boot, dracut will know that it can unlock the LUKS volume with a fido2 device.

I have done more tests and things can be simplified a bit more!

When you set hostonly=yes in dracut configuration, the file /etc/crypttab is included into the initrd.
Since dracut will have this file during boot, you don’t need to:

  • add rd.auto=1 in /etc/default/grub
  • rename the target in /etc/crypttab

So it boils down to:

#
# Switch from initramfs-tools to Dracut to manage initrd
#
apt install dracut
apt purge cryptsetup-initramfs && apt autoremove -purge
echo "hostonly=yes" > /etc/dracut.conf.d/10-hostonly.conf
dracut -f
# Test that the switch to dracut is working by rebooting 😀
reboot

#
# Enroll your FIDO2 device to unlock Luks volume
#
apt install fido2-tools
nano /etc/crypttab
# Change the line:
# vda5_crypt UUID=165e9c6c-6277-49b1-ac51-94158b504964 none luks,discard
# to:
# vda5_crypt UUID=165e9c6c-6277-49b1-ac51-94158b504964 none luks,discard,fido2-device=auto
# Update initrd to include FIDO2 tools and updated /etc/crypttab
dracut -f
# Plug your FIDO2 device
systemd-cryptenroll -fido2-device=list
# Check your FIDO2 device is listed
systemd-cryptenroll -fido2-device=auto /dev/vda5
# Test if everything works as expected ! 😀
reboot
1 Like

I had some trouble with your code.

#
# Switch from initramfs-tools to Dracut to manage initrd
#
sudo -i
nano /etc/default/grub
# Change the line with GRUB_CMDLINE_LINUX_DEFAULT like this:
# GRUB_CMDLINE_LINUX_DEFAULT="quiet rd.auto=1"
update-grub
nano /etc/crypttab
# Change the line:
# sda3_crypt UUID=165e9c6c-6277-49b1-ac51-94158b504964 none luks,discard
# to:
# luks-165e9c6c-6277-49b1-ac51-94158b504964 UUID=165e9c6c-6277-49b1-ac51-94158b504964 none luks,discard
apt install dracut
apt purge cryptsetup-initramfs && apt autoremove --purge
dracut -f
# Test that the switch to dracut is working by rebooting 😀
reboot

# Enroll your FIDO2 device to unlock Luks volume
sudo -i
apt install fido2-tools
# Plug your FIDO2 device systemd-cryptenroll --fido2-device=list
systemd-cryptenroll --fido2-device=list
# Check your FIDO2 device is listed
systemd-cryptenroll --fido2-device=/dev/hidraw0 /dev/sda3
nano /etc/crypttab
# Change the line:
# luks-165e9c6c-6277-49b1-ac51-94158b504964 UUID=165e9c6c-6277-49b1-ac51-94158b504964 none luks,discard
# to:
# luks-165e9c6c-6277-49b1-ac51-94158b504964 UUID=165e9c6c-6277-49b1-ac51-94158b504964 none luks,discard,fido2-device=/dev/hidraw0
echo 'hostonly=yes' > /etc/dracut.conf.d/10-hostonly.conf
dracut -f
# Test if everything works as expected ! 😀
reboot
# Mit folgendem Befehl kann man fehlerhafte Slots wieder löschen:
systemd-cryptenroll --wipe-slot=1 /dev/sda3

@kaugummi
What problem ?

apt purge cryptsetup-initramfs && apt autoremove --purge # here you only have a hyphen before purge (-purge)
  # Plug your FIDO2 device systemd-cryptenroll --fido2-device=list # here you only have a hyphen before fido2-device (-fido2-device)
systemd-cryptenroll --fido2-device=list # here too (-fido2-device)
# Check your FIDO2 device is listed
systemd-cryptenroll --fido2-device=/dev/hidraw0 /dev/sda3 # here too (-fido2-device)
 echo 'hostonly=yes' > /etc/dracut.conf.d/10-hostonly.conf # here I had "hostonly=yes" in 10-hostonly.conf. So with quotation marks.

Many thanks for the instructions. Everything worked after the improvements.

@kaugummi You’re welcome

Yes, some characters have been changed by the forum text editor : double hyphen into single hyphen, double quote into strange double quote…

Hi, for those using Debian and initramfs-tools I wrote a small tool to unlock a LUKS volume using a FIDO2 key: GitHub - bertogg/fido2luks: Unlock LUKS volumes at boot time using a FIDO2 token and initramfs-tools

1 Like

How do you select the unlock option once the fido key is enrolled and fido2-device=auto is part of the cryottab? Is unlocking with a password still possible?

Hi @obey

Yes, you can still unlock the partition with a password (if you have setup one).

There is 2 possibilities:
1/ If the FIDO2 device PIN is not necessary to unlock the partition
Boot with no FIDO2 device plugged and after 30s seconds the system will try to ask a password

2/ If the FIDO2 device PIN is necessary to unlock the partition
Boot with no FIDO2 device plugged, type a PIN (any PIN but not an empty one) and after 30s seconds the system will try to ask a password

See FIDO2 fallback to password · Issue #19872 · systemd/systemd · GitHub