at 17.09-beta 4.6 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 dataDir = "/var/lib/pdns-recursor"; 7 username = "pdns-recursor"; 8 9 cfg = config.services.pdns-recursor; 10 zones = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZones; 11 12 configFile = pkgs.writeText "recursor.conf" '' 13 local-address=${cfg.dns.address} 14 local-port=${toString cfg.dns.port} 15 allow-from=${concatStringsSep "," cfg.dns.allowFrom} 16 17 webserver-address=${cfg.api.address} 18 webserver-port=${toString cfg.api.port} 19 webserver-allow-from=${concatStringsSep "," cfg.api.allowFrom} 20 21 forward-zones=${concatStringsSep "," zones} 22 export-etc-hosts=${if cfg.exportHosts then "yes" else "no"} 23 dnssec=${cfg.dnssecValidation} 24 serve-rfc1918=${if cfg.serveRFC1918 then "yes" else "no"} 25 26 ${cfg.extraConfig} 27 ''; 28 29in { 30 options.services.pdns-recursor = { 31 enable = mkEnableOption "PowerDNS Recursor, a recursive DNS server"; 32 33 dns.address = mkOption { 34 type = types.str; 35 default = "0.0.0.0"; 36 description = '' 37 IP address Recursor DNS server will bind to. 38 ''; 39 }; 40 41 dns.port = mkOption { 42 type = types.int; 43 default = 53; 44 description = '' 45 Port number Recursor DNS server will bind to. 46 ''; 47 }; 48 49 dns.allowFrom = mkOption { 50 type = types.listOf types.str; 51 default = [ "10.0.0.0/8" "172.16.0.0/12" "192.168.0.0/16" ]; 52 example = [ "0.0.0.0/0" ]; 53 description = '' 54 IP address ranges of clients allowed to make DNS queries. 55 ''; 56 }; 57 58 api.address = mkOption { 59 type = types.str; 60 default = "0.0.0.0"; 61 description = '' 62 IP address Recursor REST API server will bind to. 63 ''; 64 }; 65 66 api.port = mkOption { 67 type = types.int; 68 default = 8082; 69 description = '' 70 Port number Recursor REST API server will bind to. 71 ''; 72 }; 73 74 api.allowFrom = mkOption { 75 type = types.listOf types.str; 76 default = [ "0.0.0.0/0" ]; 77 description = '' 78 IP address ranges of clients allowed to make API requests. 79 ''; 80 }; 81 82 exportHosts = mkOption { 83 type = types.bool; 84 default = false; 85 description = '' 86 Whether to export names and IP addresses defined in /etc/hosts. 87 ''; 88 }; 89 90 forwardZones = mkOption { 91 type = types.attrs; 92 example = { eth = "127.0.0.1:5353"; }; 93 default = {}; 94 description = '' 95 DNS zones to be forwarded to other servers. 96 ''; 97 }; 98 99 dnssecValidation = mkOption { 100 type = types.enum ["off" "process-no-validate" "process" "log-fail" "validate"]; 101 default = "validate"; 102 description = '' 103 Controls the level of DNSSEC processing done by the PowerDNS Recursor. 104 See https://doc.powerdns.com/md/recursor/dnssec/ for a detailed explanation. 105 ''; 106 }; 107 108 serveRFC1918 = mkOption { 109 type = types.bool; 110 default = true; 111 description = '' 112 Whether to directly resolve the RFC1918 reverse-mapping domains: 113 <literal>10.in-addr.arpa</literal>, 114 <literal>168.192.in-addr.arpa</literal>, 115 <literal>16-31.172.in-addr.arpa</literal> 116 This saves load on the AS112 servers. 117 ''; 118 }; 119 120 extraConfig = mkOption { 121 type = types.lines; 122 default = ""; 123 description = '' 124 Extra options to be appended to the configuration file. 125 ''; 126 }; 127 }; 128 129 config = mkIf cfg.enable { 130 131 users.extraUsers."${username}" = { 132 home = dataDir; 133 createHome = true; 134 uid = config.ids.uids.pdns-recursor; 135 description = "PowerDNS Recursor daemon user"; 136 }; 137 138 systemd.services.pdns-recursor = { 139 unitConfig.Documentation = "man:pdns_recursor(1) man:rec_control(1)"; 140 description = "PowerDNS recursive server"; 141 wantedBy = [ "multi-user.target" ]; 142 after = [ "network.target" ]; 143 144 serviceConfig = { 145 User = username; 146 Restart ="on-failure"; 147 RestartSec = "5"; 148 PrivateTmp = true; 149 PrivateDevices = true; 150 AmbientCapabilities = "cap_net_bind_service"; 151 ExecStart = ''${pkgs.pdns-recursor}/bin/pdns_recursor \ 152 --config-dir=${dataDir} \ 153 --socket-dir=${dataDir} \ 154 --disable-syslog 155 ''; 156 }; 157 158 preStart = '' 159 # Link configuration file into recursor home directory 160 configPath=${dataDir}/recursor.conf 161 if [ "$(realpath $configPath)" != "${configFile}" ]; then 162 rm -f $configPath 163 ln -s ${configFile} $configPath 164 fi 165 ''; 166 }; 167 }; 168}