Using FIDO2 keys to unlock LUKS on EndeavourOS

Posting this as I couldn’t find a good single source of how to enable a FIDO2 hardware token to authenticate and unlock encrypted partitions on an encrypted EndeavourOS installation.

This information is applicable to Galileo Neo 2024.1 and may not work on other versions (or indeed, at all).

Please be sure you have a tested verifiably restorable backup of your system before attempting any of this, I am not responsible for your system or data.

That out of the way.

The first problem is that EndeavourOS when installed with encryption, will use LUKS1 format header. I did not know this would be a barrier at the time, but it is.

For many of these steps you need to know what your encrypted block devices are. Mine were /dev/nvme1n1p1 and also /dev/nvme1n1p3

You can find these before starting by using

lsblk

you should see information something like

nvme1n1                                       259:2    0   1.8T  0 disk  
├─nvme1n1p1                                   259:3    0   250G  0 part  
│ └─luks-807ec89e-ec42-4507-bda0-xxxxxxxxx 254:3    0   250G  0 crypt /
├─nvme1n1p2                                   259:4    0  64.5G  0 part  [SWAP]
├─nvme1n1p3                                   259:5    0   1.5T  0 part  
│ └─luks-064a0641-f53e-4cb9-8c77-xxxxxxxxx 254:4    0   1.5T  0 crypt /home

The above would tell me that nvme1n1p1 and nvme1n1p3 are my encrypted devices, you should note yours in a similar way.

UPDATE: there is a suggestion that EndeavourOS might actually install LUKS2 as default in some circumstances. You can check by:

sudo cryptsetup luksDump /dev/nvme1n1p1

If you see:

LUKS header information
Version:        2

Then you already have a LUKS2 installation and you can skip the next section and go to STAGE 2 below.

If the Version is 1, then continue with the conversion.

So step 1 is to convert your encrypted partitions from LUKS1 header to LUKS2. This is necessary because the later steps require LUKS2 and won’t work on LUKS1 encryption.

  • STAGE 1
  • Boot from the 2024.1 USB media

Convert to luks2

  1. mount a USB flash drive or other location to hold header backups
  2. make header backups (substitute devices as from above)
sudo cryptsetup luksHeaderBackup /dev/nvme1n1p1 --header-backup-file /path/to/backups/nvme1n1p1.bin
sudo cryptsetup luksHeaderBackup /dev/nvme1n1p3 --header-backup-file /path/to/backups/nvme1n1p3.bin

And now convert to LUKS2

sudo cryptsetup convert --type luks2 /dev/nvme1n1p1
sudo cryptsetup convert --type luks2 /dev/nvme1n1p3

Answer the prompts in the appropriate manner (YES) or anything else to abort.

This does not take long (instant)

  • reboot back into your regular system

This should proceed just as before, as all we have done is converted to the LUKS2 format. EndeavourOS already supports booting from both, but will only create LUKS1 at install time.

  • STAGE 2
  • install FIDO2 support package
pacman -Sy libfido2
  • enrol each partition with the FIDO2 key
systemd-cryptenroll --fido2-device=auto --fido2-with-user-verification=true --fido2-with-client-pin=false /dev/nvme1n1p1
systemd-cryptenroll --fido2-device=auto --fido2-with-user-verification=true --fido2-with-client-pin=false /dev/nvme1n1p3

I configured mine to NOT require PIN (–fido2-with-client-pin=false), but to REQUIRE button press ( –fido2-with-user-verification=true )

You can change these options as you see fit. I might re-enroll with PIN but for now, I’m happy with the token being present, and button press only.

  • modify /etc/crypttab

Change your /etc/crypttab to append fido2-device=auto to each encrypted device you enrolled

The fourth column on each line probably has:

luks

and this is changed to

luks,fido2-device=auto
  • Set up initrd via dracut to allow the fido2 key to work

Create file /etc/dracut.conf.d/fido2.conf

install_items+=" /usr/bin/fido2-token "
add_dracutmodules+=" fido2 "

Spaces are significant there, be sure to include them. Use the calamares-luks.conf one as an example if you have it

  • rebuild the init.d using dracut
dracut -f

Make sure there are no errors, and you should also see fido2 in the list of included modules.

Reboot and hope for success

For me, the token flashes at root mount stage, I click it to authenticate, then it flashes again at home partition mount stage, click again, and boot continues.

Hope it works for you , I practised all of this in an EndeavourOS VM first, but it was still a bit sweaty palm doing it for real, even with all the backups.

Hope it’s useful to someone, I’ve been wanting to do this for a couple of years now, and finally bit the bullet.

Any errors or suggestions please do say and I’ll edit the post with corrections.

3 Likes

Thanks for sharing!

Just a quick note that for newer installs, this is only true for grub users. When systemd-boot is selected luks2 is the default.

1 Like

I installed using systemd-boot right now, in a VM, and very recently on a physical machine, and I got LUKS1 both times.

Is there anything else that triggers it to use LUKS2?

efibootmgr -v

Boot0002* Linux Boot Manager    HD(4,GPT,**d73b7226-3d70-402d-bbb6-c7f9b26a628a**,0x800,0x2f4000)/\*EFI\SYSTEMD\SYSTEMD-BOOTX64.EFI*

and

/dev/nvme1n1p4: UUID="A7A4-95AB" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="**d73b7226-3d70-402d-bbb6-c7f9b26a628a**"

is my /efi mount for this installation

You need to use a Galileo ISO. Are you using an older one?

No, it’s this one:

2760355840 Feb 13 16:22 EndeavourOS_Galileo-Neo-2024.01.25.iso

md5sum

f80e131fa9fb5c28246e6e7d70186589 EndeavourOS_Galileo-Neo-2024.01.25.iso

Just for my own sanity and in the interests of science, I’ll install another VM from this ISO and see what kind of encrypted partitions I get.

Offline Install

One of my partitions:

And the other one:

Giving:

booting:

And we got LUKS1

Anything else I can troubleshoot (if indeed this is an actual problem here), happy to.

:thinking:

Either it was somehow broken with Neo or it doesn’t work with manual partitioning for some reason.

My laptop had 2023.03.26 installed on it, with automatic partitioning and systemd-boot

That also is LUKS1 but that was a bit of an older build.

As far as getting FIDO2 working though, the note to check the LUKS header before doing the conversion step if necessary should do the job.

Interesting. When I try this command with my luks drive I get access denied. What does this mean?

[g@g-x ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sr0 11:0 1 1024M 0 rom
nvme0n1 259:0 0 953.9G 0 disk
├─nvme0n1p1 259:1 0 1000M 0 part /boot/efi
├─nvme0n1p2 259:2 0 944.1G 0 part
│ └─luks-cfd8d4b2-ce6c-4f41-97f8-4c4d5d32e1da 254:1 0 944.1G 0 crypt /
└─nvme0n1p3 259:3 0 8.8G 0 part
└─luks-36cb994f-accb-4571-8b54-a3a47c5cae05 254:0 0 8.8G 0 crypt [SWAP]

[g@g-x ~]$ sudo cryptsetup luksDump /dev/nvme1n1p1
[sudo] password for g:
Device /dev/nvme1n1p1 does not exist or access denied.
[g@g-x ~]$ sudo cryptsetup luksDump /dev/nvme1n1p3
Device /dev/nvme1n1p3 does not exist or access denied.

Your device is nvme0n1p3 . @sempterobit

So you need to substitute that in here:

sudo cryptsetup luksDump /dev/nvme0n1p3

You had my original device ( nvme1n1p3 ) in there.

I think I need to be better at writing examples. I should use more obvious substitutions instead of actual devices.

Yeah, that was before we switched to luks2 so that is normal.

Your tutorial is fine. I changed the last char to 3 in my 2nd try, but forgot to change the other char :face_with_diagonal_mouth:

1 Like

Hello, unfortunately, it didn’t work for me.
I successfully converted from luks1 to luks2 and enrolled my fido2 device but when I reboot with my fido2 device plugged-in, it just ignores it and ask to enter my passphrase.

Here’s my /etc/crypttab:
luks-b8455122-3e78-4e8d-9aed-b528b43cf73d UUID=b8455122-3e78-4e8d-9aed-b528b43cf73d luks,fido2-device=auto


[eaa@eaa ~]$ ls /etc/dracut.conf.d
10-hostonly.conf  calamares-luks.conf  eos-defaults.conf  fido2.conf

[eaa@eaa ~]$ cat /etc/dracut.conf.d/fido2.conf
install_items+=" /usr/bin/fido2-token "
add_dracutmodules+=" fido2 "

[eaa@eaa ~]$ cat /etc/dracut.conf.d/eos-defaults.conf 
omit_dracutmodules+=" network cifs nfs nbd brltty "
compress="zstd"

[eaa@eaa ~]$ cat /etc/dracut.conf.d/calamares-luks.conf 
# Configuration file automatically written by the Calamares system installer
# (This file is written once at install time and should be safe to edit.)
# Enables support for LUKS full disk encryption with single sign on from GRUB.

# force installing /etc/crypttab even if hostonly="no"
install_items+=" /etc/crypttab "

[eaa@eaa ~]$ cat /etc/dracut.conf.d/10-hostonly.conf 
“hostonly=yes”

Here’s my dracut -f result :

[sudo] Mot de passe de eaa : 
/etc/dracut.conf.d/10-hostonly.conf: line 1: $'\342\200\234hostonly=yes\342\200\235': command not found
dracut: Executing: /usr/bin/dracut -f
dracut: dracut module 'dash' will not be installed, because command 'dash' could not be found!
dracut: dracut module 'mksh' will not be installed, because command 'mksh' could not be found!
dracut: dracut module 'systemd-pcrphase' will not be installed, because command '/usr/lib/systemd/systemd-pcrphase' could not be found!
dracut: dracut module 'busybox' will not be installed, because command 'busybox' could not be found!
dracut: dracut module 'rngd' will not be installed, because command 'rngd' could not be found!
dracut: dracut module 'connman' will not be installed, because command 'connmand' could not be found!
dracut: dracut module 'connman' will not be installed, because command 'connmanctl' could not be found!
dracut: dracut module 'connman' will not be installed, because command 'connmand-wait-online' could not be found!
dracut: dracut module 'network-wicked' will not be installed, because command 'wicked' could not be found!
dracut: dracut module 'tpm2-tss' will not be installed, because command 'tpm2' could not be found!
dracut: dracut module 'fcoe' will not be installed, because command 'dcbtool' could not be found!
dracut: dracut module 'fcoe' will not be installed, because command 'fipvlan' could not be found!
dracut: dracut module 'fcoe' will not be installed, because command 'lldpad' could not be found!
dracut: dracut module 'fcoe' will not be installed, because command 'fcoemon' could not be found!
dracut: dracut module 'fcoe' will not be installed, because command 'fcoeadm' could not be found!
dracut: dracut module 'fcoe-uefi' will not be installed, because command 'dcbtool' could not be found!
dracut: dracut module 'fcoe-uefi' will not be installed, because command 'fipvlan' could not be found!
dracut: dracut module 'fcoe-uefi' will not be installed, because command 'lldpad' could not be found!
dracut: dracut module 'iscsi' will not be installed, because command 'iscsi-iname' could not be found!
dracut: dracut module 'iscsi' will not be installed, because command 'iscsiadm' could not be found!
dracut: dracut module 'iscsi' will not be installed, because command 'iscsid' could not be found!
dracut: dracut module 'nvmf' will not be installed, because command 'nvme' could not be found!
dracut: dracut module 'biosdevname' will not be installed, because command 'biosdevname' could not be found!
dracut: dracut module 'memstrack' will not be installed, because command 'memstrack' could not be found!
dracut: memstrack is not available
dracut: If you need to use rd.memdebug>=4, please install memstrack and procps-ng
dracut: *** Including module: systemd ***
dracut: *** Including module: systemd-initrd ***
dracut: *** Including module: systemd-udevd ***
dracut: *** Including module: modsign ***
dracut: *** Including module: i18n ***
dracut: *** Including module: btrfs ***
dracut: *** Including module: crypt ***
dracut: *** Including module: dm ***
dracut: Skipping udev rule: 64-device-mapper.rules
dracut: Skipping udev rule: 60-persistent-storage-dm.rules
dracut: Skipping udev rule: 55-dm.rules
dracut: *** Including module: dmraid ***
dracut: *** Including module: kernel-modules ***
dracut: *** Including module: kernel-modules-extra ***
dracut: *** Including module: lvm ***
dracut: Skipping udev rule: 64-device-mapper.rules
dracut: Skipping udev rule: 56-lvm.rules
dracut: Skipping udev rule: 60-persistent-storage-lvm.rules
dracut: *** Including module: mdraid ***
dracut: Skipping udev rule: 64-md-raid.rules
dracut: *** Including module: multipath ***
dracut: Skipping udev rule: 40-multipath.rules
dracut: *** Including module: nvdimm ***
dracut: *** Including module: qemu ***
dracut: *** Including module: qemu-net ***
dracut: *** Including module: fido2 *** #################### HERE WE GO
dracut: *** Including module: lunmask ***
dracut: *** Including module: resume ***
dracut: *** Including module: rootfs-block ***
dracut: *** Including module: terminfo ***
dracut: *** Including module: udev-rules ***
dracut: Skipping udev rule: 40-redhat.rules
dracut: Skipping udev rule: 50-firmware.rules
dracut: Skipping udev rule: 50-udev.rules
dracut: Skipping udev rule: 91-permissions.rules
dracut: Skipping udev rule: 80-drivers-modprobe.rules
dracut: *** Including module: virtiofs ***
dracut: *** Including module: dracut-systemd ***
dracut: *** Including module: usrmount ***
dracut: *** Including module: base ***
dracut: *** Including module: fs-lib ***
dracut: *** Including module: shutdown ***
dracut: *** Including modules done ***
dracut: *** Installing kernel module dependencies ***
dracut: *** Installing kernel module dependencies done ***
dracut: *** Resolving executable dependencies ***
dracut: *** Resolving executable dependencies done ***
dracut: *** Hardlinking files ***
dracut: Mode:                     real
dracut: Method:                   sha256
dracut: Files:                    2148
dracut: Linked:                   9 files
dracut: Compared:                 0 xattrs
dracut: Compared:                 486 files
dracut: Saved:                    1.39 MiB
dracut: Duration:                 0.012385 seconds
dracut: *** Hardlinking files done ***
dracut: *** Generating early-microcode cpio image ***
dracut: *** Constructing GenuineIntel.bin ***
dracut: *** Store current command line parameters ***
dracut: *** Stripping files ***
dracut: *** Stripping files done ***
dracut: *** Creating image file '/efi/3a4d08d89b4a44cc89c5bc24a9dcf9f0/6.8.1-arch1-1/initrd' ***
dracut: *** Creating initramfs image file '/efi/3a4d08d89b4a44cc89c5bc24a9dcf9f0/6.8.1-arch1-1/initrd' done ***

As you can see, fido2 module is supposed to work, but nothing changed:


(On this picture, my fido2 device was plugged before the bios start up)

Have you got any idea where can be my fault?

Have a nice day :slight_smile: