Repository navigation
Secure Boot
modules/secureboot.nix adds lanzaboote
(pinned to a release tag in flake.nix): systemd-boot's signed stub and signed
unified kernel images, with your own keys in /var/lib/sbctl. The desktop host
configuration enables lanzaboote; Secure Boot still needs its keys enrolled in
firmware and enabled in the firmware menu. sbctl is installed either way.
The disks are already LUKS-encrypted; Secure Boot adds that only boot files you
signed will run, so nobody can swap the kernel or initrd on the unencrypted
/boot to capture the passphrase.
The cachyos kernel doesn't force lockdown under Secure Boot
(LOCK_DOWN_KERNEL_FORCE_NONE, no MODULE_SIG_FORCE), so the unsigned NVIDIA
modules keep loading.
-
Keys. If keys are not already present, run
sudo sbctl create-keys(into/var/lib/sbctl, root-only). Switching with the option on but no keys fails at the bootloader step (the running generation keeps booting). -
Sign. Set
dots.secureBoot.enable = true;, thennh os switch --impure. -
Check.
sudo sbctl verify:EFI/Boot/bootx64.efi,EFI/systemd/systemd-bootx64.efiand everyEFI/Linux/nixos-generation-*.efimust show as signed.EFI/nixos/kernel-*.efistays unsigned on purpose: the signed generation stubs hash-check the kernel and initrd before booting them. Leftovers from plain systemd-boot (*bzImage.efi,EFI/systemd/systemd-boot-fallbackx64.efi) can be deleted. -
Setup Mode.
systemctl reboot --firmware-setup, then in the firmware's Secure Boot menu reset or delete the keys so it enters Setup Mode (on ASUS boards: Key Management → Clear Secure Boot keys). Keep Secure Boot off for now. -
Enroll. Back in NixOS:
sudo sbctl enroll-keys --microsoft. Keep--microsoft: the RTX 3060's option ROM is Microsoft-signed, and without those keys the card can show nothing before Linux starts. -
Enable.
systemctl reboot --firmware-setup, turn Secure Boot on, boot.bootctl statusshould saySecure Boot: enabled (user).
With Secure Boot on, the TPM can unlock the root disk at boot without the passphrase. The key is sealed to two PCRs (TPM measurement registers):
- PCR 7, the Secure Boot state and keys. If Secure Boot is turned off, the keys change, or something signed only by Microsoft boots (a live USB), it won't unseal.
-
PCR 15 = 0. With
tpm2-measure-pcr=yesthe initrd extends PCR 15 as soon as it opens a volume. That stops a decoy volume (same UUID, attacker's passphrase) from being opened first and then used to unseal the real key.
Because the disk opens by itself, root's password is locked (users.users.root.hashedPassword = "!" in the host): a boot that drops to emergency mode refuses to open a shell instead of handing one to whoever is at the keyboard. Recover a machine that won't boot from the installer ISO; sudo is unaffected.
The passphrase keyslot stays as the fallback. A firmware update or a change to the Secure Boot settings changes PCR 7: you get the passphrase prompt, then re-enroll.
-
Confirm the root device. On this host, the root container UUID is
bd950db0-dc83-432a-bec6-0bc1a72bd76e(currently/dev/nvme1n1p2; NVMe device numbering can vary). The separate encrypted swap container isf04ed75f-34bc-4c92-b7db-379feff63a71(currently/dev/nvme1n1p3). Confirm these withlsblk -fbefore running enrollment commands; use the stable UUID path below, not a guessed partition number. -
Initrd.
dots.secureBoot.tpmUnlocklists theboot.initrd.luks.devicesnames. For this root, set it to[ "luks-bd950db0-dc83-432a-bec6-0bc1a72bd76e" ]inhosts/nixos/configuration.nix. Keepdots.secureBoot.enable = true;as well, since the module requires Secure Boot for TPM unlock. Switch the configuration and reboot; with no TPM keyslot yet, it should still ask for the existing passphrase. -
Enroll. After Secure Boot is enabled in firmware, enroll the TPM key on
the root container (not the encrypted swap container):
Add
sudo systemd-cryptenroll /dev/disk/by-uuid/bd950db0-dc83-432a-bec6-0bc1a72bd76e --tpm2-device=auto \ --tpm2-pcrs=7+15:sha256=0000000000000000000000000000000000000000000000000000000000000000--tpm2-with-pin=yesto still type a short PIN at boot; the TPM rate-limits guesses. - Reboot. Root should unlock without a prompt. The encrypted swap mapping partition is currently left untouched but is not configured as swap. The host uses zram and a swapfile instead, so boot does not wait for that volume.
Re-enroll after a PCR 7 change:
sudo systemd-cryptenroll /dev/disk/by-uuid/bd950db0-dc83-432a-bec6-0bc1a72bd76e --wipe-slot=tpm2
followed by step 3's enrollment command. Verify the target UUID with lsblk -f
before wiping or enrolling any slot.
To drop it, wipe the slot and empty the list.
Turn Secure Boot off in the firmware: everything still boots. To drop
lanzaboote too, set the option back to false and switch.
Source: docs/secure-boot.md
Generated from docs/. Edits made here are overwritten on the next push — change the repo instead.
Start
Reference
Help
More