diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index ed72e246453..2349e5e62bd 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1183,13 +1183,14 @@ ./system/boot/stage-2.nix ./system/boot/systemd.nix ./system/boot/systemd/coredump.nix + ./system/boot/systemd/initrd-secrets.nix + ./system/boot/systemd/initrd.nix ./system/boot/systemd/journald.nix ./system/boot/systemd/logind.nix ./system/boot/systemd/nspawn.nix ./system/boot/systemd/shutdown.nix ./system/boot/systemd/tmpfiles.nix ./system/boot/systemd/user.nix - ./system/boot/systemd/initrd.nix ./system/boot/timesyncd.nix ./system/boot/tmp.nix ./system/etc/etc-activation.nix diff --git a/nixos/modules/system/boot/systemd/initrd-secrets.nix b/nixos/modules/system/boot/systemd/initrd-secrets.nix new file mode 100644 index 00000000000..bc65880719d --- /dev/null +++ b/nixos/modules/system/boot/systemd/initrd-secrets.nix @@ -0,0 +1,36 @@ +{ config, pkgs, lib, ... }: + +{ + config = lib.mkIf (config.boot.initrd.enable && config.boot.initrd.systemd.enable) { + # Copy secrets into the initrd if they cannot be appended + boot.initrd.systemd.contents = lib.mkIf (!config.boot.loader.supportsInitrdSecrets) + (lib.mapAttrs' (dest: source: lib.nameValuePair "/.initrd-secrets/${dest}" { source = if source == null then dest else source; }) config.boot.initrd.secrets); + + # Copy secrets to their respective locations + boot.initrd.systemd.services.initrd-nixos-copy-secrets = lib.mkIf (config.boot.initrd.secrets != {}) { + description = "Copy secrets into place"; + # Run as early as possible + wantedBy = [ "sysinit.target" ]; + before = [ "cryptsetup-pre.target" ]; + unitConfig.DefaultDependencies = false; + + # We write the secrets to /.initrd-secrets and move them because this allows + # secrets to be written to /run. If we put the secret directly to /run and + # drop this service, we'd mount the /run tmpfs over the secret, making it + # invisible in stage 2. + script = '' + for secret in $(cd /.initrd-secrets; find . -type f); do + mkdir -p "$(dirname "/$secret")" + cp "/.initrd-secrets/$secret" "/$secret" + done + ''; + + unitConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + }; + # The script needs this + boot.initrd.systemd.extraBin.find = "${pkgs.findutils}/bin/find"; + }; +} diff --git a/nixos/tests/systemd-initrd-luks-keyfile.nix b/nixos/tests/systemd-initrd-luks-keyfile.nix index 970163c36a4..25c0c5bd866 100644 --- a/nixos/tests/systemd-initrd-luks-keyfile.nix +++ b/nixos/tests/systemd-initrd-luks-keyfile.nix @@ -32,7 +32,7 @@ in { }; }; virtualisation.bootDevice = "/dev/mapper/cryptroot"; - boot.initrd.systemd.contents."/etc/cryptroot.key".source = keyfile; + boot.initrd.secrets."/etc/cryptroot.key" = keyfile; }; };