NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.43k stars 13.63k forks source link

sign bootloader to make it compatible with UEFI secure boot? #42127

Open KiaraGrouwstra opened 6 years ago

KiaraGrouwstra commented 6 years ago

The install guide states:

UEFI boot The EFI bootloader of the installation media is not signed and is not using a signed shim to boot. This means that Secure Boot will need to be disabled to boot.

I have a work machine I would like to use NixOS on.

Unfortunately, it uses secure boot, forcing me to choose between disabling secure boot (-> can boot from arbitrary USBs but can't use hard drive), or leaving it (can use hard drive but no NixOS).

It would be nice if NixOS were compatible with secure boot.

It seems this involves signing the bootloader with some Microsoft key. This makes me wonder, would this be possible, or would there be drawbacks to this?

(As a workaround, it seems one can also add a signing key to the UEFI firmware. However, if the NixOS bootloader is not signed yet I presume this does not apply yet.)

kalbasit commented 6 years ago

Relevant Arch wiki: https://wiki.archlinux.org/index.php/Secure_Boot#Using_your_own_keys

matthewbauer commented 6 years ago

I have looked into signing in Nixpkgs (#38624) and basically came to the conclusion it is not a good idea right now. The problem is that we can't safely put private stuff in the Nix store (https://github.com/NixOS/nix/issues/8). The private key will end up getting leaked into the .drv file which is available to anyone with access to your Nix store. When we start doing this on Hydra the key becomes pretty much worthless.

I think this is a pretty important thing to work towards, though. More and more computers are using secure boot.

ElvishJerricco commented 6 years ago

Would it be possible to sign files during activation, rather than during build? The problem, I suppose, would be that the activation script then depends on a signing key existing unencrypted on your file system, which is both impure and insecure. We can't have the activation script prompt the user for a decryption password, can we?

knedlsepp commented 5 years ago

Has anyone tried getting something working by using one of the signed shim bootloaders other distros are using?

etu commented 5 years ago

@knedlsepp Hey, someone mentioning having it set up in the nixos IRC-channel the other day.

Here's the piece of log covering this: https://logs.nix.samueldr.com/nixos/2018-11-07#1541583001-1541583306;

This seems to be the relevant links: https://git.joko.gr/nixos/gummibootr https://git.joko.gr/joko/etc-nixos/src/master/machines/munch.nix#L10

I haven't tried it myself though.

redfish64 commented 5 years ago

@etu I tried this and got it to work

Good things:

I looked at the code, specifically https://git.joko.gr/nixos/gummibootr/src/master/systemd-boot-builder.py and it seems comprehensive. It take the kernel, initird, and kernel parameters and sticks them all into one efi binary, and signs that binary using keys hardcoded as "/etc/uefi/DB.crt" and "etc/uefi/DB.key". As for my unskilled appraisal, this looks satisfactory.

Neutral things:

It recreates and signs all generations of the kernel that have not been garbage collected (ie. seen in systemd-boot as the prompt with names somewhat like Gen 60, Gen 61, Gen 62, ...). This sort of makes sense because if the keys have changed since "Gen 60" has been created and now we are on "Gen 63", for example, you do not want to not be able to run "Gen 60" using secure boot, even though it was created before the keys were changed. Realistically, though, the keys aren't going to change very often, so I'm not sure if I like this, especially because it causes more problems, see below (although this can be fixed).

You'll need efitools to create key pairs for the various EFI keys. I created a pull request for it, here: https://github.com/NixOS/nixpkgs/pull/53489 but it's not in nixpkgs yet.

Bad things:

Each kernel is understandably pretty big, because it now contains the initrd along with it (along with the kernel parameters, although I hope for godsake that in your system they themselves don't add much to the size...). The problem here is that because there are multiple generations that by default aren't cleaned up, the disk space fills up quickly.

I couldn't figure out how to get it to sign the initial "systemd-boot" (which in turn verifies and calls the kernel generations). It needs NIXOS_INSTALL_BOOTLOADER to be set to invoke that code. I simply hacked the code to remove the check. This check is also in the original "nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py" so I don't think is a good fix for the master branch, because I'm not sure of the implications... alternatively you could just sign it manually, using:

$ sbsign --key /etc/uefi/DB.key --cert /etc/uefi/DB.crt systemd-bootx64.efi --output systemd-bootx64.efi.signed $ mv systemd-bootx64.efi.signed systemd-bootx64.efi

Very bad things:

If the disk space fills up on your ESP (where the kernel generations live), running nixos-rebuild will destroy all of your kernel generations and not report an error, so if you aren't looking carefully at the output, next time you reboot, you won't be able to reboot into a working system using any of the generations because it tries to sign each one to another file, runs out of space and doesn't report the error (which, of course, happened to me*).

If I find the time I'll try and fix this.


* This can be fixed by disabling secureboot and using the nixos minimal boot disk, mount your encrypted root partition on /mnt and run:

$ nixos-enter

and clean up the old generations by running:

$ nix-env -p /nix/var/nix/profiles/system --delete-generations old $ nix-collect-garbage -d --delete-older-than 1d $ nixos-rebuild boot

ElvishJerricco commented 5 years ago

We could potentially write an efi application that does extra verification on the grub.cfg and on the initrd, separately from the kernel itself. This way it can all be kept separate, and merely changing kernel params doesn't have to duplicate either the kernel or the initrd. Of course you then also have to make sure grub doesn't let users modify command line args before booting.

knedlsepp commented 5 years ago

I'm currently piggybacking on an Ubuntu shim +grub to boot nixOS. It works fine, but I couldn't figure out how to do this from within nixOS, so I simply installed nixOS on top of an existing Ubuntu.

ElvishJerricco commented 5 years ago

You'd still need to write something in between shim and grub that actually verifies the relevant files with shim's protocol, right?

redfish64 commented 5 years ago

We could potentially write an efi application that does extra verification on the grub.cfg and on the initrd, separately from the kernel itself.

@ElvishJerricco This configuration doesn't use grub, but rather just systemd-bootx64.efi, which nixos fetches and builds using https://github.com/NixOS/systemd/ but otherwise your point stands. Since systemd is already forked, it wouldn't be too much work to do this.

OTOH, grub looks like it does this already, see https://ruderich.org/simon/notes/secure-boot-with-grub-and-signed-linux-and-initrd (although I haven't tried this), so it might be better just to alter the grub bootloader configuration in nixpkgs to support secureboot, rather than trying to hack systemd-boot.

lheckemann commented 5 years ago

@grahamc apparently has a somewhat-working solution for this, although it has problems with running out of space on /boot?

grahamc commented 5 years ago

See #53901

stale[bot] commented 4 years ago

Thank you for your contributions.

This has been automatically marked as stale because it has had no activity for 180 days.

If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity.

Here are suggestions that might help resolve this more quickly:

  1. Search for maintainers and people that previously touched the related code and @ mention them in a comment.
  2. Ask on the NixOS Discourse.
  3. Ask on the #nixos channel on irc.freenode.net.
Atemu commented 4 years ago

Still important to me.

Lunarequest commented 4 years ago

Have you guys considered using machine owner keys(MOKs) over signed bootloaders as MOKs are linked to one system. This would allow secure boot to be enabled.

KiaraGrouwstra commented 4 years ago

Have you guys considered using machine owner keys(MOKs) over signed bootloaders as MOKs are linked to one system. This would allow secure boot to be enabled.

for my original use-case, I was interested in booting NixOS on a machine at work I did not have keys for. that said I cannot speak to the use-cases of others, so curious to see what others might think. that said a general solution would seem nice tho.

lheckemann commented 4 years ago

@advaithm AFAIU #53901 uses MOKs.

Lunarequest commented 4 years ago

That's cool

stale[bot] commented 3 years ago

I marked this as stale due to inactivity. → More info

bbigras commented 3 years ago

bad bot!

TLATER commented 2 years ago

For future reference, since I will almost certainly come back here to check for the latest state again, #53901 was ultimately rejected, with @grahamc stating that he would share a counter proposal when it's ready.

In the mean time, I don't think there is currently another proposal.

chianuo commented 2 years ago

Just chiming in that this is important to me too. I have laptops that I would love to put NixOS on, but can't, because I need to keep Secure Boot enabled. Secure Boot is not going away and can't be ignored indefinitely... it's a little sad to see this issue still unresolved 3 years later.

grahamc commented 2 years ago

For what it is worth, I have a new implementation as a work in progress, and I’m looking for funding to finish it. Hopefully for 22.05, as 21.11 is quite soon. 

On September 24, 2021, GitHub @.***> wrote:

Just chiming in that this is important to me too. I have laptops that I would love to put NixOS on, but can't, because I need to keep Secure Boot enabled. Secure Boot is not going away and can't be ignored indefinitely... it's a little sad to see this issue still unresolved 3 years later.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/NixOS/nixpkgs/issues/42127#issuecomment-926975876, or unsubscribe https://github.com/notifications/unsubscribe- auth/AAASXLGZ3SSBLTGIXZSUQKDUDUGV3ANCNFSM4FFLE3PQ. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification- email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification- email%26utm_medium%3Demail%26utm_source%3Dgithub.

06kellyjac commented 2 years ago

Are you going to request funding through the NixOS org or is there somewhere people can donate?

florianjacob commented 2 years ago

Lennart Poettering recently wrote Authenticated Boot and Disk Encryption on Linux from the systemd perspective, which also touches how the boot process should be signed and verified.

Atemu commented 2 years ago

Every single component of the boot process and OS needs to be authenticated, i.e. all of shim (done), boot loader (done), kernel (done), initrd (missing so far), OS binary resources (missing so far), OS configuration and state (missing so far), the user's home (missing so far).

Authentication of OS binary resources and OS configuration/state would be an ideal use-case for Nix since all our paths are read-only and could therefore be covered by fsverity: https://github.com/NixOS/nix/issues/4917

TLATER commented 2 years ago

I think we're also uniquely in a good position to make initrd signing happen without the suggested modular approach. This is all a fair bit of work though (inspiring as it is), and requires booting with systemd which we also still don't do after several years of drafts from various people (latest, most likely one being #120015).

We should probably keep discussion on the issue at hand, which is just implementing signed boot at all. Some separate issues to support each of the features drafted in that blog post with an overall tracking issue likely makes more sense.

This issue is the first step of that big plan, it'd just be a shame if we still couldn't use secure boot at all in 3 years because we're too busy implementing some cutting edge initrd module system :)

pnmadelaine commented 2 years ago

Just chiming in that this is important to me too. I have laptops that I would love to put NixOS on, but can't, because I need to keep Secure Boot enabled. Secure Boot is not going away and can't be ignored indefinitely... it's a little sad to see this issue still unresolved 3 years later.

There is this solution https://github.com/NixOS/nixpkgs/pull/53901#issuecomment-894797193 that is ready. I use it on my laptop and it seems to me like the most straightforward solution to the problem : it signs unified kernel images at activation time, like described in Arch Wiki.

This issue is the first step of that big plan, it'd just be a shame if we still couldn't use secure boot at all in 3 years because we're too busy implementing some cutting edge initrd module system :)

It would be great to have some information about @grahamc implementation to know if it would be worth merging @frogamic solution right now.

Madouura commented 2 years ago

+1 to this, secure boot is a necessity.

Artturin commented 2 years ago

secure boot can be tested in a vm https://fedoraproject.org/wiki/Using_UEFI_with_QEMU?rd=Testing_secureboot_with_KVM#Creating_a_VM

nixos-discourse commented 2 years ago

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

https://discourse.nixos.org/t/encrypted-root-with-single-password-prompt/17054/3

ilikeavocadoes commented 2 years ago

Has there been any progress lately? Is there anything that can be done to help without having any know-how about UEFI?

06kellyjac commented 2 years ago

There has been progress

https://github.com/NixOS/rfcs/pull/125

https://github.com/DeterminateSystems/bootspec-secureboot

Im not sure how much more remains to be done other than finishing the RFC and stabilizing the bootspec format

weitzj commented 1 year ago

Just a hint: Would this project also be feasible to integrate with NixOs? Looks like it had secure boot available for ZFS

https://github.com/zbm-dev/zfsbootmenu

Atemu commented 1 year ago

Our bootloaders (systemd-boot and GRUB) already support secure boot. That's not the issue.

brainrake commented 1 year ago

secure boot support: https://github.com/nix-community/lanzaboote pr: https://github.com/NixOS/nixpkgs/pull/202497

chuangzhu commented 1 year ago

Just a hint: Would this project also be feasible to integrate with NixOs? Looks like it had secure boot available for ZFS

https://github.com/zbm-dev/zfsbootmenu

I also want to mention ZFSBootMenu. It is a unique approach that decrypts the filesystem at the boot loader stage so you can put the kernel and initrd encrypted in / alongside with the system. In this approach you don't have to sign kernel and initrd every time they update. However there are some drawbacks:

samueldr commented 1 year ago

ZFSBootMenu also uses kexec, which on x86_64 will most likely be fine, but is still YMMV.

nixos-discourse commented 1 year ago

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

https://discourse.nixos.org/t/dual-boot-on-a-secure-boot-enabled-system/31963/1