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

Initrd verify stage 2 #273593

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

ElvishJerricco
Copy link
Contributor

Description of changes

Adds options for verifying the system closure during boot, and signing during switch-to-configuration.

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • 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/)
  • 24.05 Release Notes (or backporting 23.05 and 23.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
  • Fits CONTRIBUTING.md.

Add a 👍 reaction to pull requests you find important.

@github-actions github-actions bot added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` 6.topic: systemd labels Dec 11, 2023
@NickCao
Copy link
Member

NickCao commented Dec 11, 2023

Are there some background discussions on this?

@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10 labels Dec 11, 2023
@fricklerhandwerk
Copy link
Contributor

This work is part of the supply chain security project funded by the STF, so indeed there is some background real-time discussion because we're trying to make the deadline. Feel free to get in touch if you have any questions and let's take it to another channel (public if you wish) and keep the PRs for technical discussion.

@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/boot-time-integrity-checks-for-the-nix-store/36793/1

after = [ "initrd-fs.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${nix}/bin/nix --experimental-features nix-command verify -r --store /sysroot --trusted-public-keys \"${lib.concatStringsSep " " cfg.trustedPublicKeys}\" ${if cfg.sigsNeeded == 0 then "--no-trust" else "--sigs-needed " + toString cfg.sigsNeeded} \${NIXOS_SYSTEM_CLOSURE}";
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
ExecStart = "${nix}/bin/nix --experimental-features nix-command verify -r --store /sysroot --trusted-public-keys \"${lib.concatStringsSep " " cfg.trustedPublicKeys}\" ${if cfg.sigsNeeded == 0 then "--no-trust" else "--sigs-needed " + toString cfg.sigsNeeded} \${NIXOS_SYSTEM_CLOSURE}";
ExecStart = "${nix}/bin/nix --extra-experimental-features nix-command verify -r --store /sysroot --trusted-public-keys \"${lib.concatStringsSep " " cfg.trustedPublicKeys}\" ${if cfg.sigsNeeded == 0 then "--no-trust" else "--sigs-needed " + toString cfg.sigsNeeded} \${NIXOS_SYSTEM_CLOSURE}";

I am not sure if it would be relevant if ca-derivations or similar are used in the closures.

Copy link
Contributor

Choose a reason for hiding this comment

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

What do you mean? Content-address derivations have the hash in their path measure their contents, but it's not checked at boot- or access-time.

AFAIK, nix store verify still checks that the contents of CA derivations match their NAR hash, per the description:

For each path, it checks that

  • its contents match the NAR hash recorded in the Nix database; and
  • it is trusted, that is, it is signed by at least one trusted signing key, is content-addressed, or is built locally ("ultimately trusted").

That does lead to an interesting question, though: could an adversary manipulate the Nix db to change a CA derivation's expected hash ?

@@ -398,6 +419,9 @@ in {
ManagerEnvironment=${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "${n}=${lib.escapeShellArg v}") cfg.managerEnvironment)}
'';

# Make the system closure available as an environment variable.
"/etc/systemd/system-environment-generators/nixos-environment-generator".source = "${envGenerator}/bin/nixos-environment-generator";
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"/etc/systemd/system-environment-generators/nixos-environment-generator".source = "${envGenerator}/bin/nixos-environment-generator";
"/etc/systemd/system-environment-generators/nixos-environment-generator".source = lib.getExe envGenerator;

TIL that meta.mainProgram is prefilled for writeShellScriptBin

@@ -0,0 +1 @@
not-secret:0f9ZmCOeRdEa5HitWkOOfQDJQcrif06V+apZpSSHJ/WZL9ZDI2Guw7qEw3/cjBtKgh1r8MJoqQPWUmkL4gjZ5g==
Copy link
Member

Choose a reason for hiding this comment

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

To fix the editorconfig check we probably need to add a line sort of like

insert_final_newline = unset

@nbraud
Copy link
Contributor

nbraud commented Dec 31, 2023

Appologies if this is the wrong place to mention this, @ElvishJerricco

An alternative I experimented with (and discussed a bit with some people at CCCamp's NixOS tent this year) is using fs-verity to perform access-time verification, which solves 2 issues with boot-time verification:

  • boot isn't slowed down nearly as much, since all that needs to be checked is that the filesystem has the appropriate root hashes for the Merkle tree of each file in each drv output (rather than actually hash the contents) ;
  • TOCTOU (Time Of Check vs. TIme Of Use): this remains secure against an adversary tampering with storage after boot (most straightforward attack would probably be to suspend the system, write to the storage device, then resume it)

I'd be happy to share my experiences with that, and help upstream such a solution; the main issues I ran into were:

  • fs-verity depends on filesystem support; in particular, ZFS does not support this feature... yet?
  • builds shouldn't depend on FS support
    that could be worked around, using a userspace tool to perform the same tree hash as the kernel; libfsverity (from fsverity-utils) implements this, but its executable does not (yet?) expose the functionality

@ElvishJerricco
Copy link
Contributor Author

@nbraud It would probably be best to share that here: https://discourse.nixos.org/t/boot-time-integrity-checks-for-the-nix-store/36793

But the short version of my findings is that you can't actually verify that files are in the right locations with fs-verity, so e.g. it doesn't protect against the bash and systemd binaries being swapped, causing PID 1 to be a shell.

@nbraud
Copy link
Contributor

nbraud commented Jan 1, 2024

@nbraud It would probably be best to share that here: https://discourse.nixos.org/t/boot-time-integrity-checks-for-the-nix-store/36793

OK, let's take it to Discourse.
P.S. Having issues logging into Discourse, but I'll be home in a few days so I'll see then.

@wegank wegank added the 2.status: merge conflict This PR has merge conflicts with the target branch label Mar 20, 2024
@wegank wegank added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jul 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.status: merge conflict This PR has merge conflicts with the target branch 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 6.topic: systemd 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants