-
Notifications
You must be signed in to change notification settings - Fork 1
Secure_Boot
This documentation was generated by Claude
Make sure the file header is { lib, ... }: (not just {), import the module, and set the
loader:
{ lib, ... }: {
imports = [ inputs.lanzaboote.nixosModules.lanzaboote ]; # or add to default.nix imports
boot = {
# ... your existing hardware bits (luks, kernelModules, etc.) ...
loader = {
systemd-boot.enable = lib.mkForce false; # lanzaboote replaces systemd-boot
efi.canTouchEfiVariables = true;
};
lanzaboote = {
enable = true;
pkiBundle = "/var/lib/sbctl"; # the persisted sbctl key store
configurationLimit = 2; # <-- size to your ESP (see Step 0)
};
};
}environment.persistence."/persist".directories = [
# ...
"/var/lib/sbctl" # secure boot keys (already here)
];if not booted into a generation with /var/lib/sbctl use the following to bind mount it manually to be able to rebuild:
sudo mkdir -p /persist/var/lib/sbctl /var/lib/sbctl
sudo mount --bind /persist/var/lib/sbctl /var/lib/sbctl
sudo nix-shell -p sbctl --run 'sbctl create-keys'
nx-switch
Have sbctl available for the key steps below — either add it to systemPackages, or just use
nix-shell -p sbctl ad hoc (shown inline below).
Do not rebuild yet
Because you're already booted with the /var/lib/sbctl bind mount active, keys created here
land directly on persistent storage — just create them:
findmnt /var/lib/sbctl # sanity: confirm it's a persist bind mount
sudo nix-shell -p sbctl --run 'sbctl create-keys' # writes into the persisted store
sudo ls -la /persist/var/lib/sbctl/keys/ # confirm PK, KEK, db exist under /persist
If findmnt shows the source as your persist device (e.g. cryptpersist[/var/lib/sbctl]) and
keys/ contains PK, KEK, db, you're set.
sudo nixos-rebuild switch --flake .#<host>
Lanzaboote builds a signed UKI per generation (in /boot/EFI/Linux/) and a signed
systemd-boot stub. It boots normally because Secure Boot isn't enabled in firmware yet.
If it fails on
No space left on device: the ESP is too small or has leftover boot files. Free space, then rebuild — do not reboot in between:sudo sh -c 'du -sh /boot/EFI/* | sort -h' # find what's eating it sudo nix-collect-garbage -d # drop old generations # remove stale UKIs / dead bootloader files only after confirming what they are sudo nixos-rebuild switch --flake .#<host>Lower
configurationLimitif it still won't fit.
sudo sbctl verify
Every EFI image listed should be ✓ signed — the systemd-boot stub
(/boot/EFI/systemd/… and the /boot/EFI/BOOT/BOOTX64.EFI fallback) and each per-generation
UKI (/boot/EFI/Linux/*.efi). Unlike Limine, there's no standalone kernel on the ESP, so there
should be no ✗ lines to hand-wave. If anything shows ✗, fix it before enabling Secure Boot.
Reboot now and confirm the machine boots normally via lanzaboote (Secure Boot still off). This checkpoints the boot-chain switch before you touch firmware.
This machine dual-boots Windows, which changes three things. Do the BitLocker step before you touch the BIOS.
-
Back up your BitLocker recovery key first (critical). Windows 11 usually has BitLocker/Device Encryption on. Secure Boot state is measured into TPM PCR 7; clearing the firmware keys and enrolling your own changes PCR 7, breaks the TPM seal, and triggers a BitLocker recovery prompt on the next Windows boot. Before Step 5, either:
- retrieve the 48-digit key from https://aka.ms/myrecoverykey (signed into your MS account), or
- suspend BitLocker in Windows:
manage-bde -protectors -disable C: -RebootCount 0(re-enable with-enableafter everything is stable), or -
manage-bde -statusto check whether it's even on.
-
--microsoftis mandatory here (not optional). Windows Boot Manager (bootmgfw.efi) is signed with Microsoft's key. Enrolling only your own keys removes Microsoft's certs, so Windows would fail with a Secure Boot violation. In Step 6 you must keep--microsoft— the "try-falone" tightening does not apply on a dual-boot machine. -
Make the boot menu reachable to select Windows. systemd-boot (used by lanzaboote) auto-detects Windows Boot Manager and lists it, but your
common.nixsetsboot.loader.timeout = lib.mkForce 0, hiding the menu (hold space at boot to show it). For convenience, consider a small timeout on this host, e.g.:boot.loader.timeout = lib.mkForce 5;
Also recommended: keep sbctl recent (Microsoft is rotating to the 2023 UEFI CA certs; older
sbctl only enrolls the 2011 set, which can break a freshly-updated Windows), and disable
Windows Fast Startup (Control Panel → Power → Choose what the power buttons do) so a shared
NTFS partition isn't left in a hibernated/dirty state.
Enrolling your own keys requires the firmware in Setup Mode (no Platform Key enrolled).
- Power on and tap F10 repeatedly to enter BIOS Setup (or tap Esc for the Startup Menu, then F10). F9 is the one-time boot device menu.
- Find Secure Boot — usually under Advanced → Secure Boot Configuration, or System Configuration → Boot Options → Secure Boot (label varies by BIOS version).
- To reach Setup Mode, look for one of:
- "Clear Secure Boot Keys" / "Erase all Secure Boot Settings", or
- set Secure Boot mode to "Custom" (vs "Standard"), then clear/delete the existing keys.
- Leave Secure Boot itself disabled for now. Save & exit (HP will make you type a 4-digit confirmation code shown on screen, then Enter — that's normal).
⚠️ HP consumer caveat: if your BIOS only offers enable/disable + "Restore Factory Keys" and has no way to clear keys / no "Custom" mode, self-signed enrollment isn't possible on that firmware — you'd be stuck with Microsoft-signed shim instead. Check for the clear/custom option before proceeding. Most HP Insyde BIOSes have it.
sudo sbctl enroll-keys --microsoft --firmware-builtin
-
--firmware-builtin(-f): enrolls the certs already baked into your firmware — covers vendor-signed device option ROMs. Keep this. -
--microsoft(-m): trusts Microsoft's certs. Required on this dual-boot machine — it's what keeps Windows Boot Manager bootable (it also covers MS-signed option ROMs andfwupdcapsules). Do not drop it here; enrolling without it gives a Secure Boot violation when you try to boot Windows.
- F10 into BIOS again.
- Set Secure Boot = Enabled (same menu as Step 5). Save & exit (enter the 4-digit code again).
sudo sbctl status
You want:
Setup Mode: ✗ Disabled <- out of setup mode
Secure Boot: ✓ Enabled
Cross-check:
bootctl status
Look for Secure Boot: enabled (user) — (user) means SB is on, your Platform Key is
enrolled, and it's validating against your keys (only reachable out of setup mode). Since
lanzaboote is a signed systemd-boot stub, bootctl will report systemd-boot as the current
bootloader — that's expected here (it's the lanzaboote-signed variant).
TPM2 Support: no / Measured UKI: no are fine — you're doing key-based, not TPM-measured, boot.
Nothing here is permanent:
- F10 into BIOS → disable Secure Boot (or "Clear Secure Boot Keys" / "Restore Factory Keys"), boot, fix, re-enroll.
- systemd-boot (and thus lanzaboote) installs a signed stub at the removable fallback
EFI/BOOT/BOOTX64.EFIas well as the NVRAM entry, so a wiped NVRAM boot entry still boots the signed stub — the common HP failure mode is covered. -
Windows won't boot / "Secure Boot violation": you enrolled without
--microsoft. Re-runsudo sbctl enroll-keys --microsoft --firmware-builtin(firmware back in Setup Mode). Windows demands a recovery key: that's the expected PCR 7 change — enter the key you backed up; it boots normally afterward and re-seals.
# 1. Config: add lanzaboote flake input; import the module;
# boot.lanzaboote { enable; pkiBundle = "/var/lib/sbctl"; configurationLimit = 2; };
# systemd-boot off. (persistence for /var/lib/sbctl already set up) DON'T rebuild yet.
# 2. Keys (bind mount already live -> lands in /persist)
findmnt /var/lib/sbctl
sudo nix-shell -p sbctl --run 'sbctl create-keys'
sudo ls -la /persist/var/lib/sbctl/keys/
# 3. Build & sign (Secure Boot still OFF)
sudo nixos-rebuild switch --flake .#<host>
sudo sbctl verify # all EFI images ✓ (stub + per-gen UKIs)
# reboot, confirm lanzaboote boots
# 4. BIOS (F10): clear keys -> Setup Mode, leave SB disabled
sudo sbctl enroll-keys --microsoft --firmware-builtin
# BIOS (F10): enable Secure Boot (4-digit confirm)
# 5. Confirm
sudo sbctl status # Setup Mode: Disabled ; Secure Boot: Enabled
bootctl status # Secure Boot: enabled (user)
A note about getting AI assistance: Especially with deeper low level config, less intelligent AI models can overcomplicate and bloat the codebase with poor/hacky configuration. If you are going to use AI to modify this flake for you, I highly encourage you to understand the changes its making. AI is a great tool for learning Nix for the first time, but I suggest that you actively learn and understand from what its doing, consult the Nix search and don't be dependent on it.
If it helps to talk to a real person, I am always available to help you with any Nix/NixOS-related questions! (@amazinaxel on Discord)