This guide is based off some articles from Fedora Magazine by Alexander Wellbrock. What you see here brings together information from multiple articles to give this one specific use-case succinctly and contiguously in one guide.
Note
While this guide is specific to Fedora and it's EL derivatives, it can easily be adjusted to other distributions by substituting commands and packages as necessary (i.e. On Debian derivatives, swap DNF for apt)
Install dependencies:
[…]$ sudo dnf install fido2-tools dracut
Plug in the FIDO2 U2F key and check that it's correctly detected:
[…]$ fido2-token -L
/dev/hidraw1: vendor=0x1050, product=0x0407 (Yubico YubiKey OTP+FIDO+CCID)
(Optional) Set a PIN for the new FIDO2 key, for added security if somebody gets physical access to it:
[…]$ fido2-token -C /dev/hidraw1
Enter current PIN for /dev/hidraw1:
Enter new PIN for /dev/hidraw1:
Use lsblk
to find your encrypted drive
[…]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 1 0B 0 disk
sdb 8:16 1 0B 0 disk
zram0 252:0 0 8G 0 disk [SWAP]
nvme0n1 259:0 0 476.9G 0 disk
├─nvme0n1p1 259:1 0 600M 0 part /boot/efi
├─nvme0n1p2 259:2 0 1G 0 part /boot
└─nvme0n1p3 259:3 0 475.4G 0 part
└─luks-fdb98c38-... 253:0 0 475.3G 0 crypt /home
/
Find the partition number(s) hosting the luks-* partition of type crypt. In this case that'd be /dev/nvme0n1p3
. Use this path as target for the following sections.
Add the fido2 dracut module to your dracut configuration.
[…]$ echo "add_dracutmodules+=\" fido2 \"" | sudo tee /etc/dracut.conf.d/fido2.conf
add_dracutmodules+=" fido2 "
Now enroll the FIDO key with your LUKS partition as an alternative decryption factor. See systemd-cryptenroll(1) for options to control features like touch or pin prompt. By default presence and pin (if you chose to set one) are requested for enrollment and use. Depending on your FIDO2 device, you may also need to press an activation button/fingerprint scanner. Repeat this command for any subsequent FIDO2 key (always have a backup key) after you have unplugged the previous key and plugged in the next one.
[…]$ sudo systemd-cryptenroll --fido2-device auto /dev/nvmen1p3
Now update /etc/crypttab
and append fido2-device=auto
to the appropriate line's options. A line in /etc/crypttab
consists of four fields with the last one being a comma separated list. I've chosen to remove discard
due to it's security implications1 but this can be overcome somewhat by first doing a random wipe of the entire storage device with a PRNG2 Stream from nwipe, DBAN or simply dd if=/dev/random of=<device>
.
[…]$ sudo nano /etc/crypttab
luks-#### UUID=#### none fido2-device=auto
Finally, rebuild your initramfs using dracut. The following command will rebuild your currently-booted initramfs slot.
[…]$ sudo dracut -f
Now you can choose to leave the LUKS2 password active if you had the foresight to have a sufficently secure (long and complex, think 32+ alphanumeric characters) password. Otherwise proceed to remove the password entirely and solely use your FIDO2 keys.
[…]$ sudo systemd-cryptenroll --wipe-slot password
Personally, I also like the idea of locking the GNOME system if you have to leave on short notice and take your FIDO2 key/s with you.
Create an udev rule to catch the device detach event with a shell script. The model ID in this example might differ so please check your lsusb
output to confirm it. Save the following udev rule into /etc/udev/rules.d/20-u2f.rules
:
[…]$ sudo nano /etc/udev/rules.d/20-u2f.rules
ACTION=="remove", ENV{ID_BUS}=="usb", ENV{ID_MODEL_ID}=="0407", ENV{ID_VENDOR_ID}=="1050", RUN+="/usr/local/bin/lockscreen.sh"
Add the following script to the /usr/local/bin/lockscreen.sh file:
[…]$ sudo nano /usr/local/bin/lockscreen.sh
#!/bin/sh
for bus in /run/user/*/bus; do
uid=$(basename $(dirname $bus))
if [ $uid -ge 1000 ]; then
user=$(id -un $uid)
export DBUS_SESSION_BUS_ADDRESS=unix:path=$bus
if su -c 'dbus-send --session --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.ListNames' $user | grep org.gnome.ScreenSaver; then
su -c 'dbus-send --session --type=method_call --dest=org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.Lock' $user
fi
fi
done
Add execution permission to this script and reload udev:
[…]$ sudo chmod +x /usr/local/bin/lockscreen.sh
[…]$ sudo udevadm control -R
Reboot with your FIDO2 key plugged in and you should be in business.
Footnotes
-
A discard request, aka "TRIM", puts part of a solid-state drive into an "unused, ready to write" state. An attacker can use this to figure out which parts of the drive are empty, something they couldn't figure out if those sections contained encrypted empty space. See here ↩
-
Pseudo Random Number Generators, such as the Mersenne Twister, ISAAC, XORoshiro-256 or Lagged Fibonacci. ↩