nixos/nscd: start in early boot

Services that have dynamic users require nscd to resolve users
via pam_systemd. Those services might not even create
their own dynamic users itself i.e. iptables.
To make sure nscd is always started when this is happening we move
nscd to sysinit.target and make sure that it is always started before
starting/reloading/restarting any other service.
This commit is contained in:
Jörg Thalheim 2020-12-07 20:59:03 +01:00
parent 330218e69a
commit 1024571d35
No known key found for this signature in database
GPG Key ID: 003F2096411B5F92
2 changed files with 35 additions and 17 deletions

View File

@ -50,10 +50,20 @@ in
systemd.services.nscd =
{ description = "Name Service Cache Daemon";
wantedBy = [ "nss-lookup.target" "nss-user-lookup.target" ];
environment = { LD_LIBRARY_PATH = nssModulesPath; };
# We need system users to be resolveable in late-boot. nscd is the proxy between
# nss-modules in NixOS and thus if you have nss-modules providing system users
# (e.g. when using DynamicUser) then nscd needs to be available before late-boot is ready
# We add a dependency of sysinit.target to nscd to ensure
# these units are started after nscd is fully started.
unitConfig.DefaultDependencies = false;
wantedBy = [ "sysinit.target" ];
before = [ "sysinit.target" "shutdown.target" ];
conflicts = [ "shutdown.target" ];
wants = [ "local-fs.target" ];
after = [ "local-fs.target" ];
restartTriggers = [
config.environment.etc.hosts.source
config.environment.etc."nsswitch.conf".source
@ -66,20 +76,19 @@ in
# privileges after all the NSS modules have read their configuration
# files. So prefix the ExecStart command with "!" to prevent systemd
# from dropping privileges early. See ExecStart in systemd.service(5).
serviceConfig =
{ ExecStart = "!@${nscd}/sbin/nscd nscd";
Type = "forking";
DynamicUser = true;
RuntimeDirectory = "nscd";
PIDFile = "/run/nscd/nscd.pid";
Restart = "always";
ExecReload =
[ "${nscd}/sbin/nscd --invalidate passwd"
"${nscd}/sbin/nscd --invalidate group"
"${nscd}/sbin/nscd --invalidate hosts"
];
};
serviceConfig = {
ExecStart = "!@${nscd}/sbin/nscd nscd";
Type = "forking";
DynamicUser = true;
RuntimeDirectory = "nscd";
PIDFile = "/run/nscd/nscd.pid";
Restart = "always";
ExecReload = [
"${nscd}/sbin/nscd --invalidate passwd"
"${nscd}/sbin/nscd --invalidate group"
"${nscd}/sbin/nscd --invalidate hosts"
];
};
};
};
}

View File

@ -346,10 +346,11 @@ sub filterUnits {
return @res;
}
my $startNscd = delete $unitsToStart{"nscd.service"};
my @unitsToStopFiltered = filterUnits(\%unitsToStop);
my @unitsToStartFiltered = filterUnits(\%unitsToStart);
# Show dry-run actions.
if ($action eq "dry-activate") {
print STDERR "would stop the following units: ", join(", ", @unitsToStopFiltered), "\n"
@ -359,6 +360,7 @@ if ($action eq "dry-activate") {
print STDERR "would restart systemd\n" if $restartSystemd;
print STDERR "would restart the following units: ", join(", ", sort(keys %unitsToRestart)), "\n"
if scalar(keys %unitsToRestart) > 0;
print STDERR "would start nscd\n" if $startNscd;
print STDERR "would start the following units: ", join(", ", @unitsToStartFiltered), "\n"
if scalar @unitsToStartFiltered;
print STDERR "would reload the following units: ", join(", ", sort(keys %unitsToReload)), "\n"
@ -418,6 +420,13 @@ close $listActiveUsers;
print STDERR "setting up tmpfiles\n";
system("@systemd@/bin/systemd-tmpfiles", "--create", "--remove", "--exclude-prefix=/dev") == 0 or $res = 3;
# We need to start nscd before any other service, since they might need
# to resolve users/groups only exposed by nss modules (i.e. DynamicUser via nss_systemd)
if ($startNscd) {
print STDERR "starting nscd\n";
system("@systemd@/bin/systemctl", "start", "nscd.service") == 0 or $res = 4;
}
# Reload units that need it. This includes remounting changed mount
# units.
if (scalar(keys %unitsToReload) > 0) {