at master 5.1 kB view raw
1{ 2 lib, 3 config, 4 pkgs, 5 ... 6}: 7 8let 9 cfg = config.services.ntpd-rs; 10 format = pkgs.formats.toml { }; 11 configFile = format.generate "ntpd-rs.toml" cfg.settings; 12 13 validateConfig = 14 file: 15 pkgs.runCommand "validate-ntpd-rs.toml" 16 { 17 nativeBuildInputs = [ cfg.package ]; 18 } 19 '' 20 ntp-ctl validate -c ${file} 21 ln -s "${file}" "$out" 22 ''; 23in 24{ 25 options.services.ntpd-rs = { 26 enable = lib.mkEnableOption "Network Time Service (ntpd-rs)"; 27 metrics.enable = lib.mkEnableOption "ntpd-rs Prometheus Metrics Exporter"; 28 29 package = lib.mkPackageOption pkgs "ntpd-rs" { }; 30 31 useNetworkingTimeServers = lib.mkOption { 32 type = lib.types.bool; 33 default = true; 34 description = '' 35 Use source time servers from {var}`networking.timeServers` in config. 36 ''; 37 }; 38 39 settings = lib.mkOption { 40 type = lib.types.submodule { 41 freeformType = format.type; 42 }; 43 default = { }; 44 description = '' 45 Settings to write to {file}`ntp.toml` 46 47 See <https://docs.ntpd-rs.pendulum-project.org/man/ntp.toml.5> 48 for more information about available options. 49 ''; 50 }; 51 }; 52 53 config = lib.mkIf cfg.enable { 54 assertions = [ 55 { 56 assertion = !config.services.timesyncd.enable; 57 message = '' 58 `ntpd-rs` is not compatible with `services.timesyncd`. Please disable one of them. 59 ''; 60 } 61 ]; 62 63 environment.systemPackages = [ cfg.package ]; 64 systemd.packages = [ cfg.package ]; 65 66 services.timesyncd.enable = false; 67 systemd.services.systemd-timedated.environment = { 68 SYSTEMD_TIMEDATED_NTP_SERVICES = "ntpd-rs.service"; 69 }; 70 71 services.ntpd-rs.settings = { 72 observability = { 73 observation-path = lib.mkDefault "/var/run/ntpd-rs/observe"; 74 }; 75 source = lib.mkIf cfg.useNetworkingTimeServers ( 76 map (ts: { 77 mode = if lib.strings.hasInfix "pool" ts then "pool" else "server"; 78 address = ts; 79 }) config.networking.timeServers 80 ); 81 }; 82 83 systemd.services.ntpd-rs = { 84 wantedBy = [ "multi-user.target" ]; 85 serviceConfig = { 86 User = ""; 87 Group = ""; 88 DynamicUser = true; 89 ExecStart = [ 90 "" 91 "${lib.makeBinPath [ cfg.package ]}/ntp-daemon --config=${validateConfig configFile}" 92 ]; 93 94 CapabilityBoundingSet = [ 95 "CAP_SYS_TIME" 96 "CAP_NET_BIND_SERVICE" 97 ]; 98 AmbientCapabilities = [ 99 "CAP_SYS_TIME" 100 "CAP_NET_BIND_SERVICE" 101 ]; 102 LimitCORE = 0; 103 LimitNOFILE = 65535; 104 LockPersonality = true; 105 MemorySwapMax = 0; 106 MemoryZSwapMax = 0; 107 PrivateTmp = true; 108 ProcSubset = "pid"; 109 ProtectControlGroups = true; 110 ProtectHome = true; 111 ProtectHostname = true; 112 ProtectKernelLogs = true; 113 ProtectKernelModules = true; 114 ProtectKernelTunables = true; 115 ProtectProc = "invisible"; 116 ProtectSystem = "strict"; 117 Restart = "on-failure"; 118 RestartSec = "10s"; 119 RestrictAddressFamilies = [ 120 "AF_INET" 121 "AF_INET6" 122 "AF_UNIX" 123 "AF_NETLINK" 124 ]; 125 RestrictNamespaces = true; 126 RestrictRealtime = true; 127 SystemCallArchitectures = "native"; 128 SystemCallFilter = [ 129 "@system-service" 130 "@resources" 131 "@network-io" 132 "@clock" 133 ]; 134 NoNewPrivileges = true; 135 UMask = "0077"; 136 }; 137 }; 138 139 systemd.services.ntpd-rs-metrics = lib.mkIf cfg.metrics.enable { 140 wantedBy = [ "multi-user.target" ]; 141 serviceConfig = { 142 User = ""; 143 Group = ""; 144 DynamicUser = true; 145 ExecStart = [ 146 "" 147 "${lib.makeBinPath [ cfg.package ]}/ntp-metrics-exporter --config=${validateConfig configFile}" 148 ]; 149 150 CapabilityBoundingSet = [ ]; 151 LimitCORE = 0; 152 LimitNOFILE = 65535; 153 LockPersonality = true; 154 MemorySwapMax = 0; 155 MemoryZSwapMax = 0; 156 PrivateTmp = true; 157 ProcSubset = "pid"; 158 ProtectClock = true; 159 ProtectControlGroups = true; 160 ProtectHome = true; 161 ProtectHostname = true; 162 ProtectKernelLogs = true; 163 ProtectKernelModules = true; 164 ProtectKernelTunables = true; 165 ProtectProc = "invisible"; 166 ProtectSystem = "strict"; 167 PrivateDevices = true; 168 RestrictSUIDSGID = true; 169 RemoveIPC = true; 170 RestrictAddressFamilies = [ 171 "AF_INET" 172 "AF_INET6" 173 "AF_UNIX" 174 ]; 175 RestrictNamespaces = true; 176 RestrictRealtime = true; 177 SystemCallArchitectures = "native"; 178 SystemCallFilter = [ 179 "@system-service" 180 "@network-io" 181 "~@privileged" 182 "~@resources" 183 "~@mount" 184 ]; 185 NoNewPrivileges = true; 186 UMask = "0077"; 187 }; 188 }; 189 }; 190 191 meta.maintainers = with lib.maintainers; [ fpletz ]; 192}