NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.06k stars 13.39k forks source link

luksroot: Use keyctl over ramfs #273591

Open stackcoder opened 8 months ago

stackcoder commented 8 months ago

When the option reusePassphrases is activated nixos stores the plaintext passphrase on a ramdisk located at /crypt-ramfs/passphrase. The wohle ramdisk is destoryed using umount later by postCommands. While umount just frees the memory the password might still resists somewhere.

Even if a ramdisk is used here, the Kernel Key Retention Service resp. keyctl is better suited for this purpose. That's how Debian implemented their luks passphrase caching, within mostly two scripts: decrypt_keyctl and cryptdisks-functions.

Compared to the current solution kernel keyring offers advantages:

What do you think of using keyctl over ramfs for reusePassphrases, should we replace it or add an option? If I would make a PR for this, is there a chance to get it upstream?

flokli commented 8 months ago

How does this relate to systemd-ask-password and friends, which we use at least in the systemd-in-initrd case?

cc @ElvishJerricco @RaitoBezarius

RaitoBezarius commented 8 months ago

I think the ramfs stuff will disappear as soon as we deprecate the scripted stage 1. So I don't know if this is a good idea to spend time on that.

NickCao commented 8 months ago

How does this relate to systemd-ask-password and friends, which we use at least in the systemd-in-initrd case?

systemd-ask-password can cache passwords in the kernel keyring, so potentially related.

stackcoder commented 8 months ago

@RaitoBezarius Thanks for pointing that out! What will replace the current scripted stage 1, does this mean systemd-in-initrd with systemd-ask-password?

I am curious how the many cases such as yubikey and gpg can be realized without scripting. Is there something I can already switch to or help with instead of patching scripted stage 1?

ElvishJerricco commented 7 months ago

@stackcoder It's likely we'll have to deprecate the old yubikey and gpg things along with scripted stage 1. They're very obscure in terms of implementation anyway. systemd-initrd makes it very easy to use FIDO2 though, so I hope we have most users covered that way.

Anyway, yes, systemd-initrd does already use the kernel keyring for exactly this purpose.

Joseph-DiGiovanni commented 4 months ago
  • Could be accessible after initrd stage to derive secrets for other services

I'd like to see this PR just for this option really. It would be nice to cache my luks password to unlock my gnome-keyring with auto/biometric login like debian/fedora do.

stackcoder commented 4 months ago

I've tried to switch to systemd using the boot.initrd.systemd.enable option. Which ended up really annoying:

First boot.initrd.systemd lacks mkMerge or something like that, so nix required me to write my config in a specific order. Also when I was not supplying the password immediately on time, systemd goes to emergency mode and sucks there forever. In best case, you're still be able to reboot again via ssh. In worst case you'll need physical access to the machine. Maybe some extra config could help - just switching to systemd is completely unusable. Can some one provide a better working full example? Maybe mount option x-systemd.mount-timeout=0 could help.

Sorry but scripted stage 1 is (at least at this time) much more reliable to bring up the system.

ElvishJerricco commented 4 months ago

@stackcoder None of that has anything to do with this issue. But I'll reply briefly and direct you to better places to go for support.

  1. It's not possible for it to "lack mkMerge". That's part of the module system, not part of any individual options. I have no idea what you're talking about with this one. If you can demonstrate what you mean, please open another issue or ask on matrix what's going wrong, because your description is not possible.
  2. The disk timeout problem already has an issue and it has been described at length. I agree it's not ideal, but we're still in search of a solution for this one that isn't just "no disk timeouts" or "everything is after cryptsetup.target", because obviously neither of those is ideal. There are workarounds you can implement for yourself; or actually, the most correct thing to do isn't even a workaround: Use device = "/dev/mapper/foo"; for your LUKS file systems instead of device = "/dev/disk/by-uuid/asdfasdf";.
nixos-discourse commented 2 months ago

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/unlocking-multiple-luks-devices-with-same-passphrase/45856/13