Skip to main content

Secure Boot mit eigenem Kernel unter NixOS (lanzaboote)

Ausgangslage

Secure Boot ist ein System-weiter Schalter in der UEFI-Firmware: Ist er aktiv, muss jede EFI-Binary in der Bootkette signiert sein — Bootloader, Kernel, Initrd, egal von welchem Betriebssystem. Windows bringt seine eigenen (Microsoft-)Signaturen mit und läuft mit Secure Boot problemlos. Bei den meisten klassischen Linux-Distros signiert man Kernel/Bootloader einmalig mit sbctl.

Bei NixOS funktioniert das reine sbctl-Vorgehen aber nicht dauerhaft: Bei jedem nixos-rebuild landet ein neuer Kernel/Initrd im Nix-Store und wird neu nach /boot verlinkt — eine manuelle Signatur wäre nach dem nächsten Rebuild sofort wieder ungültig. Der Standardweg für NixOS ist deshalb lanzaboote: Es ersetzt systemd-boot als Bootmanager und signiert bei jeder Aktivierung automatisch mit.

Warum überhaupt Secure Boot aktivieren, wenn man "nur" Linux nutzt? In diesem Fall: weil zusätzlich Windows 11 (für Spiele) auf derselben Maschine installiert werden soll, und Windows 11 Secure Boot + TPM 2.0 als Systemvoraussetzung verlangt.

1. Firmware in Setup Mode bringen

Im UEFI-Setup (BIOS) die vorhandenen Secure-Boot-Keys löschen bzw. zurücksetzen ("Clear Secure Boot Keys" / "Setup Mode"). Secure Boot bleibt dabei zunächst aus — es wird nur der Zustand hergestellt, in dem sich neue eigene Keys einspielen lassen.

2. lanzaboote als Flake-Input einbinden

In flake.nix:

inputs = {
  nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  lanzaboote.url = "github:nix-community/lanzaboote";
  lanzaboote.inputs.nixpkgs.follows = "nixpkgs";
  # ... weitere Inputs
};

outputs = { self, nixpkgs, lanzaboote, ... }: {
  nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
    system = "x86_64-linux";
    modules = [
      ./configuration.nix
      lanzaboote.nixosModules.lanzaboote
      # ... weitere Module
    ];
  };
};

Hinweis: Den v0.4.2-Tag von lanzaboote gibt es zwar, er ist aber teils inkompatibel mit einem aktuellen nixpkgs-unstable (die boot.bootspec.enable-Option wurde entfernt, Bootspec wird inzwischen immer generiert). Deshalb den Input ohne Versions-Pin auf master zeigen lassen — github:nix-community/lanzaboote ohne /v0.4.2-Suffix.

Danach den Lockfile-Eintrag für den neuen Input erzeugen:

nix flake lock --update-input lanzaboote

3. Bootloader in configuration.nix umstellen

systemd-boot wird von lanzaboote ersetzt, canTouchEfiVariables bleibt bestehen. Die Funktionssignatur der Datei braucht zusätzlich lib (für lib.mkForce):

{ config, lib, pkgs, ... }:
{
  boot.loader.systemd-boot.enable = lib.mkForce false;
  boot.loader.efi.canTouchEfiVariables = true;

  boot.lanzaboote = {
    enable = true;
    pkiBundle = "/etc/secureboot";
  };
}

Vor dem eigentlichen Rebuild lohnt sich eine reine Evaluation, um Tippfehler/Inkompatibilitäten ohne Build zu erkennen:

nix eval .#nixosConfigurations.nixos.config.system.build.toplevel.drvPath

4. Keys erzeugen, enrollen, Rebuild

Ab hier sind Root-Rechte nötig:

# Eigene Secure-Boot-Keys erzeugen
sudo sbctl create-keys

# WICHTIG: Microsoft-Keys mit-enrollen, sonst bootet Windows danach nicht mehr
sudo sbctl enroll-keys --microsoft

# Rebuild – lanzaboote signiert Kernel/Initrd/Bootloader automatisch mit
sudo nixos-rebuild switch --flake /etc/nixos#<hostname>

# Status prüfen (Secure Boot in der Firmware ist an dieser Stelle noch aus)
sudo sbctl status
bootctl status

sbctl status sollte alle relevanten Boot-Dateien als "signed" ausweisen.

5. Secure Boot aktivieren

Neu starten, im UEFI-Setup Secure Boot aktivieren, speichern. NixOS sollte danach ganz normal weiter booten — nach jedem künftigen nixos-rebuild signiert lanzaboote automatisch neu, ein manueller Schritt entfällt.

Windows 11 danach installieren

Da Secure Boot bereits mit den Microsoft-Keys enrolled ist, kann Windows 11 installiert werden, ohne Secure Boot zwischendurch wieder auszuschalten.

Für die Zielplatte gilt: Nicht von Linux aus manuell partitionieren/formatieren. Der Windows-Installer legt sein eigenes Layout an (EFI System Partition, MSR, primäre NTFS-Partition, Recovery-Partition) und formatiert dabei selbst. Es reicht, die alte Partitionstabelle zu entfernen und die Platte im Windows-Setup auszuwählen:

sudo umount /pfad/zum/mountpoint   # falls die Platte gerade gemountet ist
sudo wipefs -a /dev/nvmeXn1        # Ziel-Gerät! Vorher unbedingt prüfen (lsblk),
                                    # dass es wirklich die richtige Platte ist

Danach im Windows-11-Setup die Platte auswählen, vorhandene Partitionen löschen, Windows den Rest automatisch erledigen lassen.

Bootreihenfolge im Blick behalten: Manche Windows-Installationen räumen die EFI-Bootvariablen um. Nach der Windows-Installation lohnt sich ein Blick mit efibootmgr, ob der NixOS-Eintrag noch vorhanden und als Default gesetzt ist — falls nicht, hilft ein erneutes sudo nixos-rebuild boot --flake /etc/nixos#<hostname> bzw. bootctl install, um den Eintrag wiederherzustellen.