anatol / booster

Fast and secure initramfs generator
MIT License
505 stars 45 forks source link

`extra_files: fido2-assert` can't unlock w/ systemd-cryptenroll -ed Yubikey #228

Closed 5long closed 1 year ago

5long commented 1 year ago

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:

/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/.

...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.

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

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).

5long commented 1 year ago

I think I've found the root cause:

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...

anatol commented 1 year ago

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 https://github.com/anatol/booster/commit/7766b079c8fd004fee9d5eba19cb98cac568773b) booster has switched to predefined list of directories to lookup. It was done for the security and reproducibility reasons. The list is here https://github.com/anatol/booster/blob/7766b079c8fd004fee9d5eba19cb98cac568773b/generator/generator.go#L306-L313.

The change is not part of a released version. It targets the upcoming 0.11 release.

c3Ls1US commented 1 year ago

@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

5long commented 1 year ago

@c3Ls1US Upgrading to booster=v0.11-1 solved my issue. Can't be of help here, sorry.