diff options
Diffstat (limited to 'nixos/modules')
-rw-r--r-- | nixos/modules/module-list.nix | 1 | ||||
-rw-r--r-- | nixos/modules/security/sudo-rs.nix | 296 | ||||
-rw-r--r-- | nixos/modules/security/sudo.nix | 169 | ||||
-rw-r--r-- | nixos/modules/services/matrix/synapse.nix | 4 | ||||
-rw-r--r-- | nixos/modules/services/misc/mbpfan.nix | 19 | ||||
-rw-r--r-- | nixos/modules/services/search/typesense.nix | 4 | ||||
-rwxr-xr-x | nixos/modules/system/activation/switch-to-configuration.pl | 20 | ||||
-rw-r--r-- | nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh | 28 | ||||
-rw-r--r-- | nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix | 1 | ||||
-rw-r--r-- | nixos/modules/system/boot/stage-1.nix | 7 |
10 files changed, 428 insertions, 121 deletions
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index e17d430e59b..22724138d5d 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -311,6 +311,7 @@ ./security/rngd.nix ./security/rtkit.nix ./security/sudo.nix + ./security/sudo-rs.nix ./security/systemd-confinement.nix ./security/tpm2.nix ./security/wrappers/default.nix diff --git a/nixos/modules/security/sudo-rs.nix b/nixos/modules/security/sudo-rs.nix new file mode 100644 index 00000000000..6b8f09a8d3d --- /dev/null +++ b/nixos/modules/security/sudo-rs.nix @@ -0,0 +1,296 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + inherit (pkgs) sudo sudo-rs; + + cfg = config.security.sudo-rs; + + enableSSHAgentAuth = + with config.security; + pam.enableSSHAgentAuth && pam.sudo.sshAgentAuth; + + usingMillersSudo = cfg.package.pname == sudo.pname; + usingSudoRs = cfg.package.pname == sudo-rs.pname; + + toUserString = user: if (isInt user) then "#${toString user}" else "${user}"; + toGroupString = group: if (isInt group) then "%#${toString group}" else "%${group}"; + + toCommandOptionsString = options: + "${concatStringsSep ":" options}${optionalString (length options != 0) ":"} "; + + toCommandsString = commands: + concatStringsSep ", " ( + map (command: + if (isString command) then + command + else + "${toCommandOptionsString command.options}${command.command}" + ) commands + ); + +in + +{ + + ###### interface + + options.security.sudo-rs = { + + defaultOptions = mkOption { + type = with types; listOf str; + default = optional usingMillersSudo "SETENV"; + defaultText = literalMD '' + `[ "SETENV" ]` if using the default `sudo` implementation + ''; + description = mdDoc '' + Options used for the default rules, granting `root` and the + `wheel` group permission to run any command as any user. + ''; + }; + + enable = mkOption { + type = types.bool; + default = false; + description = mdDoc '' + Whether to enable the {command}`sudo` command, which + allows non-root users to execute commands as root. + ''; + }; + + package = mkOption { + type = types.package; + default = pkgs.sudo-rs; + defaultText = literalExpression "pkgs.sudo-rs"; + description = mdDoc '' + Which package to use for `sudo`. + ''; + }; + + wheelNeedsPassword = mkOption { + type = types.bool; + default = true; + description = mdDoc '' + Whether users of the `wheel` group must + provide a password to run commands as super user via {command}`sudo`. + ''; + }; + + execWheelOnly = mkOption { + type = types.bool; + default = false; + description = mdDoc '' + Only allow members of the `wheel` group to execute sudo by + setting the executable's permissions accordingly. + This prevents users that are not members of `wheel` from + exploiting vulnerabilities in sudo such as CVE-2021-3156. + ''; + }; + + configFile = mkOption { + type = types.lines; + # Note: if syntax errors are detected in this file, the NixOS + # configuration will fail to build. + description = mdDoc '' + This string contains the contents of the + {file}`sudoers` file. + ''; + }; + + extraRules = mkOption { + description = mdDoc '' + Define specific rules to be in the {file}`sudoers` file. + More specific rules should come after more general ones in order to + yield the expected behavior. You can use mkBefore/mkAfter to ensure + this is the case when configuration options are merged. + ''; + default = []; + example = literalExpression '' + [ + # Allow execution of any command by all users in group sudo, + # requiring a password. + { groups = [ "sudo" ]; commands = [ "ALL" ]; } + + # Allow execution of "/home/root/secret.sh" by user `backup`, `database` + # and the group with GID `1006` without a password. + { users = [ "backup" "database" ]; groups = [ 1006 ]; + commands = [ { command = "/home/root/secret.sh"; options = [ "SETENV" "NOPASSWD" ]; } ]; } + + # Allow all users of group `bar` to run two executables as user `foo` + # with arguments being pre-set. + { groups = [ "bar" ]; runAs = "foo"; + commands = + [ "/home/baz/cmd1.sh hello-sudo" + { command = '''/home/baz/cmd2.sh ""'''; options = [ "SETENV" ]; } ]; } + ] + ''; + type = with types; listOf (submodule { + options = { + users = mkOption { + type = with types; listOf (either str int); + description = mdDoc '' + The usernames / UIDs this rule should apply for. + ''; + default = []; + }; + + groups = mkOption { + type = with types; listOf (either str int); + description = mdDoc '' + The groups / GIDs this rule should apply for. + ''; + default = []; + }; + + host = mkOption { + type = types.str; + default = "ALL"; + description = mdDoc '' + For what host this rule should apply. + ''; + }; + + runAs = mkOption { + type = with types; str; + default = "ALL:ALL"; + description = mdDoc '' + Under which user/group the specified command is allowed to run. + + A user can be specified using just the username: `"foo"`. + It is also possible to specify a user/group combination using `"foo:bar"` + or to only allow running as a specific group with `":bar"`. + ''; + }; + + commands = mkOption { + description = mdDoc '' + The commands for which the rule should apply. + ''; + type = with types; listOf (either str (submodule { + + options = { + command = mkOption { + type = with types; str; + description = mdDoc '' + A command being either just a path to a binary to allow any arguments, + the full command with arguments pre-set or with `""` used as the argument, + not allowing arguments to the command at all. + ''; + }; + + options = mkOption { + type = with types; listOf (enum [ "NOPASSWD" "PASSWD" "NOEXEC" "EXEC" "SETENV" "NOSETENV" "LOG_INPUT" "NOLOG_INPUT" "LOG_OUTPUT" "NOLOG_OUTPUT" ]); + description = mdDoc '' + Options for running the command. Refer to the [sudo manual](https://www.sudo.ws/man/1.7.10/sudoers.man.html). + ''; + default = []; + }; + }; + + })); + }; + }; + }); + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = mdDoc '' + Extra configuration text appended to {file}`sudoers`. + ''; + }; + }; + + + ###### implementation + + config = mkIf cfg.enable { + security.sudo-rs.extraRules = + let + defaultRule = { users ? [], groups ? [], opts ? [] }: [ { + inherit users groups; + commands = [ { + command = "ALL"; + options = opts ++ cfg.defaultOptions; + } ]; + } ]; + in mkMerge [ + # This is ordered before users' `mkBefore` rules, + # so as not to introduce unexpected changes. + (mkOrder 400 (defaultRule { users = [ "root" ]; })) + + # This is ordered to show before (most) other rules, but + # late-enough for a user to `mkBefore` it. + (mkOrder 600 (defaultRule { + groups = [ "wheel" ]; + opts = (optional (!cfg.wheelNeedsPassword) "NOPASSWD"); + })) + ]; + + security.sudo-rs.configFile = concatStringsSep "\n" (filter (s: s != "") [ + '' + # Don't edit this file. Set the NixOS options ‘security.sudo-rs.configFile’ + # or ‘security.sudo-rs.extraRules’ instead. + '' + (optionalString enableSSHAgentAuth '' + # Keep SSH_AUTH_SOCK so that pam_ssh_agent_auth.so can do its magic. + Defaults env_keep+=SSH_AUTH_SOCK + '') + (concatStringsSep "\n" ( + lists.flatten ( + map ( + rule: optionals (length rule.commands != 0) [ + (map (user: "${toUserString user} ${rule.host}=(${rule.runAs}) ${toCommandsString rule.commands}") rule.users) + (map (group: "${toGroupString group} ${rule.host}=(${rule.runAs}) ${toCommandsString rule.commands}") rule.groups) + ] + ) cfg.extraRules + ) + ) + "\n") + (optionalString (cfg.extraConfig != "") '' + # extraConfig + ${cfg.extraConfig} + '') + ]); + + security.wrappers = let + owner = "root"; + group = if cfg.execWheelOnly then "wheel" else "root"; + setuid = true; + permissions = if cfg.execWheelOnly then "u+rx,g+x" else "u+rx,g+x,o+x"; + in { + sudo = { + source = "${cfg.package.out}/bin/sudo"; + inherit owner group setuid permissions; + }; + # sudo-rs does not yet ship a sudoedit (as of v0.2.0) + sudoedit = mkIf usingMillersSudo { + source = "${cfg.package.out}/bin/sudoedit"; + inherit owner group setuid permissions; + }; + }; + + environment.systemPackages = [ sudo ]; + + security.pam.services.sudo = { sshAgentAuth = true; usshAuth = true; }; + security.pam.services.sudo-i = mkIf usingSudoRs + { sshAgentAuth = true; usshAuth = true; }; + + environment.etc.sudoers = + { source = + pkgs.runCommand "sudoers" + { + src = pkgs.writeText "sudoers-in" cfg.configFile; + preferLocalBuild = true; + } + "${pkgs.buildPackages."${cfg.package.pname}"}/bin/visudo -f $src -c && cp $src $out"; + mode = "0440"; + }; + + }; + + meta.maintainers = [ lib.maintainers.nicoo ]; + +} diff --git a/nixos/modules/security/sudo.nix b/nixos/modules/security/sudo.nix index 4bdbe9671e6..d225442773c 100644 --- a/nixos/modules/security/sudo.nix +++ b/nixos/modules/security/sudo.nix @@ -4,16 +4,9 @@ with lib; let - inherit (pkgs) sudo sudo-rs; - cfg = config.security.sudo; - enableSSHAgentAuth = - with config.security; - pam.enableSSHAgentAuth && pam.sudo.sshAgentAuth; - - usingMillersSudo = cfg.package.pname == sudo.pname; - usingSudoRs = cfg.package.pname == sudo-rs.pname; + inherit (pkgs) sudo; toUserString = user: if (isInt user) then "#${toString user}" else "${user}"; toGroupString = group: if (isInt group) then "%#${toString group}" else "%${group}"; @@ -37,51 +30,41 @@ in ###### interface - options.security.sudo = { - - defaultOptions = mkOption { - type = with types; listOf str; - default = optional usingMillersSudo "SETENV"; - defaultText = literalMD '' - `[ "SETENV" ]` if using the default `sudo` implementation - ''; - description = mdDoc '' - Options used for the default rules, granting `root` and the - `wheel` group permission to run any command as any user. - ''; - }; + options = { - enable = mkOption { + security.sudo.enable = mkOption { type = types.bool; default = true; - description = mdDoc '' - Whether to enable the {command}`sudo` command, which - allows non-root users to execute commands as root. - ''; + description = + lib.mdDoc '' + Whether to enable the {command}`sudo` command, which + allows non-root users to execute commands as root. + ''; }; - package = mkOption { + security.sudo.package = mkOption { type = types.package; default = pkgs.sudo; defaultText = literalExpression "pkgs.sudo"; - description = mdDoc '' + description = lib.mdDoc '' Which package to use for `sudo`. ''; }; - wheelNeedsPassword = mkOption { + security.sudo.wheelNeedsPassword = mkOption { type = types.bool; default = true; - description = mdDoc '' - Whether users of the `wheel` group must - provide a password to run commands as super user via {command}`sudo`. - ''; + description = + lib.mdDoc '' + Whether users of the `wheel` group must + provide a password to run commands as super user via {command}`sudo`. + ''; }; - execWheelOnly = mkOption { + security.sudo.execWheelOnly = mkOption { type = types.bool; default = false; - description = mdDoc '' + description = lib.mdDoc '' Only allow members of the `wheel` group to execute sudo by setting the executable's permissions accordingly. This prevents users that are not members of `wheel` from @@ -89,18 +72,19 @@ in ''; }; - configFile = mkOption { + security.sudo.configFile = mkOption { type = types.lines; # Note: if syntax errors are detected in this file, the NixOS # configuration will fail to build. - description = mdDoc '' - This string contains the contents of the - {file}`sudoers` file. - ''; + description = + lib.mdDoc '' + This string contains the contents of the + {file}`sudoers` file. + ''; }; - extraRules = mkOption { - description = mdDoc '' + security.sudo.extraRules = mkOption { + description = lib.mdDoc '' Define specific rules to be in the {file}`sudoers` file. More specific rules should come after more general ones in order to yield the expected behavior. You can use mkBefore/mkAfter to ensure @@ -130,7 +114,7 @@ in options = { users = mkOption { type = with types; listOf (either str int); - description = mdDoc '' + description = lib.mdDoc '' The usernames / UIDs this rule should apply for. ''; default = []; @@ -138,7 +122,7 @@ in groups = mkOption { type = with types; listOf (either str int); - description = mdDoc '' + description = lib.mdDoc '' The groups / GIDs this rule should apply for. ''; default = []; @@ -147,7 +131,7 @@ in host = mkOption { type = types.str; default = "ALL"; - description = mdDoc '' + description = lib.mdDoc '' For what host this rule should apply. ''; }; @@ -155,7 +139,7 @@ in runAs = mkOption { type = with types; str; default = "ALL:ALL"; - description = mdDoc '' + description = lib.mdDoc '' Under which user/group the specified command is allowed to run. A user can be specified using just the username: `"foo"`. @@ -165,7 +149,7 @@ in }; commands = mkOption { - description = mdDoc '' + description = lib.mdDoc '' The commands for which the rule should apply. ''; type = with types; listOf (either str (submodule { @@ -173,7 +157,7 @@ in options = { command = mkOption { type = with types; str; - description = mdDoc '' + description = lib.mdDoc '' A command being either just a path to a binary to allow any arguments, the full command with arguments pre-set or with `""` used as the argument, not allowing arguments to the command at all. @@ -182,7 +166,7 @@ in options = mkOption { type = with types; listOf (enum [ "NOPASSWD" "PASSWD" "NOEXEC" "EXEC" "SETENV" "NOSETENV" "LOG_INPUT" "NOLOG_INPUT" "LOG_OUTPUT" "NOLOG_OUTPUT" ]); - description = mdDoc '' + description = lib.mdDoc '' Options for running the command. Refer to the [sudo manual](https://www.sudo.ws/man/1.7.10/sudoers.man.html). ''; default = []; @@ -195,10 +179,10 @@ in }); }; - extraConfig = mkOption { + security.sudo.extraConfig = mkOption { type = types.lines; default = ""; - description = mdDoc '' + description = lib.mdDoc '' Extra configuration text appended to {file}`sudoers`. ''; }; @@ -208,52 +192,44 @@ in ###### implementation config = mkIf cfg.enable { - security.sudo.extraRules = - let - defaultRule = { users ? [], groups ? [], opts ? [] }: [ { - inherit users groups; - commands = [ { - command = "ALL"; - options = opts ++ cfg.defaultOptions; - } ]; - } ]; - in mkMerge [ - # This is ordered before users' `mkBefore` rules, - # so as not to introduce unexpected changes. - (mkOrder 400 (defaultRule { users = [ "root" ]; })) - - # This is ordered to show before (most) other rules, but - # late-enough for a user to `mkBefore` it. - (mkOrder 600 (defaultRule { - groups = [ "wheel" ]; - opts = (optional (!cfg.wheelNeedsPassword) "NOPASSWD"); - })) - ]; - - security.sudo.configFile = concatStringsSep "\n" (filter (s: s != "") [ + assertions = [ + { assertion = cfg.package.pname != "sudo-rs"; + message = "The NixOS `sudo` module does not work with `sudo-rs` yet."; } + ]; + + # We `mkOrder 600` so that the default rule shows up first, but there is + # still enough room for a user to `mkBefore` it. + security.sudo.extraRules = mkOrder 600 [ + { groups = [ "wheel" ]; + commands = [ { command = "ALL"; options = (if cfg.wheelNeedsPassword then [ "SETENV" ] else [ "NOPASSWD" "SETENV" ]); } ]; + } + ]; + + security.sudo.configFile = '' # Don't edit this file. Set the NixOS options ‘security.sudo.configFile’ # or ‘security.sudo.extraRules’ instead. - '' - (optionalString enableSSHAgentAuth '' + # Keep SSH_AUTH_SOCK so that pam_ssh_agent_auth.so can do its magic. Defaults env_keep+=SSH_AUTH_SOCK - '') - (concatStringsSep "\n" ( - lists.flatten ( - map ( - rule: optionals (length rule.commands != 0) [ - (map (user: "${toUserString user} ${rule.host}=(${rule.runAs}) ${toCommandsString rule.commands}") rule.users) - (map (group: "${toGroupString group} ${rule.host}=(${rule.runAs}) ${toCommandsString rule.commands}") rule.groups) - ] - ) cfg.extraRules - ) - ) + "\n") - (optionalString (cfg.extraConfig != "") '' - # extraConfig + + # "root" is allowed to do anything. + root ALL=(ALL:ALL) SETENV: ALL + + # extraRules + ${concatStringsSep "\n" ( + lists.flatten ( + map ( + rule: optionals (length rule.commands != 0) [ + (map (user: "${toUserString user} ${rule.host}=(${rule.runAs}) ${toCommandsString rule.commands}") rule.users) + (map (group: "${toGroupString group} ${rule.host}=(${rule.runAs}) ${toCommandsString rule.commands}") rule.groups) + ] + ) cfg.extraRules + ) + )} + ${cfg.extraConfig} - '') - ]); + ''; security.wrappers = let owner = "root"; @@ -265,8 +241,7 @@ in source = "${cfg.package.out}/bin/sudo"; inherit owner group setuid permissions; }; - # sudo-rs does not yet ship a sudoedit (as of v0.2.0) - sudoedit = mkIf usingMillersSudo { + sudoedit = { source = "${cfg.package.out}/bin/sudoedit"; inherit owner group setuid permissions; }; @@ -275,8 +250,6 @@ in environment.systemPackages = [ sudo ]; security.pam.services.sudo = { sshAgentAuth = true; usshAuth = true; }; - security.pam.services.sudo-i = mkIf usingSudoRs - { sshAgentAuth = true; usshAuth = true; }; environment.etc.sudoers = { source = @@ -285,12 +258,12 @@ in src = pkgs.writeText "sudoers-in" cfg.configFile; preferLocalBuild = true; } - "${cfg.package}/bin/visudo -f $src -c && cp $src $out"; + # Make sure that the sudoers file is syntactically valid. + # (currently disabled - NIXOS-66) + "${pkgs.buildPackages.sudo}/sbin/visudo -f $src -c && cp $src $out"; mode = "0440"; }; }; - meta.maintainers = [ lib.maintainers.nicoo ]; - } diff --git a/nixos/modules/services/matrix/synapse.nix b/nixos/modules/services/matrix/synapse.nix index 5cce36f41e5..1354a8cb58b 100644 --- a/nixos/modules/services/matrix/synapse.nix +++ b/nixos/modules/services/matrix/synapse.nix @@ -1022,7 +1022,7 @@ in { systemd.targets.matrix-synapse = lib.mkIf hasWorkers { description = "Synapse Matrix parent target"; - after = [ "network.target" ] ++ optional hasLocalPostgresDB "postgresql.service"; + after = [ "network-online.target" ] ++ optional hasLocalPostgresDB "postgresql.service"; wantedBy = [ "multi-user.target" ]; }; @@ -1036,7 +1036,7 @@ in { unitConfig.ReloadPropagatedFrom = "matrix-synapse.target"; } else { - after = [ "network.target" ] ++ optional hasLocalPostgresDB "postgresql.service"; + after = [ "network-online.target" ] ++ optional hasLocalPostgresDB "postgresql.service"; wantedBy = [ "multi-user.target" ]; }; baseServiceConfig = { diff --git a/nixos/modules/services/misc/mbpfan.nix b/nixos/modules/services/misc/mbpfan.nix index e75c3525414..8f64fb2d9c5 100644 --- a/nixos/modules/services/misc/mbpfan.nix +++ b/nixos/modules/services/misc/mbpfan.nix @@ -26,7 +26,7 @@ in { aggressive = mkOption { type = types.bool; - default = false; + default = true; description = lib.mdDoc "If true, favors higher default fan speeds."; }; @@ -38,17 +38,20 @@ in { options.general.low_temp = mkOption { type = types.int; - default = 63; + default = (if cfg.aggressive then 55 else 63); + defaultText = literalExpression "55"; description = lib.mdDoc "If temperature is below this, fans will run at minimum speed."; }; options.general.high_temp = mkOption { type = types.int; - default = 66; + default = (if cfg.aggressive then 58 else 66); + defaultText = literalExpression "58"; description = lib.mdDoc "If temperature is above this, fan speed will gradually increase."; }; options.general.max_temp = mkOption { type = types.int; - default = 86; + default = (if cfg.aggressive then 78 else 86); + defaultText = literalExpression "78"; description = lib.mdDoc "If temperature is above this, fans will run at maximum speed."; }; options.general.polling_interval = mkOption { @@ -70,13 +73,6 @@ in { ]; config = mkIf cfg.enable { - services.mbpfan.settings = mkIf cfg.aggressive { - general.min_fan1_speed = mkDefault 2000; - general.low_temp = mkDefault 55; - general.high_temp = mkDefault 58; - general.max_temp = mkDefault 70; - }; - boot.kernelModules = [ "coretemp" "applesmc" ]; environment.systemPackages = [ cfg.package ]; environment.etc."mbpfan.conf".source = settingsFile; @@ -86,6 +82,7 @@ in { wantedBy = [ "sysinit.target" ]; after = [ "syslog.target" "sysinit.target" ]; restartTriggers = [ config.environment.etc."mbpfan.conf".source ]; + serviceConfig = { Type = "simple"; ExecStart = "${cfg.package}/bin/mbpfan -f${verbose}"; diff --git a/nixos/modules/services/search/typesense.nix b/nixos/modules/services/search/typesense.nix index 856c3cad22d..c158d04fea2 100644 --- a/nixos/modules/services/search/typesense.nix +++ b/nixos/modules/services/search/typesense.nix @@ -83,12 +83,12 @@ in { Group = "typesense"; StateDirectory = "typesense"; - StateDirectoryMode = "0700"; + StateDirectoryMode = "0750"; # Hardening CapabilityBoundingSet = ""; LockPersonality = true; - MemoryDenyWriteExecute = true; + # MemoryDenyWriteExecute = true; needed since 0.25.1 NoNewPrivileges = true; PrivateUsers = true; PrivateTmp = true; diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl index 8bd450d7343..e05f89bb0fb 100755 --- a/nixos/modules/system/activation/switch-to-configuration.pl +++ b/nixos/modules/system/activation/switch-to-configuration.pl @@ -74,7 +74,7 @@ if ("@localeArchive@" ne "") { if (!defined($action) || ($action ne "switch" && $action ne "boot" && $action ne "test" && $action ne "dry-activate")) { print STDERR <<"EOF"; -Usage: $0 [switch|boot|test] +Usage: $0 [switch|boot|test|dry-activate] switch: make the configuration the boot default and activate now boot: make the configuration the boot default @@ -661,10 +661,20 @@ foreach my $mount_point (keys(%{$cur_fss})) { # Filesystem entry disappeared, so unmount it. $units_to_stop{$unit} = 1; } elsif ($cur->{fsType} ne $new->{fsType} || $cur->{device} ne $new->{device}) { - # Filesystem type or device changed, so unmount and mount it. - $units_to_stop{$unit} = 1; - $units_to_start{$unit} = 1; - record_unit($start_list_file, $unit); + if ($mount_point eq '/' or $mount_point eq '/nix') { + if ($cur->{options} ne $new->{options}) { + # Mount options changed, so remount it. + $units_to_reload{$unit} = 1; + record_unit($reload_list_file, $unit); + } else { + # Don't unmount / or /nix if the device changed + $units_to_skip{$unit} = 1; + } + } else { + # Filesystem type or device changed, so unmount and mount it. + $units_to_restart{$unit} = 1; + record_unit($restart_list_file, $unit); + } } elsif ($cur->{options} ne $new->{options}) { # Mount options changes, so remount it. $units_to_reload{$unit} = 1; diff --git a/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh index 1a0da005029..84a0a93ded1 100644 --- a/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh +++ b/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh @@ -70,13 +70,33 @@ copyToKernelsDir() { addEntry() { local path=$(readlink -f "$1") local tag="$2" # Generation number or 'default' + local current="$3" # whether this is the current/latest generation if ! test -e $path/kernel -a -e $path/initrd; then return fi + if test -e "$path/append-initrd-secrets"; then + local initrd="$target/nixos/$(basename "$path")-initramfs-with-secrets" + cp $(readlink -f "$path/initrd") "$initrd" + chmod 600 "${initrd}" + chown 0:0 "${initrd}" + filesCopied[$initrd]=1 + + "$path/append-initrd-secrets" "$initrd" || if test "${current}" = "1"; then + echo "failed to create initrd secrets for the current generation." >&2 + echo "are your \`boot.initrd.secrets\` still in place?" >&2 + exit 1 + else + echo "warning: failed to create initrd secrets for \"$path\", an older generation" >&2 + echo "note: this is normal after having removed or renamed a file in \`boot.initrd.secrets\`" >&2 + fi + else + copyToKernelsDir "$path/initrd"; initrd=$result + fi + copyToKernelsDir "$path/kernel"; kernel=$result - copyToKernelsDir "$path/initrd"; initrd=$result + dtbDir=$(readlink -m "$path/dtbs") if [ -e "$dtbDir" ]; then copyToKernelsDir "$dtbDir"; dtbs=$result @@ -130,18 +150,20 @@ MENU TITLE ------------------------------------------------------------ TIMEOUT $timeout EOF -addEntry $default default >> $tmpFile +addEntry $default default 1 >> $tmpFile if [ "$numGenerations" -gt 0 ]; then # Add up to $numGenerations generations of the system profile to the menu, # in reverse (most recent to least recent) order. + current=1 for generation in $( (cd /nix/var/nix/profiles && ls -d system-*-link) \ | sed 's/system-\([0-9]\+\)-link/\1/' \ | sort -n -r \ | head -n $numGenerations); do link=/nix/var/nix/profiles/system-$generation-link - addEntry $link $generation + addEntry $link $generation $current + current=0 done >> $tmpFile fi diff --git a/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix b/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix index 9c9bee93de8..c64ef092667 100644 --- a/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix +++ b/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix @@ -142,6 +142,7 @@ in assertion = !pkgs.stdenv.hostPlatform.isAarch64 || cfg.version >= 3; message = "Only Raspberry Pi >= 3 supports aarch64."; }; + boot.loader.supportsInitrdSecrets = cfg.uboot.enable; system.build.installBootLoader = builder; system.boot.loader.id = "raspberrypi"; diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index a3551f68dbe..1cf58dbe9f1 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -610,6 +610,13 @@ in path the secret should have inside the initrd, the value is the path it should be copied from (or null for the same path inside and out). + + The loader `generic-extlinux-compatible` supports this. Because + it is not well know how different implementations react to + concatenated cpio archives, this is disabled by default. It can be + enabled by setting {option}`boot.loader.supportsInitrdSecrets` + to true. If this works for you, please report your findings at + https://github.com/NixOS/nixpkgs/issues/247145 . ''; example = literalExpression '' |