Where to go from `boot.initrd.luks.gpgSupport`?

I have a few yubikeys configured to use the same gpg key and I currently use the following to unlock during boot

boot.initrd.luks.gpgSupport = true;
boot.initrd.luks.devices.“cryptroot”.device = “/dev/disk/by-uuid/…
boot.initrd.luks.devices.“cryptroot”.gpgCard.publicKey = ..;
boot.initrd.luks.devices.“cryptroot”.gpgCard.encryptedPass = ..;

IIUC correctly support for this will be removed with scripted initrd in 26.11.

Wondering if anyone is in a similar position and what they ended up doing and why.

I think I have the option of using piv (which will work both with my yubikey 4 and 5) or FIDO2 which is only supported by the yubikey v5. At first glance FIDO2 seems easier to configure except for having to enroll each yubikey.

4 Likes

Same position here. GPG support is a great feature that would be unfortunate to lose. There are no good alternatives as far as I can tell.

The supported options are those described in systemd-cryptenroll(1). Anything else is just out of scope and not reasonably maintainable in-tree in nixpkgs. cryptsetup does have a concept of plugins, and I think it would be a good idea for us to add more generic support for those, but AFAIK there aren’t plugins for the deprecated methods other than the fido2 / tpm2 / pkcs11 ones you get with systemd-cryptenroll.

If you want support for additional key acquisition methods, my recommendation is to file issues upstream with systemd about the method you’d like, or to create an out-of-tree cryptsetup plugin for it. In the latter case, NixOS still needs to implement a generic interface for integrating arbitrary cryptsetup plugins, but that would be a welcome change (unlike any specific in-tree implementations of key acquisition methods).

1 Like

Is adapting existing scripts that acquire key from gpg card to run as systemd service a viable option? It seems to be according to this post, and if so, that’s probably the easiest path for people that needs this functionality.

I think it just hasn’t been done yet, which is why there are still # TODO comments in the assertion block above. I don’t think there’s anything preventing it from being done other than somebody with the hardware and motivation doing it. A “good” solution probably leans into systemd to handle waiting for hardware devices and retires instead of just porting the shell script 1:1, so it’s not quite a trivial translation.

FWIW, I ended up transitioning to TPM unlocks with secureboot since I wrote that post and it’s pretty great.

2 Likes

You certainly could adapt the scripts from scripted initrd to systemd units in your own config; NixOS makes it really easy to customize initrd with your own systemd units. But I don’t think it would be acceptable upstream in nixpkgs to reimplement these options for systemd initrd. We have to consider the engineering tradeoff involved in supporting these options. Maintaining a non-trivial amount of in-house code for handling sensitive key material is the kind of thing we really don’t want to be doing unless we really have to. And this is a case where I think we really don’t have to.

All yubikey models that support OpenPGP (the protocol that gpgSupport uses) also support PIV, and PIV similarly allows each yubikey device to import the same key. Of the yubikey models that support Yubico OTP (the protocol that yubikeySupport uses), all but two (Yubikey Standard, and Yubikey Nano (original)) also support PIV and/or FIDO2. So almost all users should be able to reasonably migrate to something supported by upstream projects.

Like I said, I would welcome the code to integrate arbitrary cryptsetup plugins, and that would make it easy for third parties to implement other methods as cryptsetup plugins that systemd could use. Any custom methods that we could ship in nixpkgs should be done like this, not with code we have to maintain in nixpkgs.

Custom methods you implement yourself can of course be done in your own systemd units similar to how scripted stage 1 used to do them.

Oh, uh… if those TODOs are still there, that’s an oversight and I should open a PR to remove those comments.

2 Likes

Oh, uh… if those TODOs are still there, that’s an oversight and I should open a PR to remove those comments.

Oh, lol. Well, I definitely defer to you here.

I’m actually looking at the gpg options, and it is definitely a bit more janky than the other hardware key options. I don’t think I would want to maintain it either. There are just better options.

One particular instance where migration to e.g. PIV or FIDO2 does not work: PGP cards can be duplicated at setup (as they can import keys), allowing for backups. PIV and FIDO2 do not allow for those kinds of backups, as far as I understand.[1]

Unsure where to go from here on. I understand and empathize the motivation to reduce the maintenance burden. I do not have the resources to contribute to upstream, nor do I want my system to stay outdated. I guess I will have to find a hack or switch away from NixOS.


  1. systemd-cryptenrolling all backup keys is not workable for some threat models. Backups may be inaccessible without having engaged emergency procedures. Thus, the PGP key can be printed out before importing to the card; PIV/FIDO2 cannot. ↩︎

As I said before:

So you can certainly import a key, the only issue is that I don’t think you can export a key that was generated on the device. But that’s by design; once the key has been exported, even for a backup, you’ve defeated the point of generating it on-device, which is that the key never leaves the device. So it makes much more sense to me that if you want the same key on multiple devices, you would have to generate it externally and import it into each, rather than giving the devices the ability to export the keys they generate.

I think I’ve misread both your previous post and the manual of my key then. I’ll recheck, thanks!