From 06b5b95a8ae3138f39fc7b812b5610d1235deed2 Mon Sep 17 00:00:00 2001 From: Swarsel Date: Sat, 28 Dec 2024 03:06:45 +0100 Subject: [PATCH] feat: deploy secure boot on bootstrap --- SwarselSystems.org | 56 ++++++++++++++++++++------ hosts/nixos/nbl-imba-2/default.nix | 3 +- hosts/nixos/toto/default.nix | 13 ++++-- lib/default.nix | 1 + modules/nixos/setup.nix | 1 + profiles/common/nixos/impermanence.nix | 2 +- profiles/iso/minimal.nix | 1 + scripts/bootstrap.sh | 36 +++++++++++++---- 8 files changed, 87 insertions(+), 26 deletions(-) diff --git a/SwarselSystems.org b/SwarselSystems.org index 002bb33..182c471 100644 --- a/SwarselSystems.org +++ b/SwarselSystems.org @@ -1249,7 +1249,8 @@ My work machine. Built for more security, this is the gold standard of my config loader.efi.canTouchEfiVariables = true; lanzaboote = { enable = true; - pkiBundle = "/etc/secureboot"; + # pkiBundle = "/etc/secureboot"; + pkiBundle = "/var/lib/sbctl"; }; supportedFilesystems = [ "btrfs" ]; kernelPackages = lib.mkDefault pkgs.linuxPackages_latest; @@ -1752,6 +1753,7 @@ This is a slim setup for developing base configuration. inputs.sops-nix.nixosModules.sops inputs.impermanence.nixosModules.impermanence + inputs.lanzaboote.nixosModules.lanzaboote "${profilesPath}/optional/nixos/autologin.nix" "${profilesPath}/common/nixos/settings.nix" @@ -1791,15 +1793,21 @@ This is a slim setup for developing base configuration. sops vim just + sbctl ]; system.stateVersion = lib.mkForce "23.05"; boot = { - loader.systemd-boot.enable = lib.mkForce true; loader.efi.canTouchEfiVariables = true; supportedFilesystems = [ "btrfs" ]; kernelPackages = lib.mkDefault pkgs.linuxPackages_latest; + loader.systemd-boot.enable = lib.swarselsystems.mkIfElse (config.swarselsystems.initialSetup || !config.swarselsystems.isSecureBoot) (lib.mkForce true) (lib.mkForce false); + lanzaboote = lib.mkIf (!config.swarselsystems.initialSetup && config.swarselsystems.isSecureBoot) { + enable = true; + pkiBundle = "/var/lib/sbctl"; + # enrollKeys = true; + }; }; @@ -1812,10 +1820,10 @@ This is a slim setup for developing base configuration. wallpaper = self + /wallpaper/lenovowp.png; isImpermanence = true; isCrypted = true; - initialSetup = true; + isSecureBoot = true; isSwap = true; swapSize = "8G"; - rootDisk = "/dev/vda"; + rootDisk = "/dev/nvme0n1"; } sharedOptions; home-manager.users.swarsel.swarselsystems = lib.recursiveUpdate { @@ -2853,14 +2861,14 @@ This program sets up a new NixOS host remotely. It also takes care of secret man SOPS_FILE=".sops.yaml" sed -i "{ - # Remove any * and & entries for this host - /[*&]$key_name/ d; - # Inject a new age: entry - # n matches the first line following age: and p prints it, then we transform it while reusing the spacing - /age:/{n; p; s/\(.*- \*\).*/\1$key_name/}; - # Inject a new hosts or user: entry - /&$key_type/{n; p; s/\(.*- &\).*/\1$key_name $key/} - }" $SOPS_FILE + # Remove any * and & entries for this host + /[*&]$key_name/ d; + # Inject a new age: entry + # n matches the first line following age: and p prints it, then we transform it while reusing the spacing + /age:/{n; p; s/\(.*- \*\).*/\1$key_name/}; + # Inject a new hosts or user: entry + /&$key_type/{n; p; s/\(.*- &\).*/\1$key_name $key/} + }" $SOPS_FILE green "Updating .sops.yaml" cd - } @@ -2975,9 +2983,14 @@ This program sets up a new NixOS host remotely. It also takes care of secret man # ------------------------ green "Generating hardware-config.nix for $target_hostname and adding it to the nix-config." $ssh_root_cmd "nixos-generate-config --force --no-filesystems --root /mnt" + + green "Injecting initialSetup" + $ssh_root_cmd "sed -i '/ boot.extraModulePackages /a \ swarselsystems.initialSetup = true;' /mnt/etc/nixos/hardware-configuration.nix" + mkdir -p "$FLAKE"/hosts/nixos/"$target_hostname" $scp_cmd root@"$target_destination":/mnt/etc/nixos/hardware-configuration.nix "${git_root}"/hosts/nixos/"$target_hostname"/hardware-configuration.nix # ------------------------ + green "Deploying minimal NixOS installation on $target_destination" SHELL=/bin/sh nix run github:nix-community/nixos-anywhere -- --ssh-port "$ssh_port" --extra-files "$temp" --flake .#"$target_hostname" root@"$target_destination" @@ -2994,7 +3007,17 @@ This program sets up a new NixOS host remotely. It also takes care of secret man yellow "$target_destination is not yet ready." fi done + # ------------------------ + green "Setting up secure boot keys" + $ssh_root_cmd "mkdir -p /var/lib/sbctl" + read -ra scp_call <<< "${scp_cmd}" + sudo "${scp_call[@]}" -r /var/lib/sbctl root@"$target_destination":/var/lib/ + $ssh_root_cmd "sbctl enroll-keys --ignore-immutable --microsoft || true" + # ------------------------ + green "restoring hardware-configuration" + sed -i '/swarselsystems\.initialSetup = true;/d' "$git_root"/hosts/nixos/"$target_hostname"/hardware-configuration.nix + if [ -n "$persist_dir" ]; then $ssh_root_cmd "cp /etc/machine-id $persist_dir/etc/machine-id || true" $ssh_root_cmd "cp -R /etc/ssh/ $persist_dir/etc/ssh/ || true" @@ -3073,6 +3096,11 @@ This program sets up a new NixOS host remotely. It also takes care of secret man echo fi + # # ------------------------ + # green "Enrolling secure boot keys" + # $ssh_root_cmd "sbctl enroll-keys --microsoft" + # ------------------------ + if yes_or_no "You can now commit and push the nix-config, which includes the hardware-configuration.nix for $target_hostname?"; then cd "${git_root}" deadnix hosts/nixos/"$target_hostname"/hardware-configuration.nix -qe @@ -3651,6 +3679,7 @@ I usually use =mutableUsers = false= in my NixOS configuration. However, on a ne options.swarselsystems.isBtrfs = lib.mkEnableOption "use btrfs filesystem"; options.swarselsystems.isImpermanence = lib.mkEnableOption "use impermanence on this system"; + options.swarselsystems.isSecureBoot = lib.mkEnableOption "use secure boot on this system"; } #+end_src @@ -5624,7 +5653,7 @@ Normally, doing that also resets the lecture that happens on the first use of =s "/etc/nixos" "/etc/nix" "/etc/NetworkManager/system-connections" - "/etc/secureboot" + # "/etc/secureboot" "/var/db/sudo" "/var/cache" "/var/lib" @@ -7977,6 +8006,7 @@ Options that I need specifically at work. There are more options at [[#h:f0b2ea9 sops vim just + sbctl ]; programs = { diff --git a/hosts/nixos/nbl-imba-2/default.nix b/hosts/nixos/nbl-imba-2/default.nix index 1ab327a..695435c 100644 --- a/hosts/nixos/nbl-imba-2/default.nix +++ b/hosts/nixos/nbl-imba-2/default.nix @@ -45,7 +45,8 @@ in loader.efi.canTouchEfiVariables = true; lanzaboote = { enable = true; - pkiBundle = "/etc/secureboot"; + # pkiBundle = "/etc/secureboot"; + pkiBundle = "/var/lib/sbctl"; }; supportedFilesystems = [ "btrfs" ]; kernelPackages = lib.mkDefault pkgs.linuxPackages_latest; diff --git a/hosts/nixos/toto/default.nix b/hosts/nixos/toto/default.nix index f128658..e32377f 100644 --- a/hosts/nixos/toto/default.nix +++ b/hosts/nixos/toto/default.nix @@ -14,6 +14,7 @@ in inputs.sops-nix.nixosModules.sops inputs.impermanence.nixosModules.impermanence + inputs.lanzaboote.nixosModules.lanzaboote "${profilesPath}/optional/nixos/autologin.nix" "${profilesPath}/common/nixos/settings.nix" @@ -53,15 +54,21 @@ in sops vim just + sbctl ]; system.stateVersion = lib.mkForce "23.05"; boot = { - loader.systemd-boot.enable = lib.mkForce true; loader.efi.canTouchEfiVariables = true; supportedFilesystems = [ "btrfs" ]; kernelPackages = lib.mkDefault pkgs.linuxPackages_latest; + loader.systemd-boot.enable = lib.swarselsystems.mkIfElse (config.swarselsystems.initialSetup || !config.swarselsystems.isSecureBoot) (lib.mkForce true) (lib.mkForce false); + lanzaboote = lib.mkIf (!config.swarselsystems.initialSetup && config.swarselsystems.isSecureBoot) { + enable = true; + pkiBundle = "/var/lib/sbctl"; + # enrollKeys = true; + }; }; @@ -75,10 +82,10 @@ in wallpaper = self + /wallpaper/lenovowp.png; isImpermanence = true; isCrypted = true; - initialSetup = true; + isSecureBoot = true; isSwap = true; swapSize = "8G"; - rootDisk = "/dev/vda"; + rootDisk = "/dev/nvme0n1"; } sharedOptions; diff --git a/lib/default.nix b/lib/default.nix index ae4262a..ed90255 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -4,4 +4,5 @@ (lib.mkIf p yes) (lib.mkIf (!p) no) ]; + mkIfElse = p: yes: no: if p then yes else no; } diff --git a/modules/nixos/setup.nix b/modules/nixos/setup.nix index 70dbeb8..1810cae 100644 --- a/modules/nixos/setup.nix +++ b/modules/nixos/setup.nix @@ -30,4 +30,5 @@ options.swarselsystems.isBtrfs = lib.mkEnableOption "use btrfs filesystem"; options.swarselsystems.isImpermanence = lib.mkEnableOption "use impermanence on this system"; + options.swarselsystems.isSecureBoot = lib.mkEnableOption "use secure boot on this system"; } diff --git a/profiles/common/nixos/impermanence.nix b/profiles/common/nixos/impermanence.nix index fbc9c52..810b453 100644 --- a/profiles/common/nixos/impermanence.nix +++ b/profiles/common/nixos/impermanence.nix @@ -74,7 +74,7 @@ in "/etc/nixos" "/etc/nix" "/etc/NetworkManager/system-connections" - "/etc/secureboot" + # "/etc/secureboot" "/var/db/sudo" "/var/cache" "/var/lib" diff --git a/profiles/iso/minimal.nix b/profiles/iso/minimal.nix index d274891..0dd966e 100644 --- a/profiles/iso/minimal.nix +++ b/profiles/iso/minimal.nix @@ -53,6 +53,7 @@ sops vim just + sbctl ]; programs = { diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh index 76e1fab..ecdaef1 100644 --- a/scripts/bootstrap.sh +++ b/scripts/bootstrap.sh @@ -78,14 +78,14 @@ function update_sops_file() { SOPS_FILE=".sops.yaml" sed -i "{ - # Remove any * and & entries for this host - /[*&]$key_name/ d; - # Inject a new age: entry - # n matches the first line following age: and p prints it, then we transform it while reusing the spacing - /age:/{n; p; s/\(.*- \*\).*/\1$key_name/}; - # Inject a new hosts or user: entry - /&$key_type/{n; p; s/\(.*- &\).*/\1$key_name $key/} - }" $SOPS_FILE + # Remove any * and & entries for this host + /[*&]$key_name/ d; + # Inject a new age: entry + # n matches the first line following age: and p prints it, then we transform it while reusing the spacing + /age:/{n; p; s/\(.*- \*\).*/\1$key_name/}; + # Inject a new hosts or user: entry + /&$key_type/{n; p; s/\(.*- &\).*/\1$key_name $key/} + }" $SOPS_FILE green "Updating .sops.yaml" cd - } @@ -200,9 +200,14 @@ fi # ------------------------ green "Generating hardware-config.nix for $target_hostname and adding it to the nix-config." $ssh_root_cmd "nixos-generate-config --force --no-filesystems --root /mnt" + +green "Injecting initialSetup" +$ssh_root_cmd "sed -i '/ boot.extraModulePackages /a \ swarselsystems.initialSetup = true;' /mnt/etc/nixos/hardware-configuration.nix" + mkdir -p "$FLAKE"/hosts/nixos/"$target_hostname" $scp_cmd root@"$target_destination":/mnt/etc/nixos/hardware-configuration.nix "${git_root}"/hosts/nixos/"$target_hostname"/hardware-configuration.nix # ------------------------ + green "Deploying minimal NixOS installation on $target_destination" SHELL=/bin/sh nix run github:nix-community/nixos-anywhere -- --ssh-port "$ssh_port" --extra-files "$temp" --flake .#"$target_hostname" root@"$target_destination" @@ -219,7 +224,17 @@ while true; do yellow "$target_destination is not yet ready." fi done + # ------------------------ +green "Setting up secure boot keys" +$ssh_root_cmd "mkdir -p /var/lib/sbctl" +read -ra scp_call <<< "${scp_cmd}" +sudo "${scp_call[@]}" -r /var/lib/sbctl root@"$target_destination":/var/lib/ +$ssh_root_cmd "sbctl enroll-keys --ignore-immutable --microsoft || true" +# ------------------------ +green "restoring hardware-configuration" +sed -i '/swarselsystems\.initialSetup = true;/d' "$git_root"/hosts/nixos/"$target_hostname"/hardware-configuration.nix + if [ -n "$persist_dir" ]; then $ssh_root_cmd "cp /etc/machine-id $persist_dir/etc/machine-id || true" $ssh_root_cmd "cp -R /etc/ssh/ $persist_dir/etc/ssh/ || true" @@ -298,6 +313,11 @@ else echo fi +# # ------------------------ +# green "Enrolling secure boot keys" +# $ssh_root_cmd "sbctl enroll-keys --microsoft" +# ------------------------ + if yes_or_no "You can now commit and push the nix-config, which includes the hardware-configuration.nix for $target_hostname?"; then cd "${git_root}" deadnix hosts/nixos/"$target_hostname"/hardware-configuration.nix -qe