New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Sign systemd boot EFI images for secure booting. #53901
Conversation
26d2e3f
to
7d1fc12
Compare
This whole PR was made sort of on a lark, I didn't exactly plan to set out and do this ... but here we are =) |
Replace the systemd bootloader module with my custom one, which was PR'd in NixOS/nixpkgs#53901.
Replace the systemd bootloader module with my custom one, which was PR'd in NixOS/nixpkgs#53901.
@GrahamcOfBorg test boot.uefiUsb |
nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
Outdated
Show resolved
Hide resolved
Very cool concept. PS: in the nix script you put in the description, is this line correct?
instead of:
|
7d1fc12
to
326b7dc
Compare
That line was actually correct, but resulted in the output in $out/usr/... I've now fixed that, and PR'd efitools separately: #54471 |
326b7dc
to
b80a723
Compare
nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
Outdated
Show resolved
Hide resolved
with efitools (`nix-shell -p efitools`) and running with openssl in the shell environment: $ cd /home/grahamc/projects/grahamc/secure-boot $ uuidgen --random > GUID.txt $ openssl req -newkey rsa:4096 -nodes -keyout PK.key -new -x509 -sha256 -days 3650 -subj "/CN=my Platform Key/" -out PK.crt $ openssl x509 -outform DER -in PK.crt -out PK.cer $ cert-to-efi-sig-list -g "$(< GUID.txt)" PK.crt PK.esl $ sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK PK.esl PK.auth $ sign-efi-sig-list -g "$(< GUID.txt)" -c PK.crt -k PK.key PK /dev/null rm_PK.auth $ openssl req -newkey rsa:4096 -nodes -keyout KEK.key -new -x509 -sha256 -days 3650 -subj "/CN=my Key Exchange Key/" -out KEK.crt $ openssl x509 -outform DER -in KEK.crt -out KEK.cer $ cert-to-efi-sig-list -g "$(< GUID.txt)" KEK.crt KEK.esl $ sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt KEK KEK.esl KEK.auth $ openssl req -newkey rsa:4096 -nodes -keyout db.key -new -x509 -sha256 -days 3650 -subj "/CN=my Signature Database key/" -out db.crt $ openssl x509 -outform DER -in db.crt -out db.cer $ cert-to-efi-sig-list -g "$(< GUID.txt)" db.crt db.esl $ sign-efi-sig-list -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db db.esl db.auth and then loading the .auth files in my UEFI firmware, then setting in my configuration.nix: boot = { loader = { systemd-boot = { enable = true; signed = true; signing-key = "/home/grahamc/projects/grahamc/secure-boot/db.key"; signing-certificate = "/home/grahamc/projects/grahamc/secure-boot/db.crt"; }; }; }; and running `nixos-rebuild boot` I was able to secure-boot my laptop. Note: this code signs EVERY boot entry for NixOS, and the BOOT files from systemd (even if they're already tampered with! since this code doesn't replace it.) AND does not allow a graceful key phase out. If the key is replaced in gen2, gen1's boot EFI is deleted and replaced with a new version. Also note this only works on x86-64 due to the assumptions in the builder.py. Finally, you can have much fewer generations: each generation on my laptop takes 20MB in /boot. Info taken from: - https://wiki.archlinux.org/index.php/Secure_Boot#Using_your_own_keys - https://systemd.io/BOOT_LOADER_SPECIFICATION#type-2-efi-unified-kernel-images - https://www.freedesktop.org/software/systemd/man/os-release.html
b80a723
to
357d388
Compare
nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
Outdated
Show resolved
Hide resolved
nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
Outdated
Show resolved
Hide resolved
nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
Outdated
Show resolved
Hide resolved
If you merge this feature could you drop your notes for setting up in the manual or the wiki? |
Only copy if we need to append initrd secrets, and even then don't copy to the EFI partition.
Note the whitespace-free diff is a bit easier to see the smaller changes: 68f7139?w=1 Yes definitely: docs is a blocker for this PR. But, so is having a few people try it out for a while. |
PS extending this Python code has not been a lot of fun :( |
It gets more fun, once it has type annotations and one has type checks running in its editor because the feedback cycle gets shorter. |
I can add the code from this PR still works fine on 20.09 when used as a module. |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/nixos-on-secure-boot-debian-based-laptop/10976/2 |
@danielfullmer Do you feel like taking this forward? It seems that @grahamc doesn't have time to push this anymore. I'm actually using this code for almost a year already and it would be really great if it made into 21.05. |
As an observer, what extra work is required to make this ready? (Excluding resolving merge conflicts) |
I think for something so security critical it needs an automatic VM test. I think that is pretty much it.
…On Sat, Jan 16, 2021, at 1:22 PM, Jack Kelly wrote:
As an observer, what extra work is required to make this ready? (Excluding resolving merge conflicts)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#53901 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AGCEZ2WQ7AHHSYX74VCXMTTS2HKPHANCNFSM4GPVW2YA>.
|
@hmenke I unfortunately can't commit to having time to finish up this PR. I should be available to answer any questions about the tests if anyone else would like to finish this up. I'd also like to add that we'd also need some documentation for this feature. However, I do have a slightly more recent version of the secure boot tests at: https://github.com/danielfullmer/nixpkgs/tree/secure-boot-wip2 I might not be the best to finish up this PR since I personally wasn't planning to use this feature on my machine until we also had working kernel module signing (#87426) and had chained integrity checking to the actual generation NixOS boots via dm-verity / fs-verity / IMA, or something similar, for which I don't have any great ideas. |
WOW! I kinda wanted to have this and now it exists. I don't think the security would suffer too much from the fact that files are re-signed on every |
Thanks a lot for this module. |
@cwyc Are you going to open a PR? 🙏 |
I've also tried out @danielfullmer 's tests. They work on my end, what is it that has to be changed? |
Maybe open a new PR and ask for reviews again. |
Please, please, if someone has the time and knowledge to take this over the finish line, please do. We will apparently not get very many testers without this having landed in nixpkgs, and the value of having this built-in and easily set up is so huge. |
@benpye I think a start would be addressing the review comments - there are plenty right there, some really low hanging fruit! |
It's something that really ought to be merged and functional by the time of the next release, because a lot of people are about to lose the option of running their systems with secure boot disabled. Given Windows 11 has it as a requirement, any operating system which doesn't support it at all can't boot. Not without reconfiguring your BIOS at every reboot, at any rate, which I don't think many people are going to do. Personally I've been running an indev version of 11, and... Well, it's a good upgrade. With the exception of the usual development snapshot bugs, most everything works better than on 10. I don't expect anyone who's already using NixOS to be stopped by this, so it might not seem that important, but losing the ability to dual-boot will make it far harder to make new converts. |
This sounds like FUD to me. I don't see why Windows11 making it a requirement makes the hardware or firmware behave differently than it has for years. I'd be interested in primary sources if you can provide some. I have a different approach to this PR in progress, but I don't think this particular implementation is good or worth merging: the lifecycle around signing is unfit for purpose. To that end, I'm closing this because I would be -1 on an implementation similar to this merging. |
@Baughn |
You can import several signing keys in UEFI. This way, I have my own Platform Key, two Key Exchange Keys (my own and Microsoft's, so Windows can autoupdate dbx), two keys in db (again, my own and Microsoft's), and dbx is full of Microsoft's revoked signs. This way, I have Secure dual-boot with Windows 10 and Ubuntu (autosigned by https://github.com/julian-klode/sicherboot). Installing NixOS requires disabling Secure Boot, which will somewhat lower my security, and this is one of the few reasons that stops me from daily driving NixOS. |
that only seems to be true for installation. I installed win 11 then turned off secure boot and am now back to dual booting win 11 and nixos |
@grahamc do please link your solution here once it's in a state worth looking at so we get a notification :) |
I don't know if Windows 11 has it as a requirement but I have been using it since release to Dev and the like past 3 updates and have not gotten anything needing Secure Boot to be re-enabled (whether during upgrade process or daily driving). |
The source would be https://blogs.windows.com/windows-insider/2021/06/28/update-on-windows-11-minimum-system-requirements/ It's true that at the moment you can disable secure boot after installation, and it'll keep running, but I don't think it's especially safe to assume that will still be the case with the final release. I've never seen any statement from MS saying it will be, and I don't think it'd be safe to assume even if I had. |
Okay. Good to confirm there is no imminent risk here. |
I have been meaning to implement an alternative to this myself for a while but I finally got round to it. This completely replaces the configuration file approach with unified kernel images. https://github.com/frogamic/nix-machines/tree/main/modules/systemd-secure-boot Some caveats:
Some thoughts I had while doing it:
|
I've used @frogamic approach on my laptop and I'd really like to see this in NixOS. A few comments I have:
|
Yes, my company determinate.systems has been investing considerable time and money in to a suitable implementation over the past two months. We're about ready to publish some WIP code. Typically we do all our work in public, however I wanted to have lots of room to experiment and try different approaches. We're also in the process of applying for funding to implement a few workflows. |
Any updates on this? |
with efitools (
nix-shell -p efitools
)and running with openssl in the shell environment:
and then loading the .auth files in my UEFI firmware, then setting in
my configuration.nix:
and running
nixos-rebuild boot
I was able to secure-boot my laptop.Note: this code signs EVERY boot entry for NixOS, and the BOOT files
from systemd (even if they're already tampered with! since this code
doesn't replace it.) AND does not allow a graceful key phase out. If
the key is replaced in gen2, gen1's boot EFI is deleted and replaced
with a new version.
Also note this only works on x86-64 due to the assumptions in the
builder.py.
Finally, you can have much fewer generations: each generation on my
laptop takes 20MB in /boot.
Info taken from: