{ nixos = { config, lib, pkgs, inputs, ... }: let cfg = config.features.bootloader; keyDir = "/etc/secrets/initrd"; mkIpString = { address, gateway, netmask, interface, ... }: "${address}::${gateway}:${netmask}::${interface}:none"; in { imports = [ inputs.lanzaboote.nixosModules.lanzaboote ]; options.features.bootloader = { enable = lib.mkEnableOption "bootloader"; mode = lib.mkOption { type = lib.types.enum [ "systemd-boot" "lanzaboote" ]; default = "systemd-boot"; }; configurationLimit = lib.mkOption { type = lib.types.int; default = 10; }; consoleFont = lib.mkOption { type = lib.types.str; default = "ter-v32n"; }; resumeDevice = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; }; initrdSsh = { enable = lib.mkEnableOption "remote LUKS unlock via ssh in initrd"; networkModule = lib.mkOption { type = lib.types.str; }; ip = { enable = lib.mkEnableOption "static IP for initrd (otherwise DHCP)"; address = lib.mkOption { type = lib.types.str; }; gateway = lib.mkOption { type = lib.types.str; }; netmask = lib.mkOption { type = lib.types.str; default = "255.255.255.0"; }; interface = lib.mkOption { type = lib.types.str; }; }; authorizedKeys = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; }; }; }; config = lib.mkIf cfg.enable ( lib.mkMerge [ { boot.loader.efi.canTouchEfiVariables = true; # lanzaboote inherits editor, configurationLimit, consoleMode from systemd-boot.* boot.loader.systemd-boot = { editor = false; consoleMode = "max"; inherit (cfg) configurationLimit; }; # plymouth owns the framebuffer end-to-end: hides simpledrm -> amdgpu # handover, renders luks prompt on its own surface, stock bgrt theme boot.plymouth.enable = true; stylix.targets.plymouth.enable = false; boot.initrd.systemd.enable = true; boot.kernelParams = [ "quiet" "splash" "loglevel=3" "rd.systemd.show_status=false" "rd.udev.log_level=3" "udev.log_priority=3" "plymouth.force-scale=1" ]; boot.consoleLogLevel = 0; boot.initrd.verbose = false; # fallback when plymouth fails: readable kernel-console font console = { earlySetup = true; font = cfg.consoleFont; packages = [ pkgs.terminus_font ]; }; } (lib.mkIf (cfg.mode == "systemd-boot") { boot.loader.systemd-boot.enable = true; }) (lib.mkIf (cfg.mode == "lanzaboote") { boot.loader.systemd-boot.enable = lib.mkForce false; boot.lanzaboote = { enable = true; pkiBundle = "/var/lib/sbctl"; }; }) (lib.mkIf (cfg.resumeDevice != null) { boot.resumeDevice = cfg.resumeDevice; }) (lib.mkIf cfg.initrdSsh.enable { boot.initrd.systemd.settings.Manager.DefaultDeviceTimeoutSec = "infinity"; boot.initrd.availableKernelModules = [ cfg.initrdSsh.networkModule ]; boot.kernelParams = lib.mkIf cfg.initrdSsh.ip.enable [ "ip=${mkIpString cfg.initrdSsh.ip}" ]; boot.initrd.network = { enable = true; ssh = { enable = true; port = 22; hostKeys = [ "${keyDir}/ssh_host_rsa_key" "${keyDir}/ssh_host_ed25519_key" ]; # forward LUKS password prompt to the SSH session shell = "/bin/systemd-tty-ask-password-agent"; inherit (cfg.initrdSsh) authorizedKeys; }; }; boot.initrd.systemd.network.networks = lib.mkIf (!cfg.initrdSsh.ip.enable) { "10-initrd" = { matchConfig.Driver = cfg.initrdSsh.networkModule; networkConfig.DHCP = "yes"; }; }; }) ] ); }; }