From b75f44ceab66da233c4047ef783abec1632a82d7 Mon Sep 17 00:00:00 2001 From: aaron Date: Sat, 3 Oct 2026 10:39:28 +0200 Subject: [PATCH 1/2] feature(lanzaboote): add support for secure-boot through lanazaboote --- flake.lock | 99 +++++++++++++++++++++++++++++++++ flake.nix | 4 ++ hosts/krypton/configuration.nix | 1 + modules/nixos/lanzaboote.nix | 25 +++++++++ 4 files changed, 129 insertions(+) create mode 100644 modules/nixos/lanzaboote.nix diff --git a/flake.lock b/flake.lock index c5ca9f5..1187909 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,36 @@ { "nodes": { + "crane": { + "locked": { + "lastModified": 1789760033, + "narHash": "sha256-jtT4yxZpR8seYnlCMMWSSPlFN92zO6ICuZ8pJrmi86k=", + "owner": "ipetkov", + "repo": "crane", + "rev": "73b980519cefc727a5f6cc8e5c0947a2f9be6edd", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1767039857, + "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", + "owner": "NixOS", + "repo": "flake-compat", + "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "flake-compat", + "type": "github" + } + }, "flake-parts": { "inputs": { "nixpkgs-lib": [ @@ -41,6 +72,30 @@ "type": "github" } }, + "lanzaboote": { + "inputs": { + "crane": "crane", + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit": "pre-commit", + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1790423250, + "narHash": "sha256-sr4Kfp6yaXUeyKL6n0Y8/ElcR3momIRC20HFc+LF22s=", + "owner": "nix-community", + "repo": "lanzaboote", + "rev": "c1c5edd31802d181c8aa2c71588995d93425d650", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "v1.2.0", + "repo": "lanzaboote", + "type": "github" + } + }, "nixos-hardware": { "inputs": { "nixpkgs": [ @@ -119,15 +174,59 @@ "type": "github" } }, + "pre-commit": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1789514889, + "narHash": "sha256-PFD1nxptCXJyJoiYO1gf/5Vv43yqGpHtMC6LUhl9/pQ=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "59f4ca0d063a1a3ec722c88b51a33004862e5379", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, "root": { "inputs": { "home-manager": "home-manager", + "lanzaboote": "lanzaboote", "nixos-hardware": "nixos-hardware", "nixpkgs": "nixpkgs", "nixvim": "nixvim", "noctalia": "noctalia" } }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1789889921, + "narHash": "sha256-aL/ogiN7qZCGeNovS1f9hX73jwYIKb4Pcq6AZm57WtY=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "1fb104a12a8667045559b2575d6d448ae2fbd99b", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, "systems": { "flake": false, "locked": { diff --git a/flake.nix b/flake.nix index 84bc252..7e72e9a 100644 --- a/flake.nix +++ b/flake.nix @@ -11,6 +11,10 @@ url = "github:noctalia-dev/noctalia-shell"; inputs.nixpkgs.follows = "nixpkgs"; }; + lanzaboote = { + url = "github:nix-community/lanzaboote/v1.2.0"; + inputs.nixpkgs.follows = "nixpkgs"; + }; nixos-hardware = { url = "github:NixOS/nixos-hardware"; inputs.nixpkgs.follows = "nixpkgs"; diff --git a/hosts/krypton/configuration.nix b/hosts/krypton/configuration.nix index a711fe0..05059ae 100644 --- a/hosts/krypton/configuration.nix +++ b/hosts/krypton/configuration.nix @@ -12,6 +12,7 @@ ../../modules/nixos/certificates.nix ../../modules/nixos/docker.nix ../../modules/nixos/gnupg.nix + ../../modules/nixos/lanzaboote.nix ../../modules/nixos/locales.nix ../../modules/nixos/networking.nix ../../modules/nixos/niri.nix diff --git a/modules/nixos/lanzaboote.nix b/modules/nixos/lanzaboote.nix new file mode 100644 index 0000000..ed57016 --- /dev/null +++ b/modules/nixos/lanzaboote.nix @@ -0,0 +1,25 @@ +# Secure Boot with lanzaboote. systemd-boot stays the bootloader, but lanzaboote +# installs it signed and writes signed boot entries instead of the nixos module. +# The keys are created once per host with `sudo sbctl create-keys` before the +# first rebuild, and enrolled into the firmware with `sbctl enroll-keys`. + +{ + inputs, + lib, + pkgs, + ... +}: + +{ + imports = [ inputs.lanzaboote.nixosModules.lanzaboote ]; + + boot.loader.systemd-boot.enable = lib.mkForce false; + + boot.lanzaboote = { + enable = true; + pkiBundle = "/var/lib/sbctl"; + }; + + # key management and verification + environment.systemPackages = [ pkgs.sbctl ]; +} -- 2.52.0 From a5e69c043df51bdcee81044c4a7a8ee5d40746d5 Mon Sep 17 00:00:00 2001 From: aaron Date: Sat, 3 Oct 2026 12:47:27 +0200 Subject: [PATCH 2/2] chore: update installation guide with secure-boot setup --- INSTALLATION.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/INSTALLATION.md b/INSTALLATION.md index 56d205c..568148c 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -102,10 +102,62 @@ nixos-install ## how to deploy the initial config - Don't forget to install the bootloader, if you changed it since `nixos-install` +- The fresh install has no flakes and no git yet, a temporary shell is enough +- If the installer iso is older than the flake's nixpkgs, `--no-reexec` keeps + `nixos-rebuild` from re-executing a newer version of itself, which can fail + against the older systemd of the fresh install (only needed once) +- Set a password for the user before rebooting, `users.nix` doesn't set one ```bash -$ sudo nixos-rebuild --install-bootloader switch --flake .#host_name +$ export NIX_CONFIG="experimental-features = nix-command flakes" +$ nix-shell -p git +$ sudo nixos-rebuild --install-bootloader boot --flake .#host_name --no-reexec +$ sudo passwd aaron ``` +## how to enable secure boot +Secure Boot uses lanzaboote with our own keys, see `modules/nixos/lanzaboote.nix`. +Do this after the initial config is deployed and boots. + +1. create the keys, before the first rebuild with the lanzaboote module +```bash +# the keys end up in /var/lib/sbctl, they never leave the host +$ sudo nix run nixpkgs#sbctl -- create-keys +``` + +2. import `modules/nixos/lanzaboote.nix` in the host's `configuration.nix`, rebuild and check the signatures +```bash +$ sudo nixos-rebuild switch --flake .#host_name +# EFI/Linux/*.efi and the bootloader must be signed, kernels in EFI/nixos +# are not, lanzaboote checks them by hash +$ sudo sbctl verify +``` + +3. reboot once with Secure Boot still disabled, to make sure the new entries boot + +4. in the firmware (F2), erase all Secure Boot keys, then boot nixos again +```bash +# "Setup Mode: ✗ Enabled", the ✗ only means the state is insecure +$ sudo sbctl status +``` + +5. enroll the keys +```bash +# only our own keys, no microsoft keys +$ sudo sbctl enroll-keys +``` +- sbctl refuses if the TPM eventlog shows option ROMs (e.g. a dedicated gpu). + Don't force it, either trust exactly those with `--tpm-eventlog` or + microsoft's keys with `--microsoft`. Without either, the firmware may not + start the device, in the worst case the machine doesn't boot at all. + +6. enable Secure Boot in the firmware and set a firmware password, then check +```bash +$ bootctl status | grep "Secure Boot" # enabled (user) +$ sudo sbctl status # Secure Boot: ✓ Enabled +``` +- If it doesn't boot anymore, disabling Secure Boot in the firmware boots as before +- Losing the keys isn't fatal: erase the keys in the firmware and start over at step 1 + ## how to upgrade the system ```bash $ cd /path/to/repo -- 2.52.0