diff --git a/nixos/doc/manual/release-notes/rl-1909.xml b/nixos/doc/manual/release-notes/rl-1909.xml
index 85ad34f6a66..6493bb99596 100644
--- a/nixos/doc/manual/release-notes/rl-1909.xml
+++ b/nixos/doc/manual/release-notes/rl-1909.xml
@@ -284,6 +284,13 @@
Squid 3 has been removed and the derivation now refers to Squid 4.
+
+
+ The option has been replaced by
+ . The new option allows setting extra
+ configuration while being better type-checked and mergeable.
+
+
diff --git a/nixos/modules/services/networking/pdns-recursor.nix b/nixos/modules/services/networking/pdns-recursor.nix
index d07deb9dcc6..ec69cc838da 100644
--- a/nixos/modules/services/networking/pdns-recursor.nix
+++ b/nixos/modules/services/networking/pdns-recursor.nix
@@ -6,25 +6,27 @@ let
dataDir = "/var/lib/pdns-recursor";
username = "pdns-recursor";
- cfg = config.services.pdns-recursor;
- zones = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZones;
+ cfg = config.services.pdns-recursor;
- configFile = pkgs.writeText "recursor.conf" ''
- local-address=${cfg.dns.address}
- local-port=${toString cfg.dns.port}
- allow-from=${concatStringsSep "," cfg.dns.allowFrom}
+ oneOrMore = type: with types; either type (listOf type);
+ valueType = with types; oneOf [ int str bool path ];
+ configType = with types; attrsOf (nullOr (oneOrMore valueType));
- webserver-address=${cfg.api.address}
- webserver-port=${toString cfg.api.port}
- webserver-allow-from=${concatStringsSep "," cfg.api.allowFrom}
+ toBool = val: if val then "yes" else "no";
+ serialize = val: with types;
+ if str.check val then val
+ else if int.check val then toString val
+ else if path.check val then toString val
+ else if bool.check val then toBool val
+ else if builtins.isList val then (concatMapStringsSep "," serialize val)
+ else "";
- forward-zones=${concatStringsSep "," zones}
- export-etc-hosts=${if cfg.exportHosts then "yes" else "no"}
- dnssec=${cfg.dnssecValidation}
- serve-rfc1918=${if cfg.serveRFC1918 then "yes" else "no"}
+ configFile = pkgs.writeText "recursor.conf"
+ (concatStringsSep "\n"
+ (flip mapAttrsToList cfg.settings
+ (name: val: "${name}=${serialize val}")));
- ${cfg.extraConfig}
- '';
+ mkDefaultAttrs = mapAttrs (n: v: mkDefault v);
in {
options.services.pdns-recursor = {
@@ -117,17 +119,55 @@ in {
'';
};
- extraConfig = mkOption {
+ settings = mkOption {
+ type = configType;
+ default = { };
+ example = literalExample ''
+ {
+ loglevel = 8;
+ log-common-errors = true;
+ }
+ '';
+ description = ''
+ PowerDNS Recursor settings. Use this option to configure Recursor
+ settings not exposed in a NixOS option or to bypass one.
+ See the full documentation at
+
+ for the available options.
+ '';
+ };
+
+ luaConfig = mkOption {
type = types.lines;
default = "";
description = ''
- Extra options to be appended to the configuration file.
+ The content Lua configuration file for PowerDNS Recursor. See
+ .
'';
};
};
config = mkIf cfg.enable {
+ services.pdns-recursor.settings = mkDefaultAttrs {
+ local-address = cfg.dns.address;
+ local-port = cfg.dns.port;
+ allow-from = cfg.dns.allowFrom;
+
+ webserver-address = cfg.api.address;
+ webserver-port = cfg.api.port;
+ webserver-allow-from = cfg.api.allowFrom;
+
+ forward-zones = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZones;
+ export-etc-hosts = cfg.exportHosts;
+ dnssec = cfg.dnssecValidation;
+ serve-rfc1918 = cfg.serveRFC1918;
+ lua-config-file = pkgs.writeText "recursor.lua" cfg.luaConfig;
+
+ log-timestamp = false;
+ disable-syslog = true;
+ };
+
users.users."${username}" = {
home = dataDir;
createHome = true;
@@ -150,8 +190,7 @@ in {
AmbientCapabilities = "cap_net_bind_service";
ExecStart = ''${pkgs.pdns-recursor}/bin/pdns_recursor \
--config-dir=${dataDir} \
- --socket-dir=${dataDir} \
- --disable-syslog
+ --socket-dir=${dataDir}
'';
};
@@ -165,4 +204,10 @@ in {
'';
};
};
+
+ imports = [
+ (mkRemovedOptionModule [ "services" "pdns-recursor" "extraConfig" ]
+ "To change extra Recursor settings use services.pdns-recursor.settings instead.")
+ ];
+
}