at 25.11-pre 6.2 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8with lib; 9 10let 11 cfg = config.services.pdns-recursor; 12 13 oneOrMore = type: with types; either type (listOf type); 14 valueType = 15 with types; 16 oneOf [ 17 int 18 str 19 bool 20 path 21 ]; 22 configType = with types; attrsOf (nullOr (oneOrMore valueType)); 23 24 toBool = val: if val then "yes" else "no"; 25 serialize = 26 val: 27 with types; 28 if str.check val then 29 val 30 else if int.check val then 31 toString val 32 else if path.check val then 33 toString val 34 else if bool.check val then 35 toBool val 36 else if builtins.isList val then 37 (concatMapStringsSep "," serialize val) 38 else 39 ""; 40 41 configDir = pkgs.writeTextDir "recursor.conf" ( 42 concatStringsSep "\n" (flip mapAttrsToList cfg.settings (name: val: "${name}=${serialize val}")) 43 ); 44 45 mkDefaultAttrs = mapAttrs (n: v: mkDefault v); 46 47in 48{ 49 options.services.pdns-recursor = { 50 enable = mkEnableOption "PowerDNS Recursor, a recursive DNS server"; 51 52 dns.address = mkOption { 53 type = oneOrMore types.str; 54 default = [ 55 "::" 56 "0.0.0.0" 57 ]; 58 description = '' 59 IP addresses Recursor DNS server will bind to. 60 ''; 61 }; 62 63 dns.port = mkOption { 64 type = types.port; 65 default = 53; 66 description = '' 67 Port number Recursor DNS server will bind to. 68 ''; 69 }; 70 71 dns.allowFrom = mkOption { 72 type = types.listOf types.str; 73 default = [ 74 "127.0.0.0/8" 75 "10.0.0.0/8" 76 "100.64.0.0/10" 77 "169.254.0.0/16" 78 "192.168.0.0/16" 79 "172.16.0.0/12" 80 "::1/128" 81 "fc00::/7" 82 "fe80::/10" 83 ]; 84 example = [ 85 "0.0.0.0/0" 86 "::/0" 87 ]; 88 description = '' 89 IP address ranges of clients allowed to make DNS queries. 90 ''; 91 }; 92 93 api.address = mkOption { 94 type = types.str; 95 default = "0.0.0.0"; 96 description = '' 97 IP address Recursor REST API server will bind to. 98 ''; 99 }; 100 101 api.port = mkOption { 102 type = types.port; 103 default = 8082; 104 description = '' 105 Port number Recursor REST API server will bind to. 106 ''; 107 }; 108 109 api.allowFrom = mkOption { 110 type = types.listOf types.str; 111 default = [ 112 "127.0.0.1" 113 "::1" 114 ]; 115 example = [ 116 "0.0.0.0/0" 117 "::/0" 118 ]; 119 description = '' 120 IP address ranges of clients allowed to make API requests. 121 ''; 122 }; 123 124 exportHosts = mkOption { 125 type = types.bool; 126 default = false; 127 description = '' 128 Whether to export names and IP addresses defined in /etc/hosts. 129 ''; 130 }; 131 132 forwardZones = mkOption { 133 type = types.attrs; 134 default = { }; 135 description = '' 136 DNS zones to be forwarded to other authoritative servers. 137 ''; 138 }; 139 140 forwardZonesRecurse = mkOption { 141 type = types.attrs; 142 example = { 143 eth = "[::1]:5353"; 144 }; 145 default = { }; 146 description = '' 147 DNS zones to be forwarded to other recursive servers. 148 ''; 149 }; 150 151 dnssecValidation = mkOption { 152 type = types.enum [ 153 "off" 154 "process-no-validate" 155 "process" 156 "log-fail" 157 "validate" 158 ]; 159 default = "validate"; 160 description = '' 161 Controls the level of DNSSEC processing done by the PowerDNS Recursor. 162 See https://doc.powerdns.com/md/recursor/dnssec/ for a detailed explanation. 163 ''; 164 }; 165 166 serveRFC1918 = mkOption { 167 type = types.bool; 168 default = true; 169 description = '' 170 Whether to directly resolve the RFC1918 reverse-mapping domains: 171 `10.in-addr.arpa`, 172 `168.192.in-addr.arpa`, 173 `16-31.172.in-addr.arpa` 174 This saves load on the AS112 servers. 175 ''; 176 }; 177 178 settings = mkOption { 179 type = configType; 180 default = { }; 181 example = literalExpression '' 182 { 183 loglevel = 8; 184 log-common-errors = true; 185 } 186 ''; 187 description = '' 188 PowerDNS Recursor settings. Use this option to configure Recursor 189 settings not exposed in a NixOS option or to bypass one. 190 See the full documentation at 191 <https://doc.powerdns.com/recursor/settings.html> 192 for the available options. 193 ''; 194 }; 195 196 luaConfig = mkOption { 197 type = types.lines; 198 default = ""; 199 description = '' 200 The content Lua configuration file for PowerDNS Recursor. See 201 <https://doc.powerdns.com/recursor/lua-config/index.html>. 202 ''; 203 }; 204 }; 205 206 config = mkIf cfg.enable { 207 208 environment.etc."pdns-recursor".source = configDir; 209 210 services.pdns-recursor.settings = mkDefaultAttrs { 211 local-address = cfg.dns.address; 212 local-port = cfg.dns.port; 213 allow-from = cfg.dns.allowFrom; 214 215 webserver-address = cfg.api.address; 216 webserver-port = cfg.api.port; 217 webserver-allow-from = cfg.api.allowFrom; 218 219 forward-zones = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZones; 220 forward-zones-recurse = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZonesRecurse; 221 export-etc-hosts = cfg.exportHosts; 222 dnssec = cfg.dnssecValidation; 223 serve-rfc1918 = cfg.serveRFC1918; 224 lua-config-file = pkgs.writeText "recursor.lua" cfg.luaConfig; 225 226 daemon = false; 227 write-pid = false; 228 log-timestamp = false; 229 disable-syslog = true; 230 }; 231 232 systemd.packages = [ pkgs.pdns-recursor ]; 233 234 systemd.services.pdns-recursor = { 235 wantedBy = [ "multi-user.target" ]; 236 237 serviceConfig = { 238 ExecStart = [ 239 "" 240 "${pkgs.pdns-recursor}/bin/pdns_recursor --config-dir=${configDir}" 241 ]; 242 }; 243 }; 244 245 users.users.pdns-recursor = { 246 isSystemUser = true; 247 group = "pdns-recursor"; 248 description = "PowerDNS Recursor daemon user"; 249 }; 250 251 users.groups.pdns-recursor = { }; 252 253 }; 254 255 imports = [ 256 (mkRemovedOptionModule [ 257 "services" 258 "pdns-recursor" 259 "extraConfig" 260 ] "To change extra Recursor settings use services.pdns-recursor.settings instead.") 261 ]; 262 263 meta.maintainers = with lib.maintainers; [ rnhmjoj ]; 264 265}