diff options
Diffstat (limited to 'nixos/modules/system/boot/systemd')
-rw-r--r-- | nixos/modules/system/boot/systemd/initrd.nix | 28 | ||||
-rw-r--r-- | nixos/modules/system/boot/systemd/journald.nix | 3 | ||||
-rw-r--r-- | nixos/modules/system/boot/systemd/nspawn.nix | 3 | ||||
-rw-r--r-- | nixos/modules/system/boot/systemd/shutdown.nix | 10 | ||||
-rw-r--r-- | nixos/modules/system/boot/systemd/sysusers.nix | 215 | ||||
-rw-r--r-- | nixos/modules/system/boot/systemd/tmpfiles.nix | 6 |
6 files changed, 138 insertions, 127 deletions
diff --git a/nixos/modules/system/boot/systemd/initrd.nix b/nixos/modules/system/boot/systemd/initrd.nix index 6107a2594baf8..0caea104b1b52 100644 --- a/nixos/modules/system/boot/systemd/initrd.nix +++ b/nixos/modules/system/boot/systemd/initrd.nix @@ -70,6 +70,7 @@ let "systemd-tmpfiles-setup-dev.service" "systemd-tmpfiles-setup.service" "timers.target" + "tpm2.target" "umount.target" "systemd-bsod.service" ] ++ cfg.additionalUpstreamUnits; @@ -102,7 +103,7 @@ let initrdBinEnv = pkgs.buildEnv { name = "initrd-bin-env"; paths = map getBin cfg.initrdBin; - pathsToLink = ["/bin" "/sbin"]; + pathsToLink = ["/bin"]; postBuild = concatStringsSep "\n" (mapAttrsToList (n: v: "ln -sf '${v}' $out/bin/'${n}'") cfg.extraBin); }; @@ -111,8 +112,7 @@ let inherit (config.boot.initrd) compressor compressorArgs prepend; inherit (cfg) strip; - contents = map (path: { object = path; symlink = ""; }) (subtractLists cfg.suppressedStorePaths cfg.storePaths) - ++ mapAttrsToList (_: v: { object = v.source; symlink = v.target; }) (filterAttrs (_: v: v.enable) cfg.contents); + contents = lib.filter ({ source, ... }: !lib.elem source cfg.suppressedStorePaths) cfg.storePaths; }; in { @@ -160,7 +160,7 @@ in { description = "Set of files that have to be linked into the initrd"; example = literalExpression '' { - "/etc/hostname".text = "mymachine"; + "/etc/machine-id".source = /etc/machine-id; } ''; default = {}; @@ -171,7 +171,7 @@ in { description = '' Store paths to copy into the initrd as well. ''; - type = with types; listOf (oneOf [ singleLineStr package ]); + type = utils.systemdUtils.types.initrdStorePath; default = []; }; @@ -344,7 +344,8 @@ in { }; enableTpm2 = mkOption { - default = true; + default = cfg.package.withTpm2Tss; + defaultText = "boot.initrd.systemd.package.withTpm2Tss"; type = types.bool; description = '' Whether to enable TPM2 support in the initrd. @@ -407,7 +408,7 @@ in { fsck = "${cfg.package.util-linux}/bin/fsck"; }; - managerEnvironment.PATH = "/bin:/sbin"; + managerEnvironment.PATH = "/bin"; contents = { "/tmp/.keep".text = "systemd requires the /tmp mount point in the initrd cpio archive"; @@ -416,7 +417,7 @@ in { "/etc/systemd/system.conf".text = '' [Manager] - DefaultEnvironment=PATH=/bin:/sbin + DefaultEnvironment=PATH=/bin ${cfg.extraConfig} ManagerEnvironment=${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "${n}=${lib.escapeShellArg v}") cfg.managerEnvironment)} ''; @@ -431,9 +432,9 @@ in { "/etc/shadow".text = "root:${if isBool cfg.emergencyAccess then optionalString (!cfg.emergencyAccess) "*" else cfg.emergencyAccess}:::::::"; "/bin".source = "${initrdBinEnv}/bin"; - "/sbin".source = "${initrdBinEnv}/sbin"; + "/sbin".source = "${initrdBinEnv}/bin"; - "/etc/sysctl.d/nixos.conf".text = "kernel.modprobe = /sbin/modprobe"; + "/etc/sysctl.d/nixos.conf".text = "kernel.modprobe = /bin/modprobe"; "/etc/modprobe.d/systemd.conf".source = "${cfg.package}/lib/modprobe.d/systemd.conf"; "/etc/modprobe.d/ubuntu.conf".source = pkgs.runCommand "initrd-kmod-blacklist-ubuntu" { } '' ${pkgs.buildPackages.perl}/bin/perl -0pe 's/## file: iwlwifi.conf(.+?)##/##/s;' $src > $out @@ -443,6 +444,9 @@ in { "/etc/os-release".source = config.boot.initrd.osRelease; "/etc/initrd-release".source = config.boot.initrd.osRelease; + # For systemd-journald's _HOSTNAME field; needs to be set early, cannot be backfilled. + "/etc/hostname".text = config.networking.hostName; + } // optionalAttrs (config.environment.etc ? "modprobe.d/nixos.conf") { "/etc/modprobe.d/nixos.conf".source = config.environment.etc."modprobe.d/nixos.conf".source; }; @@ -460,6 +464,7 @@ in { "${cfg.package}/lib/systemd/systemd-sulogin-shell" "${cfg.package}/lib/systemd/systemd-sysctl" "${cfg.package}/lib/systemd/systemd-bsod" + "${cfg.package}/lib/systemd/systemd-sysroot-fstab-check" # generators "${cfg.package}/lib/systemd/system-generators/systemd-debug-generator" @@ -486,7 +491,8 @@ in { # fido2 support "${cfg.package}/lib/cryptsetup/libcryptsetup-token-systemd-fido2.so" "${pkgs.libfido2}/lib/libfido2.so.1" - ] ++ jobScripts; + ] ++ jobScripts + ++ map (c: builtins.removeAttrs c ["text"]) (builtins.attrValues cfg.contents); targets.initrd.aliases = ["default.target"]; units = diff --git a/nixos/modules/system/boot/systemd/journald.nix b/nixos/modules/system/boot/systemd/journald.nix index f9f05d2b08f41..180a5cf6c396b 100644 --- a/nixos/modules/system/boot/systemd/journald.nix +++ b/nixos/modules/system/boot/systemd/journald.nix @@ -72,7 +72,7 @@ in { type = types.lines; example = "Storage=volatile"; description = '' - Extra config options for systemd-journald. See man journald.conf + Extra config options for systemd-journald. See {manpage}`journald.conf(5)` for available options. ''; }; @@ -96,6 +96,7 @@ in { "systemd-journald@.service" "systemd-journal-flush.service" "systemd-journal-catalog-update.service" + "systemd-journald-sync@.service" ] ++ (optional (!config.boot.isContainer) "systemd-journald-audit.socket") ++ [ "systemd-journald-dev-log.socket" "syslog.socket" diff --git a/nixos/modules/system/boot/systemd/nspawn.nix b/nixos/modules/system/boot/systemd/nspawn.nix index 11fbb88838e10..e9bf82c462a95 100644 --- a/nixos/modules/system/boot/systemd/nspawn.nix +++ b/nixos/modules/system/boot/systemd/nspawn.nix @@ -127,6 +127,9 @@ in { }) { systemd.targets.multi-user.wants = [ "machines.target" ]; + systemd.services."systemd-nspawn@".environment = { + SYSTEMD_NSPAWN_UNIFIED_HIERARCHY = mkDefault "1"; + }; } ]; } diff --git a/nixos/modules/system/boot/systemd/shutdown.nix b/nixos/modules/system/boot/systemd/shutdown.nix index 5c2525a57b4be..48477954e20c7 100644 --- a/nixos/modules/system/boot/systemd/shutdown.nix +++ b/nixos/modules/system/boot/systemd/shutdown.nix @@ -2,10 +2,7 @@ cfg = config.systemd.shutdownRamfs; - ramfsContents = let - storePaths = map (p: "${p}\n") cfg.storePaths; - contents = lib.mapAttrsToList (_: v: "${v.source}\n${v.target}") (lib.filterAttrs (_: v: v.enable) cfg.contents); - in pkgs.writeText "shutdown-ramfs-contents" (lib.concatStringsSep "\n" (storePaths ++ contents)); + ramfsContents = pkgs.writeText "shutdown-ramfs-contents.json" (builtins.toJSON cfg.storePaths); in { options.systemd.shutdownRamfs = { @@ -24,7 +21,7 @@ in { description = '' Store paths to copy into the shutdown ramfs as well. ''; - type = lib.types.listOf lib.types.singleLineStr; + type = utils.systemdUtils.types.initrdStorePath; default = []; }; }; @@ -35,7 +32,8 @@ in { "/etc/initrd-release".source = config.environment.etc.os-release.source; "/etc/os-release".source = config.environment.etc.os-release.source; }; - systemd.shutdownRamfs.storePaths = [pkgs.runtimeShell "${pkgs.coreutils}/bin"]; + systemd.shutdownRamfs.storePaths = [pkgs.runtimeShell "${pkgs.coreutils}/bin"] + ++ map (c: builtins.removeAttrs c ["text"]) (builtins.attrValues cfg.contents); systemd.mounts = [{ what = "tmpfs"; diff --git a/nixos/modules/system/boot/systemd/sysusers.nix b/nixos/modules/system/boot/systemd/sysusers.nix index 476251e140456..8d401436daa17 100644 --- a/nixos/modules/system/boot/systemd/sysusers.nix +++ b/nixos/modules/system/boot/systemd/sysusers.nix @@ -5,6 +5,8 @@ let cfg = config.systemd.sysusers; userCfg = config.users; + systemUsers = lib.filterAttrs (_username: opts: !opts.isNormalUser) userCfg.users; + sysusersConfig = pkgs.writeTextDir "00-nixos.conf" '' # Type Name ID GECOS Home directory Shell @@ -16,7 +18,7 @@ let in ''u ${username} ${uid}:${opts.group} "${opts.description}" ${opts.home} ${utils.toShellPath opts.shell}'' ) - userCfg.users) + systemUsers) } # Groups @@ -30,32 +32,12 @@ let } ''; - staticSysusersCredentials = pkgs.runCommand "static-sysusers-credentials" { } '' - mkdir $out; cd $out - ${lib.concatLines ( - (lib.mapAttrsToList - (username: opts: "echo -n '${opts.initialHashedPassword}' > 'passwd.hashed-password.${username}'") - (lib.filterAttrs (_username: opts: opts.initialHashedPassword != null) userCfg.users)) - ++ - (lib.mapAttrsToList - (username: opts: "echo -n '${opts.initialPassword}' > 'passwd.plaintext-password.${username}'") - (lib.filterAttrs (_username: opts: opts.initialPassword != null) userCfg.users)) - ++ - (lib.mapAttrsToList - (username: opts: "cat '${opts.hashedPasswordFile}' > 'passwd.hashed-password.${username}'") - (lib.filterAttrs (_username: opts: opts.hashedPasswordFile != null) userCfg.users)) - ) - } - ''; - - staticSysusers = pkgs.runCommand "static-sysusers" - { - nativeBuildInputs = [ pkgs.systemd ]; - } '' - mkdir $out - export CREDENTIALS_DIRECTORY=${staticSysusersCredentials} - systemd-sysusers --root $out ${sysusersConfig}/00-nixos.conf - ''; + immutableEtc = config.system.etc.overlay.enable && !config.system.etc.overlay.mutable; + # The location of the password files when using an immutable /etc. + immutablePasswordFilesLocation = "/var/lib/nixos/etc"; + passwordFilesLocation = if immutableEtc then immutablePasswordFilesLocation else "/etc"; + # The filenames created by systemd-sysusers. + passwordFiles = [ "passwd" "group" "shadow" "gshadow" ]; in @@ -90,95 +72,114 @@ in assertion = config.users.mutableUsers -> config.system.etc.overlay.enable; message = "config.users.mutableUsers requires config.system.etc.overlay.enable."; } - ]; - - systemd = lib.mkMerge [ - ({ - - # Create home directories, do not create /var/empty even if that's a user's - # home. - tmpfiles.settings.home-directories = lib.mapAttrs' - (username: opts: lib.nameValuePair opts.home { - d = { - mode = opts.homeMode; - user = username; - group = opts.group; - }; - }) - (lib.filterAttrs (_username: opts: opts.home != "/var/empty") userCfg.users); - - # Create uid/gid marker files for those without an explicit id - tmpfiles.settings.nixos-uid = lib.mapAttrs' - (username: opts: lib.nameValuePair "/var/lib/nixos/uid/${username}" { - f = { - user = username; - }; - }) - (lib.filterAttrs (_username: opts: opts.uid == null) userCfg.users); - - tmpfiles.settings.nixos-gid = lib.mapAttrs' - (groupname: opts: lib.nameValuePair "/var/lib/nixos/gid/${groupname}" { - f = { - group = groupname; - }; - }) - (lib.filterAttrs (_groupname: opts: opts.gid == null) userCfg.groups); + ] ++ (lib.mapAttrsToList + (_username: opts: { + assertion = !opts.isNormalUser; + message = "systemd-sysusers doesn't create normal users. You can currently only use it to create system users."; }) + userCfg.users) + ++ lib.mapAttrsToList + (username: opts: { + assertion = (opts.password == opts.initialPassword || opts.password == null) && + (opts.hashedPassword == opts.initialHashedPassword || opts.hashedPassword == null); + message = "${username} uses password or hashedPassword. systemd-sysupdate only supports initial passwords. It'll never update your passwords."; + }) + systemUsers; + + systemd = { + + # Create home directories, do not create /var/empty even if that's a user's + # home. + tmpfiles.settings.home-directories = lib.mapAttrs' + (username: opts: lib.nameValuePair opts.home { + d = { + mode = opts.homeMode; + user = username; + group = opts.group; + }; + }) + (lib.filterAttrs (_username: opts: opts.home != "/var/empty") systemUsers); + + # Create uid/gid marker files for those without an explicit id + tmpfiles.settings.nixos-uid = lib.mapAttrs' + (username: opts: lib.nameValuePair "/var/lib/nixos/uid/${username}" { + f = { + user = username; + }; + }) + (lib.filterAttrs (_username: opts: opts.uid == null) systemUsers); - (lib.mkIf config.users.mutableUsers { - additionalUpstreamSystemUnits = [ - "systemd-sysusers.service" - ]; - - services.systemd-sysusers = { - # Enable switch-to-configuration to restart the service. - unitConfig.ConditionNeedsUpdate = [ "" ]; - requiredBy = [ "sysinit-reactivation.target" ]; - before = [ "sysinit-reactivation.target" ]; - restartTriggers = [ "${config.environment.etc."sysusers.d".source}" ]; - - serviceConfig = { - LoadCredential = lib.mapAttrsToList - (username: opts: "passwd.hashed-password.${username}:${opts.hashedPasswordFile}") - (lib.filterAttrs (_username: opts: opts.hashedPasswordFile != null) userCfg.users); - SetCredential = (lib.mapAttrsToList - (username: opts: "passwd.hashed-password.${username}:${opts.initialHashedPassword}") - (lib.filterAttrs (_username: opts: opts.initialHashedPassword != null) userCfg.users)) - ++ - (lib.mapAttrsToList - (username: opts: "passwd.plaintext-password.${username}:${opts.initialPassword}") - (lib.filterAttrs (_username: opts: opts.initialPassword != null) userCfg.users)) - ; + tmpfiles.settings.nixos-gid = lib.mapAttrs' + (groupname: opts: lib.nameValuePair "/var/lib/nixos/gid/${groupname}" { + f = { + group = groupname; }; + }) + (lib.filterAttrs (_groupname: opts: opts.gid == null) userCfg.groups); + + additionalUpstreamSystemUnits = [ + "systemd-sysusers.service" + ]; + + services.systemd-sysusers = { + # Enable switch-to-configuration to restart the service. + unitConfig.ConditionNeedsUpdate = [ "" ]; + requiredBy = [ "sysinit-reactivation.target" ]; + before = [ "sysinit-reactivation.target" ]; + restartTriggers = [ "${config.environment.etc."sysusers.d".source}" ]; + + serviceConfig = { + # When we have an immutable /etc we cannot write the files directly + # to /etc so we write it to a different directory and symlink them + # into /etc. + # + # We need to explicitly list the config file, otherwise + # systemd-sysusers cannot find it when we also pass another flag. + ExecStart = lib.mkIf immutableEtc + [ "" "${config.systemd.package}/bin/systemd-sysusers --root ${builtins.dirOf immutablePasswordFilesLocation} /etc/sysusers.d/00-nixos.conf" ]; + + # Make the source files writable before executing sysusers. + ExecStartPre = lib.mkIf (!userCfg.mutableUsers) + (lib.map + (file: "-${pkgs.util-linux}/bin/umount ${passwordFilesLocation}/${file}") + passwordFiles); + # Make the source files read-only after sysusers has finished. + ExecStartPost = lib.mkIf (!userCfg.mutableUsers) + (lib.map + (file: "${pkgs.util-linux}/bin/mount --bind -o ro ${passwordFilesLocation}/${file} ${passwordFilesLocation}/${file}") + passwordFiles); + + LoadCredential = lib.mapAttrsToList + (username: opts: "passwd.hashed-password.${username}:${opts.hashedPasswordFile}") + (lib.filterAttrs (_username: opts: opts.hashedPasswordFile != null) systemUsers); + SetCredential = (lib.mapAttrsToList + (username: opts: "passwd.hashed-password.${username}:${opts.initialHashedPassword}") + (lib.filterAttrs (_username: opts: opts.initialHashedPassword != null) systemUsers)) + ++ + (lib.mapAttrsToList + (username: opts: "passwd.plaintext-password.${username}:${opts.initialPassword}") + (lib.filterAttrs (_username: opts: opts.initialPassword != null) systemUsers)) + ; }; - }) - ]; + }; - environment.etc = lib.mkMerge [ - (lib.mkIf (!userCfg.mutableUsers) { - "passwd" = { - source = "${staticSysusers}/etc/passwd"; - mode = "0644"; - }; - "group" = { - source = "${staticSysusers}/etc/group"; - mode = "0644"; - }; - "shadow" = { - source = "${staticSysusers}/etc/shadow"; - mode = "0000"; - }; - "gshadow" = { - source = "${staticSysusers}/etc/gshadow"; - mode = "0000"; - }; - }) + }; - (lib.mkIf userCfg.mutableUsers { + environment.etc = lib.mkMerge [ + ({ "sysusers.d".source = sysusersConfig; }) - ]; + # Statically create the symlinks to immutablePasswordFilesLocation when + # using an immutable /etc because we will not be able to do it at + # runtime! + (lib.mkIf immutableEtc (lib.listToAttrs (lib.map + (file: lib.nameValuePair file { + source = "${immutablePasswordFilesLocation}/${file}"; + mode = "direct-symlink"; + }) + passwordFiles))) + ]; }; meta.maintainers = with lib.maintainers; [ nikstur ]; diff --git a/nixos/modules/system/boot/systemd/tmpfiles.nix b/nixos/modules/system/boot/systemd/tmpfiles.nix index ded13728017d1..af37fb07d29bc 100644 --- a/nixos/modules/system/boot/systemd/tmpfiles.nix +++ b/nixos/modules/system/boot/systemd/tmpfiles.nix @@ -200,6 +200,10 @@ in rm -f $out/${removePrefix "tmpfiles.d/" name} '') config.system.build.etc.passthru.targets; }) + "/*"; + "mtab" = { + mode = "direct-symlink"; + source = "/proc/mounts"; + }; }; systemd.tmpfiles.packages = [ @@ -244,13 +248,11 @@ in "L+ /nix/var/nix/gcroots/booted-system 0755 root root - /run/booted-system" "d /run/lock 0755 root root - -" "d /var/db 0755 root root - -" - "L /etc/mtab - - - - ../proc/mounts" "L /var/lock - - - - ../run/lock" # Boot-time cleanup "R! /etc/group.lock - - - - -" "R! /etc/passwd.lock - - - - -" "R! /etc/shadow.lock - - - - -" - "R! /etc/mtab* - - - - -" "R! /nix/var/nix/gcroots/tmp - - - - -" "R! /nix/var/nix/temproots - - - - -" ]; |