at master 4.4 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8with lib; 9 10let 11 12 inherit (pkgs) ntp; 13 14 cfg = config.services.ntp; 15 16 configFile = pkgs.writeText "ntp.conf" '' 17 driftfile /var/lib/ntp/ntp.drift 18 19 restrict default ${toString cfg.restrictDefault} 20 restrict -6 default ${toString cfg.restrictDefault} 21 restrict source ${toString cfg.restrictSource} 22 23 restrict 127.0.0.1 24 restrict -6 ::1 25 26 ${toString (map (server: "server " + server + " iburst\n") cfg.servers)} 27 28 ${cfg.extraConfig} 29 ''; 30 31 ntpFlags = [ 32 "-c" 33 "${configFile}" 34 "-u" 35 "ntp:ntp" 36 ] 37 ++ cfg.extraFlags; 38 39in 40 41{ 42 43 ###### interface 44 45 options = { 46 47 services.ntp = { 48 49 enable = mkOption { 50 type = types.bool; 51 default = false; 52 description = '' 53 Whether to synchronise your machine's time using ntpd, as a peer in 54 the NTP network. 55 56 Disables `systemd.timesyncd` if enabled. 57 ''; 58 }; 59 60 restrictDefault = mkOption { 61 type = types.listOf types.str; 62 description = '' 63 The restriction flags to be set by default. 64 65 The default flags prevent external hosts from using ntpd as a DDoS 66 reflector, setting system time, and querying OS/ntpd version. As 67 recommended in section 6.5.1.1.3, answer "No" of 68 https://support.ntp.org/Support/AccessRestrictions 69 ''; 70 default = [ 71 "limited" 72 "kod" 73 "nomodify" 74 "notrap" 75 "noquery" 76 "nopeer" 77 ]; 78 }; 79 80 restrictSource = mkOption { 81 type = types.listOf types.str; 82 description = '' 83 The restriction flags to be set on source. 84 85 The default flags allow peers to be added by ntpd from configured 86 pool(s), but not by other means. 87 ''; 88 default = [ 89 "limited" 90 "kod" 91 "nomodify" 92 "notrap" 93 "noquery" 94 ]; 95 }; 96 97 servers = mkOption { 98 default = config.networking.timeServers; 99 defaultText = literalExpression "config.networking.timeServers"; 100 type = types.listOf types.str; 101 description = '' 102 The set of NTP servers from which to synchronise. 103 ''; 104 }; 105 106 extraConfig = mkOption { 107 type = types.lines; 108 default = ""; 109 example = '' 110 fudge 127.127.1.0 stratum 10 111 ''; 112 description = '' 113 Additional text appended to {file}`ntp.conf`. 114 ''; 115 }; 116 117 extraFlags = mkOption { 118 type = types.listOf types.str; 119 description = "Extra flags passed to the ntpd command."; 120 example = literalExpression ''[ "--interface=eth0" ]''; 121 default = [ ]; 122 }; 123 124 }; 125 126 }; 127 128 ###### implementation 129 130 meta.maintainers = with lib.maintainers; [ thoughtpolice ]; 131 132 config = mkIf config.services.ntp.enable { 133 # Make tools such as ntpq available in the system path. 134 environment.systemPackages = [ pkgs.ntp ]; 135 services.timesyncd.enable = mkForce false; 136 137 systemd.services.systemd-timedated.environment = { 138 SYSTEMD_TIMEDATED_NTP_SERVICES = "ntpd.service"; 139 }; 140 141 users.users.ntp = { 142 isSystemUser = true; 143 group = "ntp"; 144 description = "NTP daemon user"; 145 home = "/var/lib/ntp"; 146 createHome = true; 147 }; 148 users.groups.ntp = { }; 149 150 systemd.services.ntpd = { 151 description = "NTP Daemon"; 152 153 wantedBy = [ "multi-user.target" ]; 154 wants = [ "time-sync.target" ]; 155 before = [ "time-sync.target" ]; 156 157 serviceConfig = { 158 ExecStart = "@${ntp}/bin/ntpd ntpd -g ${builtins.toString ntpFlags}"; 159 Type = "forking"; 160 161 # Hardening options 162 PrivateDevices = true; 163 PrivateIPC = true; 164 PrivateTmp = true; 165 ProtectClock = false; 166 ProtectHome = true; 167 168 ProtectHostname = true; 169 ProtectKernelLogs = true; 170 ProtectKernelModules = true; 171 ProtectKernelTunables = true; 172 ProtectSystem = true; 173 174 RestrictNamespaces = true; 175 RestrictRealtime = true; 176 LockPersonality = true; 177 MemoryDenyWriteExecute = true; 178 AmbientCapabilities = [ 179 "CAP_SYS_TIME" 180 ]; 181 182 ProtectControlGroups = true; 183 ProtectProc = "invisible"; 184 ProcSubset = "pid"; 185 RestrictSUIDSGID = true; 186 }; 187 }; 188 189 }; 190 191}