at 24.11-pre 3.9 kB view raw
1{ config, lib, ... }: 2 3with lib; 4 5{ 6 7 options = { 8 9 services.timesyncd = { 10 enable = mkOption { 11 default = !config.boot.isContainer; 12 defaultText = literalExpression "!config.boot.isContainer"; 13 type = types.bool; 14 description = '' 15 Enables the systemd NTP client daemon. 16 ''; 17 }; 18 servers = mkOption { 19 default = config.networking.timeServers; 20 defaultText = literalExpression "config.networking.timeServers"; 21 type = types.listOf types.str; 22 description = '' 23 The set of NTP servers from which to synchronise. 24 Note if this is set to an empty list, the defaults systemd itself is 25 compiled with ({0..4}.nixos.pool.ntp.org) apply, 26 In case you want to disable timesyncd altogether, use the `enable` option. 27 ''; 28 }; 29 extraConfig = mkOption { 30 default = ""; 31 type = types.lines; 32 example = '' 33 PollIntervalMaxSec=180 34 ''; 35 description = '' 36 Extra config options for systemd-timesyncd. See 37 [ 38 timesyncd.conf(5)](https://www.freedesktop.org/software/systemd/man/timesyncd.conf.html) for available options. 39 ''; 40 }; 41 }; 42 }; 43 44 config = mkIf config.services.timesyncd.enable { 45 46 systemd.additionalUpstreamSystemUnits = [ "systemd-timesyncd.service" ]; 47 48 systemd.services.systemd-timesyncd = { 49 wantedBy = [ "sysinit.target" ]; 50 aliases = [ "dbus-org.freedesktop.timesync1.service" ]; 51 restartTriggers = [ config.environment.etc."systemd/timesyncd.conf".source ]; 52 # systemd-timesyncd disables DNSSEC validation in the nss-resolve module by setting SYSTEMD_NSS_RESOLVE_VALIDATE to 0 in the unit file. 53 # This is required in order to solve the chicken-and-egg problem when DNSSEC validation needs the correct time to work, but to set the 54 # correct time, we need to connect to an NTP server, which usually requires resolving its hostname. 55 # In order for nss-resolve to be able to read this environment variable we patch systemd-timesyncd to disable NSCD and use NSS modules directly. 56 # This means that systemd-timesyncd needs to have NSS modules path in LD_LIBRARY_PATH. When systemd-resolved is disabled we still need to set 57 # NSS module path so that systemd-timesyncd keeps using other NSS modules that are configured in the system. 58 environment.LD_LIBRARY_PATH = config.system.nssModules.path; 59 60 preStart = ( 61 # Ensure that we have some stored time to prevent 62 # systemd-timesyncd to resort back to the fallback time. If 63 # the file doesn't exist we assume that our current system 64 # clock is good enough to provide an initial value. 65 '' 66 if ! [ -f /var/lib/systemd/timesync/clock ]; then 67 test -d /var/lib/systemd/timesync || mkdir -p /var/lib/systemd/timesync 68 touch /var/lib/systemd/timesync/clock 69 fi 70 '' + 71 # workaround an issue of systemd-timesyncd not starting due to upstream systemd reverting their dynamic users changes 72 # - https://github.com/NixOS/nixpkgs/pull/61321#issuecomment-492423742 73 # - https://github.com/systemd/systemd/issues/12131 74 (lib.optionalString (versionOlder config.system.stateVersion "19.09") '' 75 if [ -L /var/lib/systemd/timesync ]; then 76 rm /var/lib/systemd/timesync 77 mv /var/lib/private/systemd/timesync /var/lib/systemd/timesync 78 fi 79 '') 80 ); 81 }; 82 83 environment.etc."systemd/timesyncd.conf".text = '' 84 [Time] 85 NTP=${concatStringsSep " " config.services.timesyncd.servers} 86 ${config.services.timesyncd.extraConfig} 87 ''; 88 89 users.users.systemd-timesync = { 90 uid = config.ids.uids.systemd-timesync; 91 group = "systemd-timesync"; 92 }; 93 users.groups.systemd-timesync.gid = config.ids.gids.systemd-timesync; 94 }; 95}