Skip to content
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

Support external bootloader backends (RFC-0125) #172237

Merged
merged 23 commits into from Dec 17, 2022

Conversation

grahamc
Copy link
Member

@grahamc grahamc commented May 9, 2022

Description of changes

Experimental implementation of NixOS/rfcs#125.

To do:

  • Package the synthesis tool described in the RFC and as part of the documentation.

Not planned to be part of this PR:

  • Migrating the existing bootloaders to use RFC-0125.
Things done
  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 22.05 Release Notes (or backporting 21.11 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
    • (Release notes changes) Ran nixos/doc/manual/md-to-db.sh to update generated release notes
  • Fits CONTRIBUTING.md.

@Madouura
Copy link
Contributor

Madouura commented May 9, 2022

I hope this isn't too out-of-scope, but I think it may be a good idea to add some fields to bootspec for secure boot certificates/keys as well as a field for a hash of the current system closure for a TPM to verify against. Perhaps even some fields for kernel, bootloader, and any related hashes we could stick in a TPM and verify against, that aren't already included in the nixos system closure. (eg. kernel, bootloader, etc on /boot as ESP partition)
NixOS is very unique in that we can guarantee a certain set of software and data to be present and be what we are booting into, and we can update the TPM and secure boot keys/certs every nixos-rebuild. The implementation of this goes out of scope, but I wanted to explain why adding those fields may be a good idea for a future case.

@grahamc
Copy link
Member Author

grahamc commented May 10, 2022

some fields to bootspec for secure boot certificates/keys

This is definitely out of scope for bootspec, as those are configuration options that apply to the bootloader installation tool, and are highly policy-driven. Note that the RFC specifically mentions SecureBoot. Indeed, I have implemented secureboot against bootspec.

as well as a field for a hash of the current system closure for a TPM to verify against
[...]
Perhaps even some fields for kernel, bootloader, and any related hashes we could stick in a TPM and verify against

These may be useful fields, though I omitted them because those can be safely derived by the bootloader installation tool. For that reason, I'm not sure they should be included in the spec. This may be worth discussion in NixOS/rfcs#125.

NixOS is very unique in that we can guarantee a certain set of software and data to be present and be what we are booting into, and we can update the TPM and secure boot keys/certs every nixos-rebuild.

This is one of the very reasons it isn't appropriate to make those keys part of the system's closure: the policy of which keys and when they rotate is infinitely variable, and these parameters are very likely independent of a specific system closure. Embedding this information into the bootspec encodes policy which shouldn't be encoded.

As an aside, I didn't want to put too much of a point on it but: we worked on bootspec for precisely this reason: making SecureBoot work for different use cases.

@Madouura
Copy link
Contributor

Madouura commented May 11, 2022

Note that the RFC specifically mentions SecureBoot.

Yeah, that's why I was thinking it may be out-of-scope, I was thinking we might be able to use bootspec as a standardized way to either forward some information to different bootloaders or use it for gathering information to implement such a scheme for verified boot.

This is one of the very reasons it isn't appropriate to make those keys part of the system's closure: the policy of which keys and when they rotate is infinitely variable, and these parameters are very likely independent of a specific system closure

Okay, that's something I misunderstood. I didn't realize the bootspec document is part of the closure itself, in which case that throws my idea completely out, since we then can't guarantee things, thus ruining the entire point.
I'll have to think of a different method then, thank you for enlightening me.

@K900
Copy link
Contributor

K900 commented Jul 28, 2022

There's a small bug when using this on systems with no initrd, like nixos-on-wsl:

error: attribute 'initialRamdisk' missing

       at /nix/store/c9c7d2zfmjwcx3pmiygh06ggyhhwynwf-nixpkgs-patched/nixos/modules/system/activation/bootspec.nix:19:27:

           18|               kernelParams = config.boot.kernelParams;
           19|               initrd = "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}";
             |                           ^
           20|               initrdSecrets = "${config.system.build.initialRamdiskSecretAppender}/bin/append-initrd-secrets";

       … while evaluating the attribute 'text' of the derivation 'boot.v1.json'

       at /nix/store/c9c7d2zfmjwcx3pmiygh06ggyhhwynwf-nixpkgs-patched/pkgs/stdenv/generic/make-derivation.nix:270:7:

          269|     // (lib.optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) {
          270|       name =
             |       ^
          271|         let

       … while evaluating the attribute 'v1.generator'

       at /nix/store/c9c7d2zfmjwcx3pmiygh06ggyhhwynwf-nixpkgs-patched/nixos/modules/system/activation/bootspec.nix:24:7:

           23|
           24|       generator =
             |       ^
           25|         let

       … while evaluating the attribute 'writer'

       at /nix/store/c9c7d2zfmjwcx3pmiygh06ggyhhwynwf-nixpkgs-patched/nixos/modules/system/activation/bootspec.nix:55:3:

           54|   # the path of the `toplevel` itself and the `init` executable).
           55|   writer = schemas.v1.generator;
             |   ^
           56| }

       … while evaluating the attribute 'buildCommand' of the derivation 'nixos-system-sayaka-wsl-22.11pre-git'

       at /nix/store/c9c7d2zfmjwcx3pmiygh06ggyhhwynwf-nixpkgs-patched/pkgs/stdenv/generic/make-derivation.nix:270:7:

          269|     // (lib.optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) {
          270|       name =
             |       ^
          271|         let

cole-h and others added 22 commits December 8, 2022 13:50
This allows supporting external bootloader backends.
This does the following:

* turns bootspec into a NixOS module
* validates bootspecs with Cue
* exposes internal knobs
This will test various scenarios of bootspec generation.
We separate the different steps (injecting the toplevel and injecting
the specialisations) so that it's easy to document what each snippet is
actually doing.
The documentation is generated thanks to `meta.doc`, and was out of
date anyways.
The bootspec package provides synthesis and validation tooling for
RFC-0125 compliant bootspec documents.
@RaitoBezarius
Copy link
Member

As this is a PR guarded by an experimental flag and multiple tests and one which is in good shape, I think I can self-merge it in the next days once the GRUB fix is landed. Plus, it is easy to revert and enable developers to test SecureBoot (and more!) properly.

@Mic92 Mic92 merged commit 668a2b2 into NixOS:master Dec 17, 2022
@lheckemann lheckemann deleted the bootspec-rfc branch December 20, 2022 18:21
Comment on lines +115 to +122
warnings = [
''RFC-0125 is not merged yet, this is a feature preview of bootspec.
The schema is not definitive and features are not guaranteed to be stable until RFC-0125 is merged.
See:
- https://github.com/NixOS/nixpkgs/pull/172237 to track merge status in nixpkgs.
- https://github.com/NixOS/rfcs/pull/125 to track RFC status.
''
];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no native way to turn this rather annoying warning off other than introducing another option?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An other way to turn it off is to merge RFC-0125 :)

@infinisil infinisil added the significant Novel ideas, large API changes, notable refactorings, issues with RFC potential, etc. label Apr 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants