···
1
+
{ config, lib, pkgs, ... }:
6
+
dataDir = "/var/lib/pdns-recursor";
7
+
username = "pdns-recursor";
9
+
cfg = config.services.pdns-recursor;
10
+
zones = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZones;
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}
17
+
webserver-address=${cfg.api.address}
18
+
webserver-port=${toString cfg.api.port}
19
+
webserver-allow-from=${concatStringsSep "," cfg.api.allowFrom}
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"}
30
+
options.services.pdns-recursor = {
31
+
enable = mkEnableOption "PowerDNS Recursor, a recursive DNS server";
33
+
dns.address = mkOption {
35
+
default = "0.0.0.0";
37
+
IP address Recursor DNS server will bind to.
41
+
dns.port = mkOption {
45
+
Port number Recursor DNS server will bind to.
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" ];
54
+
IP address ranges of clients allowed to make DNS queries.
58
+
api.address = mkOption {
60
+
default = "0.0.0.0";
62
+
IP address Recursor REST API server will bind to.
66
+
api.port = mkOption {
70
+
Port number Recursor REST API server will bind to.
74
+
api.allowFrom = mkOption {
75
+
type = types.listOf types.str;
76
+
default = [ "0.0.0.0/0" ];
78
+
IP address ranges of clients allowed to make API requests.
82
+
exportHosts = mkOption {
86
+
Whether to export names and IP addresses defined in /etc/hosts.
90
+
forwardZones = mkOption {
92
+
example = { eth = "127.0.0.1:5353"; };
95
+
DNS zones to be forwarded to other servers.
99
+
dnssecValidation = mkOption {
100
+
type = types.enum ["off" "process-no-validate" "process" "log-fail" "validate"];
101
+
default = "validate";
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.
108
+
serveRFC1918 = mkOption {
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.
120
+
extraConfig = mkOption {
121
+
type = types.lines;
124
+
Extra options to be appended to the configuration file.
129
+
config = mkIf cfg.enable {
131
+
users.extraUsers."${username}" = {
134
+
uid = config.ids.uids.pdns-recursor;
135
+
description = "PowerDNS Recursor daemon user";
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" ];
146
+
Restart ="on-failure";
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} \
159
+
# Link configuration file into recursor home directory
160
+
configPath=${dataDir}/recursor.conf
161
+
if [ "$(realpath $configPath)" != "${configFile}" ]; then
163
+
ln -s ${configFile} $configPath