Files
matej.nix/features/bootloader.nix
2026-05-20 21:22:50 +02:00

177 lines
4.7 KiB
Nix

{
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";
};
};
})
]
);
};
}