`extra_files: fido2-assert` can't unlock w/ systemd-cryptenroll -ed Yubikey
Closed this issue · 4 comments
My root partition is a Btrfs on a LUKS2 encrypted partition with a Yubikey 5 NFC enrolled with systemd-cryptenroll --fido2-device=auto
at slot 1. I can successfully boot the system with a mkinitcpio generated initramfs-linux-{lts,zen}.img
.
With the following environment & config for booster:
- OS: Arch Linux
- Booster version: both 0.10-1 and 0.10-2 from Arch official repo
- Bootloader: systemd-boot from systemd=253.6-2
- Kernel: both linux-zen=6.4.* and linux-lts=6.1.* (probably doesn't matter)
/etc/booster.yaml
:
modules_force_load: i915
modules: vmd,i915,intel_lpss_pci
extra_files: fido2-assert
/boot/loader/entries/arch-lts.conf
:
title Arch LTS
linux /vmlinuz-linux-lts
initrd /intel-ucode.img
initrd /booster-linux-lts.img
options rd.luks.name=<REDACTED UUID>=arch root=/dev/mapper/arch rootflags=subvol=@ rw add_efi_memmap random.trust_cpu=on intel_iommu=on
Expected behavior: when the screen shows Enter passphase for arch:
, with my Yubikey plugged in, the LED on the Yubikey should be flashing. Touching the Yubikey (the metal part, that is) should unlock the LUKS partition and continue the boot process
Actual behavior: The LED on the Yubikey is not flashing. Touching the Yubikey would result a screen showing this:
Enter passphase for arch: Unlocking...
Incorrect passphrase, please try again
Enter passphase for arch:
I can still unlock w/ the passphrase at slot 0.
Attempted fiddling 1: use absolute path, avoid symlink directory (/bin)
This idea comes from mkinitcpio: all the executables in the images initramfs-*
are located in /usr/bin/
instead of /bin/
.
- In
/etc/booster.yaml
, replace the lineextra_files: fido2-assert
withextra_files: /usr/bin/fido2-assert
- Rebuild image with
/usr/lib/booster/regenerate_images
- Reboot
...and the expected behavior actually happens.
Attempted fiddling 2: throw in /bin/setfont to debug
Technically speaking this isn't really necessary for me -- the early userspace console looks exactly the same with or without vconsole: true
for now.
- Append a line
vconsole: true
to/etc/booster.yaml
- fido2-assert is still loaded by
extra_files: fido2-assert
, putting it at/bin/fido2-assert
- Rebuild image
- Reboot
Now the boot process is stuck at
[1.<can't remember exact number here>] booster: exec: "setfont": executable file not found in $PATH
Press ENTER to reboot
Looking at booster ls /boot/booster-linux-lts.img
, /bin/setfont
is present (along with /bin/fido2-assert
) in the image.
Attempt to booster unpack /boot/booster-linux-lts.img /tmp
would print a line of error: 2023/07/16 01:50:39 mkdir /tmp/bin: file exists
(not sure if this helps but FWIW)
Attempted fiddling 3: 1 and 2 combined
- Rebuild image with both
extra_files: /usr/bin/fido2-assert
andvconsole: true
, resulted images with/usr/bin/fido2-assert
and/bin/setfont
- Reboot
Expected behavior happens: no setfont error, touched Yubikey to unlock. Feels confused but okay.
Attempted fiddling 4: build a universal image
... with a line universal: true
in /etc/booster.yaml
, no full path of fido2-assert
, no vconsole
, problem still exists.
I'm not sure if this is an issue with booster or my own setup. For now I can totally get my boot process back to working condition with extra_files: /usr/bin/fido2-assert
without having to use mkinitcpio (which is pretty slow compared to booster).
I think I've found the root cause:
- On my system I've been running opendoas instead of good old sudo
- opendoas sets the
PATH
environment variable to a hardcode set of "safepath" instead of inheriting the value of$PATH
from current shell - and this "safepath" puts
/bin
at the top of the list booster build
picks up executables in/bin
because it's at the top of the list
sudo
has a simillar setting named secure_path
but somehow plays nice with booster. I just tried running sudo booster build ...
and images have /usr/bin/fido2-assert
which should work just fine.
But still, right now booster(1)
claims that a relative path is resolved from /usr/bin
without mentioning the PATH
environmental variable. Meanwhile in CHANGES.md
(which is not necessarily packaged by Linux distros) it claims that booster will actually lookup executables in PATH
.
Before I could come up with some constructive suggestions I could really use a break...
Hello @5long thank you for this extensive analysis.
right now booster(1) claims that a relative path is resolved from /usr/bin without mentioning the PATH environmental variable. Meanwhile in CHANGES.md (which is not necessarily packaged by Linux distros) it claims that booster will actually lookup executables in PATH.
Until recently booster
was using golan's exec.LookPath
function that is relying on PATH envvar.
But recently (commit 7766b07) booster has switched to predefined list of directories to lookup. It was done for the security and reproducibility reasons. The list is here
booster/generator/generator.go
Lines 306 to 313 in 7766b07
The change is not part of a released version. It targets the upcoming 0.11
release.
@5long By any chance, are you still experiencing this issue? On my host machine, booster's default minimal generated initramfs would not reliably unlock my encrypted device using a Yubikey unless it was configured to generate a universal image.
I was able to get around this by force loading my graphics module, usbhid
and hid_sensor_hub
.
booster.yaml:
modules_force_load: amdgpu,usbhid,hid_sensor_hub
extra_files: fido2-assert