···
+
{ config, lib, pkgs, ... }:
+
dataDir = "/var/lib/pdns-recursor";
+
username = "pdns-recursor";
+
cfg = config.services.pdns-recursor;
+
zones = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZones;
+
configFile = pkgs.writeText "recursor.conf" ''
+
local-address=${cfg.dns.address}
+
local-port=${toString cfg.dns.port}
+
allow-from=${concatStringsSep "," cfg.dns.allowFrom}
+
webserver-address=${cfg.api.address}
+
webserver-port=${toString cfg.api.port}
+
webserver-allow-from=${concatStringsSep "," cfg.api.allowFrom}
+
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"}
+
options.services.pdns-recursor = {
+
enable = mkEnableOption "PowerDNS Recursor, a recursive DNS server";
+
dns.address = mkOption {
+
IP address Recursor DNS server will bind to.
+
Port number Recursor DNS server will bind to.
+
dns.allowFrom = mkOption {
+
type = types.listOf types.str;
+
default = [ "10.0.0.0/8" "172.16.0.0/12" "192.168.0.0/16" ];
+
example = [ "0.0.0.0/0" ];
+
IP address ranges of clients allowed to make DNS queries.
+
api.address = mkOption {
+
IP address Recursor REST API server will bind to.
+
Port number Recursor REST API server will bind to.
+
api.allowFrom = mkOption {
+
type = types.listOf types.str;
+
default = [ "0.0.0.0/0" ];
+
IP address ranges of clients allowed to make API requests.
+
exportHosts = mkOption {
+
Whether to export names and IP addresses defined in /etc/hosts.
+
forwardZones = mkOption {
+
example = { eth = "127.0.0.1:5353"; };
+
DNS zones to be forwarded to other servers.
+
dnssecValidation = mkOption {
+
type = types.enum ["off" "process-no-validate" "process" "log-fail" "validate"];
+
Controls the level of DNSSEC processing done by the PowerDNS Recursor.
+
See https://doc.powerdns.com/md/recursor/dnssec/ for a detailed explanation.
+
serveRFC1918 = mkOption {
+
Whether to directly resolve the RFC1918 reverse-mapping domains:
+
<literal>10.in-addr.arpa</literal>,
+
<literal>168.192.in-addr.arpa</literal>,
+
<literal>16-31.172.in-addr.arpa</literal>
+
This saves load on the AS112 servers.
+
extraConfig = mkOption {
+
Extra options to be appended to the configuration file.
+
config = mkIf cfg.enable {
+
users.extraUsers."${username}" = {
+
uid = config.ids.uids.pdns-recursor;
+
description = "PowerDNS Recursor daemon user";
+
systemd.services.pdns-recursor = {
+
unitConfig.Documentation = "man:pdns_recursor(1) man:rec_control(1)";
+
description = "PowerDNS recursive server";
+
wantedBy = [ "multi-user.target" ];
+
after = [ "network.target" ];
+
AmbientCapabilities = "cap_net_bind_service";
+
ExecStart = ''${pkgs.pdns-recursor}/bin/pdns_recursor \
+
--config-dir=${dataDir} \
+
--socket-dir=${dataDir} \
+
# Link configuration file into recursor home directory
+
configPath=${dataDir}/recursor.conf
+
if [ "$(realpath $configPath)" != "${configFile}" ]; then
+
ln -s ${configFile} $configPath