at master 4.5 kB view raw
1{ config, lib, ... }: 2 3with lib; 4 5let 6 cfg = config.services.timesyncd; 7in 8{ 9 10 options = { 11 12 services.timesyncd = with types; { 13 enable = mkOption { 14 default = !config.boot.isContainer; 15 defaultText = literalExpression "!config.boot.isContainer"; 16 type = bool; 17 description = '' 18 Enables the systemd NTP client daemon. 19 ''; 20 }; 21 servers = mkOption { 22 default = null; 23 type = nullOr (listOf str); 24 description = '' 25 The set of NTP servers from which to synchronise. 26 27 Setting this option to an empty list will write `NTP=` to the 28 `timesyncd.conf` file as opposed to setting this option to null which 29 will remove `NTP=` entirely. 30 31 See {manpage}`timesyncd.conf(5)` for details. 32 ''; 33 }; 34 fallbackServers = mkOption { 35 default = config.networking.timeServers; 36 defaultText = literalExpression "config.networking.timeServers"; 37 type = nullOr (listOf str); 38 description = '' 39 The set of fallback NTP servers from which to synchronise. 40 41 Setting this option to an empty list will write `FallbackNTP=` to the 42 `timesyncd.conf` file as opposed to setting this option to null which 43 will remove `FallbackNTP=` entirely. 44 45 See {manpage}`timesyncd.conf(5)` for details. 46 ''; 47 }; 48 extraConfig = mkOption { 49 default = ""; 50 type = lines; 51 example = '' 52 PollIntervalMaxSec=180 53 ''; 54 description = '' 55 Extra config options for systemd-timesyncd. See 56 {manpage}`timesyncd.conf(5)` for available options. 57 ''; 58 }; 59 }; 60 }; 61 62 config = mkIf cfg.enable { 63 64 systemd.additionalUpstreamSystemUnits = [ "systemd-timesyncd.service" ]; 65 66 systemd.services.systemd-timesyncd = { 67 wantedBy = [ "sysinit.target" ]; 68 aliases = [ "dbus-org.freedesktop.timesync1.service" ]; 69 restartTriggers = [ config.environment.etc."systemd/timesyncd.conf".source ]; 70 # systemd-timesyncd disables DNSSEC validation in the nss-resolve module by setting SYSTEMD_NSS_RESOLVE_VALIDATE to 0 in the unit file. 71 # 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 72 # correct time, we need to connect to an NTP server, which usually requires resolving its hostname. 73 # 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. 74 # 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 75 # NSS module path so that systemd-timesyncd keeps using other NSS modules that are configured in the system. 76 environment.LD_LIBRARY_PATH = config.system.nssModules.path; 77 78 preStart = ( 79 # Ensure that we have some stored time to prevent 80 # systemd-timesyncd to resort back to the fallback time. If 81 # the file doesn't exist we assume that our current system 82 # clock is good enough to provide an initial value. 83 '' 84 if ! [ -f /var/lib/systemd/timesync/clock ]; then 85 test -d /var/lib/systemd/timesync || mkdir -p /var/lib/systemd/timesync 86 touch /var/lib/systemd/timesync/clock 87 fi 88 '' 89 + 90 # workaround an issue of systemd-timesyncd not starting due to upstream systemd reverting their dynamic users changes 91 # - https://github.com/NixOS/nixpkgs/pull/61321#issuecomment-492423742 92 # - https://github.com/systemd/systemd/issues/12131 93 (lib.optionalString (versionOlder config.system.stateVersion "19.09") '' 94 if [ -L /var/lib/systemd/timesync ]; then 95 rm /var/lib/systemd/timesync 96 mv /var/lib/private/systemd/timesync /var/lib/systemd/timesync 97 fi 98 '') 99 ); 100 }; 101 102 environment.etc."systemd/timesyncd.conf".text = '' 103 [Time] 104 '' 105 + optionalString (cfg.servers != null) '' 106 NTP=${concatStringsSep " " cfg.servers} 107 '' 108 + optionalString (cfg.fallbackServers != null) '' 109 FallbackNTP=${concatStringsSep " " cfg.fallbackServers} 110 '' 111 + cfg.extraConfig; 112 113 users.users.systemd-timesync = { 114 uid = config.ids.uids.systemd-timesync; 115 group = "systemd-timesync"; 116 }; 117 users.groups.systemd-timesync.gid = config.ids.gids.systemd-timesync; 118 }; 119}