diff --git a/nixos/modules/services/networking/pdns-recursor.nix b/nixos/modules/services/networking/pdns-recursor.nix index 3b554c7e31a1..42f609128b95 100644 --- a/nixos/modules/services/networking/pdns-recursor.nix +++ b/nixos/modules/services/networking/pdns-recursor.nix @@ -38,12 +38,34 @@ let else ""; - configDir = pkgs.writeTextDir "recursor.conf" ( - concatStringsSep "\n" (flip mapAttrsToList cfg.settings (name: val: "${name}=${serialize val}")) - ); + settingsFormat = pkgs.formats.yaml { }; mkDefaultAttrs = mapAttrs (n: v: mkDefault v); + mkForwardZone = mapAttrsToList ( + zone: uri: { + inherit zone; + forwarders = [ uri ]; + } + ); + + configFile = + if cfg.old-settings != { } then + # Convert recursor.conf to recursor.yml and merge it + let + conf = pkgs.writeText "recursor.conf" ( + concatStringsSep "\n" (mapAttrsToList (name: val: "${name}=${serialize val}") cfg.old-settings) + ); + + yaml = settingsFormat.generate "recursor.yml" cfg.yaml-settings; + in + pkgs.runCommand "recursor-merged.yml" { } '' + ${pkgs.pdns-recursor}/bin/rec_control show-yaml --config ${conf} > override.yml + ${pkgs.yq-go}/bin/yq '. *= load("override.yml")' ${yaml} > $out + '' + else + settingsFormat.generate "recursor.yml" cfg.yaml-settings; + in { options.services.pdns-recursor = { @@ -175,7 +197,7 @@ in ''; }; - settings = mkOption { + old-settings = mkOption { type = configType; default = { }; example = literalExpression '' @@ -184,11 +206,34 @@ in log-common-errors = true; } ''; + description = '' + Older 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. + + ::: {.warning} + This option is provided for backward compatibility only + and will be removed in the next release of NixOS. + ::: + ''; + }; + + yaml-settings = mkOption { + type = settingsFormat.type; + default = { }; + example = literalExpression '' + { + 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. ''; }; @@ -205,42 +250,44 @@ in config = mkIf cfg.enable { - environment.etc."pdns-recursor".source = configDir; + environment.etc."/pdns-recursor/recursor.yml".source = configFile; - services.pdns-recursor.settings = mkDefaultAttrs { - local-address = cfg.dns.address; - local-port = cfg.dns.port; - allow-from = cfg.dns.allowFrom; + services.pdns-recursor.yaml-settings = { + incoming = mkDefaultAttrs { + listen = cfg.dns.address; + 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; + webservice = mkDefaultAttrs { + address = cfg.api.address; + port = cfg.api.port; + allow_from = cfg.api.allowFrom; + }; - forward-zones = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZones; - forward-zones-recurse = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZonesRecurse; - export-etc-hosts = cfg.exportHosts; - dnssec = cfg.dnssecValidation; - serve-rfc1918 = cfg.serveRFC1918; - lua-config-file = pkgs.writeText "recursor.lua" cfg.luaConfig; + recursor = mkDefaultAttrs { + forward_zones = mkForwardZone cfg.forwardZones; + forward_zones_recurse = mkForwardZone cfg.forwardZonesRecurse; + export_etc_hosts = cfg.exportHosts; + serve_rfc1918 = cfg.serveRFC1918; + lua_config_file = pkgs.writeText "recursor.lua" cfg.luaConfig; + daemon = false; + write_pid = false; + }; - daemon = false; - write-pid = false; - log-timestamp = false; - disable-syslog = true; + dnssec = mkDefaultAttrs { + validation = cfg.dnssecValidation; + }; + + logging = mkDefaultAttrs { + timestamp = false; + disable_syslog = true; + }; }; systemd.packages = [ pkgs.pdns-recursor ]; - systemd.services.pdns-recursor = { - wantedBy = [ "multi-user.target" ]; - - serviceConfig = { - ExecStart = [ - "" - "${pkgs.pdns-recursor}/bin/pdns_recursor --config-dir=${configDir}" - ]; - }; - }; + systemd.services.pdns-recursor.wantedBy = [ "multi-user.target" ]; users.users.pdns-recursor = { isSystemUser = true; @@ -250,6 +297,15 @@ in users.groups.pdns-recursor = { }; + warnings = lib.optional (cfg.old-settings != { }) '' + pdns-recursor has changed its configuration file format from pdns-recursor.conf + (mapped to `services.pdns-recursor.old-settings`) to the newer pdns-recursor.yml + (mapped to `services.pdns-recursor.yaml-settings`). + + Support for the older format will be removed in a future version, so please migrate + your settings over. See . + ''; + }; imports = [ @@ -258,6 +314,19 @@ in "pdns-recursor" "extraConfig" ] "To change extra Recursor settings use services.pdns-recursor.settings instead.") + + (mkRenamedOptionModule + [ + "services" + "pdns-recursor" + "settings" + ] + [ + "services" + "pdns-recursor" + "old-settings" + ] + ) ]; meta.maintainers = with lib.maintainers; [ rnhmjoj ];