11 cfg = config.services.pdns-recursor;
13 oneOrMore = type: with types; either type (listOf type);
22 configType = with types; attrsOf (nullOr (oneOrMore valueType));
24 toBool = val: if val then "yes" else "no";
30 else if int.check val then
32 else if path.check val then
34 else if bool.check val then
36 else if builtins.isList val then
37 (concatMapStringsSep "," serialize val)
41 configDir = pkgs.writeTextDir "recursor.conf" (
42 concatStringsSep "\n" (flip mapAttrsToList cfg.settings (name: val: "${name}=${serialize val}"))
45 mkDefaultAttrs = mapAttrs (n: v: mkDefault v);
49 options.services.pdns-recursor = {
50 enable = mkEnableOption "PowerDNS Recursor, a recursive DNS server";
52 dns.address = mkOption {
53 type = oneOrMore types.str;
59 IP addresses Recursor DNS server will bind to.
67 Port number Recursor DNS server will bind to.
71 dns.allowFrom = mkOption {
72 type = types.listOf types.str;
89 IP address ranges of clients allowed to make DNS queries.
93 api.address = mkOption {
97 IP address Recursor REST API server will bind to.
101 api.port = mkOption {
105 Port number Recursor REST API server will bind to.
109 api.allowFrom = mkOption {
110 type = types.listOf types.str;
120 IP address ranges of clients allowed to make API requests.
124 exportHosts = mkOption {
128 Whether to export names and IP addresses defined in /etc/hosts.
132 forwardZones = mkOption {
136 DNS zones to be forwarded to other authoritative servers.
140 forwardZonesRecurse = mkOption {
147 DNS zones to be forwarded to other recursive servers.
151 dnssecValidation = mkOption {
154 "process-no-validate"
159 default = "validate";
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.
166 serveRFC1918 = mkOption {
170 Whether to directly resolve the RFC1918 reverse-mapping domains:
172 `168.192.in-addr.arpa`,
173 `16-31.172.in-addr.arpa`
174 This saves load on the AS112 servers.
178 settings = mkOption {
181 example = literalExpression ''
184 log-common-errors = true;
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.
196 luaConfig = mkOption {
200 The content Lua configuration file for PowerDNS Recursor. See
201 <https://doc.powerdns.com/recursor/lua-config/index.html>.
206 config = mkIf cfg.enable {
208 environment.etc."pdns-recursor".source = configDir;
210 services.pdns-recursor.settings = mkDefaultAttrs {
211 local-address = cfg.dns.address;
212 local-port = cfg.dns.port;
213 allow-from = cfg.dns.allowFrom;
215 webserver-address = cfg.api.address;
216 webserver-port = cfg.api.port;
217 webserver-allow-from = cfg.api.allowFrom;
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;
228 log-timestamp = false;
229 disable-syslog = true;
232 systemd.packages = [ pkgs.pdns-recursor ];
234 systemd.services.pdns-recursor = {
235 wantedBy = [ "multi-user.target" ];
240 "${pkgs.pdns-recursor}/bin/pdns_recursor --config-dir=${configDir}"
245 users.users.pdns-recursor = {
247 group = "pdns-recursor";
248 description = "PowerDNS Recursor daemon user";
251 users.groups.pdns-recursor = { };
256 (mkRemovedOptionModule [
260 ] "To change extra Recursor settings use services.pdns-recursor.settings instead.")
263 meta.maintainers = with lib.maintainers; [ rnhmjoj ];