diff --git a/features/bootloader.nix b/features/bootloader.nix index 31e6e2b..e583ebb 100644 --- a/features/bootloader.nix +++ b/features/bootloader.nix @@ -3,11 +3,23 @@ { 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 ]; @@ -23,15 +35,88 @@ default = "systemd-boot"; }; - plymouth.enable = lib.mkEnableOption "plymouth boot splash"; + 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; - # request the largest framebuffer uefi offers; plymouth inherits it - boot.loader.systemd-boot.consoleMode = "max"; + + # lanzaboote inherits editor + configurationLimit from systemd-boot.* + boot.loader.systemd-boot = { + editor = false; + inherit (cfg) configurationLimit; + }; + + boot.initrd.systemd.enable = true; + + # block simpledrm so fbcon defers until the gpu driver binds; avoids + # the simpledrm -> real-driver fbcon transition that mangles console + # text and leaves the luks prompt typing offset from the visible + # surface. hosts must put the gpu driver in initrd (nixos-hardware + # does this for amd; manual hardware.amdgpu.initrd.enable on others) + boot.kernelParams = [ "initcall_blacklist=simpledrm_platform_driver_init" ]; + + # verbose boot: kernel messages and systemd unit lines visible end + # to end. trade-off: the luks prompt will be interleaved with the + # last few "Starting/Started ..." lines (no upstream fix exists + # without plymouth). boot.initrd.verbose is a no-op under + # systemd-initrd, so not set here. + + # readable luks prompt at panel-native dpi + console = { + earlySetup = true; + font = cfg.consoleFont; + packages = [ pkgs.terminus_font ]; + }; } (lib.mkIf (cfg.mode == "systemd-boot") { @@ -46,26 +131,41 @@ }; }) - (lib.mkIf cfg.plymouth.enable { - # plymouth needs systemd-initrd to render the luks prompt cleanly - boot.initrd.systemd.enable = true; + (lib.mkIf (cfg.resumeDevice != null) { + boot.resumeDevice = cfg.resumeDevice; + }) - # host is responsible for early-KMS so plymouth lands on the gpu driver, - # not simpledrm (e.g. hardware.amdgpu.initrd.enable on amd hosts) - boot.plymouth.enable = true; - stylix.targets.plymouth.logoAnimated = false; + (lib.mkIf cfg.initrdSsh.enable { + boot.initrd.systemd.settings.Manager.DefaultDeviceTimeoutSec = "infinity"; - 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.initrd.availableKernelModules = [ cfg.initrdSsh.networkModule ]; + + boot.kernelParams = lib.mkIf cfg.initrdSsh.ip.enable [ + "ip=${mkIpString cfg.initrdSsh.ip}" ]; - boot.consoleLogLevel = 0; - boot.initrd.verbose = false; + + boot.initrd.network = { + enable = true; + ssh = { + enable = true; + port = 22; + hostKeys = [ + "${keyDir}/ssh_host_rsa_key" + "${keyDir}/ssh_host_ed25519_key" + ]; + inherit (cfg.initrdSsh) authorizedKeys; + }; + }; + + # forward LUKS password prompt to the ssh session (systemd-initrd idiom) + boot.initrd.systemd.users.root.shell = "/bin/systemd-tty-ask-password-agent"; + + boot.initrd.systemd.network.networks = lib.mkIf (!cfg.initrdSsh.ip.enable) { + "10-initrd" = { + matchConfig.Driver = cfg.initrdSsh.networkModule; + networkConfig.DHCP = "yes"; + }; + }; }) ] ); diff --git a/features/initrd-ssh.nix b/features/initrd-ssh.nix deleted file mode 100644 index 5255914..0000000 --- a/features/initrd-ssh.nix +++ /dev/null @@ -1,90 +0,0 @@ -{ - nixos = - { lib, config, ... }: - let - cfg = config.features.initrd-ssh; - keyDir = "/etc/secrets/initrd"; - - mkIpString = - { - address, - gateway, - netmask, - interface, - ... - }: - "${address}::${gateway}:${netmask}::${interface}:none"; - in - { - options.features.initrd-ssh = { - enable = lib.mkEnableOption "initrd ssh"; - - 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 = [ ]; - }; - - networkModule = lib.mkOption { - type = lib.types.str; - }; - }; - - config = lib.mkIf cfg.enable { - boot.initrd.availableKernelModules = [ cfg.networkModule ]; - boot.initrd.kernelModules = [ cfg.networkModule ]; - boot.kernelParams = lib.mkIf cfg.ip.enable [ - "ip=${mkIpString cfg.ip}" - ]; - - boot.initrd.systemd.enable = true; - - # remote unlock may take a while; don't let device units give up - boot.initrd.systemd.settings.Manager.DefaultDeviceTimeoutSec = "infinity"; - - boot.initrd.network = { - enable = true; - ssh = { - enable = true; - port = 22; - hostKeys = [ - "${keyDir}/ssh_host_rsa_key" - "${keyDir}/ssh_host_ed25519_key" - ]; - inherit (cfg) authorizedKeys; - }; - }; - - # systemd-networkd retries DHCP indefinitely, unlike udhcpc - boot.initrd.systemd.network.networks = lib.mkIf (!cfg.ip.enable) { - "10-initrd" = { - matchConfig.Driver = cfg.networkModule; - networkConfig.DHCP = "yes"; - }; - }; - - # forward LUKS password prompt to the SSH session - boot.initrd.systemd.users.root.shell = "/bin/systemd-tty-ask-password-agent"; - }; - }; -} diff --git a/features/power.nix b/features/power.nix index bd580e1..4a3f901 100644 --- a/features/power.nix +++ b/features/power.nix @@ -8,11 +8,6 @@ options.features.power = { enable = lib.mkEnableOption "laptop power management"; - resumeDevice = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - }; - lidSwitch = lib.mkOption { type = lib.types.str; default = "suspend-then-hibernate"; @@ -40,8 +35,6 @@ }; config = lib.mkIf cfg.enable { - boot.resumeDevice = lib.mkIf (cfg.resumeDevice != null) cfg.resumeDevice; - services.logind.settings.Login = { HandleLidSwitch = cfg.lidSwitch; HandlePowerKey = cfg.powerKey; diff --git a/flake/hosts.nix b/flake/hosts.nix index 288f0eb..9e66c77 100644 --- a/flake/hosts.nix +++ b/flake/hosts.nix @@ -55,7 +55,6 @@ in "git" "gnupg" "harmonia" - "initrd-ssh" "localisation" "neovim" "networkmanager" diff --git a/hosts/fw16/configuration.nix b/hosts/fw16/configuration.nix index 395e521..723c8d9 100644 --- a/hosts/fw16/configuration.nix +++ b/hosts/fw16/configuration.nix @@ -10,16 +10,13 @@ inputs.nixos-hardware.nixosModules.framework-16-amd-ai-300-series ]; - features.bootloader.plymouth.enable = true; + features.bootloader.resumeDevice = "/dev/mapper/vg0-swap"; features.desktop.bluetooth.enable = true; features.gnupg.yubikey.enable = true; features.udev = { ledger.enable = true; keyboard-zsa.enable = true; }; - features.power.resumeDevice = "/dev/disk/by-uuid/ff4750e7-3a9f-42c2-bb68-c458a6560540"; - - boot.kernelParams = [ "pcie_aspm.policy=powersupersave" ]; programs.nix-ld.libraries = options.programs.nix-ld.libraries.default; diff --git a/hosts/fw16/hardware-configuration.nix b/hosts/fw16/hardware-configuration.nix index a27e69c..d2857e3 100644 --- a/hosts/fw16/hardware-configuration.nix +++ b/hosts/fw16/hardware-configuration.nix @@ -37,10 +37,7 @@ fileSystems."/boot" = { device = "/dev/disk/by-uuid/42D9-FAFD"; fsType = "vfat"; - options = [ - "fmask=0022" - "dmask=0022" - ]; + options = [ "umask=0077" ]; }; swapDevices = [ diff --git a/hosts/tower/configuration.nix b/hosts/tower/configuration.nix index 3ae111f..d44d050 100644 --- a/hosts/tower/configuration.nix +++ b/hosts/tower/configuration.nix @@ -8,7 +8,11 @@ features.nix-settings.towerCache.enable = false; features.bootloader = { mode = "lanzaboote"; - plymouth.enable = true; + initrdSsh = { + enable = true; + networkModule = "r8169"; + authorizedKeys = userKeys.sshAuthorizedKeys; + }; }; features.desktop.bluetooth.enable = true; features.gnupg.yubikey.enable = true; @@ -16,17 +20,14 @@ ledger.enable = true; keyboard-zsa.enable = true; }; - features.initrd-ssh = { - networkModule = "r8169"; - authorizedKeys = userKeys.sshAuthorizedKeys; - }; # nix store signing sops.secrets.nix-signing-key.sopsFile = ../../secrets/tower.yaml; nix.settings.secret-key-files = [ config.sops.secrets.nix-signing-key.path ]; boot.kernelParams = [ "btusb.reset=1" ]; - # early kms so plymouth lands on amdgpu, not simpledrm + # pairs with bootloader's simpledrm initcall blacklist: amdgpu owns fbcon + # from the start, no driver-swap mode-set hardware.amdgpu.initrd.enable = true; services.udisks2.enable = true;