2017-01-18 00:29:59 +01:00
|
|
|
{
|
|
|
|
config,
|
|
|
|
lib,
|
|
|
|
pkgs,
|
|
|
|
...
|
|
|
|
}:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
2019-08-22 14:02:02 +02:00
|
|
|
cfg = config.services.pdns-recursor;
|
2017-01-18 00:29:59 +01:00
|
|
|
|
2019-08-22 14:02:02 +02:00
|
|
|
oneOrMore = type: with types; either type (listOf type);
|
|
|
|
valueType =
|
|
|
|
with types;
|
|
|
|
oneOf [
|
|
|
|
int
|
|
|
|
str
|
|
|
|
bool
|
|
|
|
path
|
|
|
|
];
|
|
|
|
configType = with types; attrsOf (nullOr (oneOrMore valueType));
|
2017-01-18 00:29:59 +01:00
|
|
|
|
2019-08-22 14:02:02 +02:00
|
|
|
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
|
|
|
|
"";
|
2024-12-10 20:26:33 +01:00
|
|
|
|
2020-10-17 17:59:18 -04:00
|
|
|
configDir = pkgs.writeTextDir "recursor.conf" (
|
2019-08-22 14:02:02 +02:00
|
|
|
concatStringsSep "\n" (flip mapAttrsToList cfg.settings (name: val: "${name}=${serialize val}"))
|
|
|
|
);
|
2017-01-18 00:29:59 +01:00
|
|
|
|
2019-08-22 14:02:02 +02:00
|
|
|
mkDefaultAttrs = mapAttrs (n: v: mkDefault v);
|
2017-01-18 00:29:59 +01:00
|
|
|
|
|
|
|
in
|
|
|
|
{
|
|
|
|
options.services.pdns-recursor = {
|
|
|
|
enable = mkEnableOption "PowerDNS Recursor, a recursive DNS server";
|
|
|
|
|
|
|
|
dns.address = mkOption {
|
2022-04-13 17:40:11 +02:00
|
|
|
type = oneOrMore types.str;
|
|
|
|
default = [
|
|
|
|
"::"
|
|
|
|
"0.0.0.0"
|
|
|
|
];
|
2017-01-18 00:29:59 +01:00
|
|
|
description = ''
|
2022-04-13 17:40:11 +02:00
|
|
|
IP addresses Recursor DNS server will bind to.
|
2017-01-18 00:29:59 +01:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
dns.port = mkOption {
|
2022-11-30 17:15:00 +01:00
|
|
|
type = types.port;
|
2017-01-18 00:29:59 +01:00
|
|
|
default = 53;
|
|
|
|
description = ''
|
|
|
|
Port number Recursor DNS server will bind to.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
dns.allowFrom = mkOption {
|
|
|
|
type = types.listOf types.str;
|
2022-04-13 17:40:11 +02:00
|
|
|
default = [
|
|
|
|
"127.0.0.0/8"
|
|
|
|
"10.0.0.0/8"
|
|
|
|
"100.64.0.0/10"
|
|
|
|
"169.254.0.0/16"
|
|
|
|
"192.168.0.0/16"
|
|
|
|
"172.16.0.0/12"
|
|
|
|
"::1/128"
|
|
|
|
"fc00::/7"
|
|
|
|
"fe80::/10"
|
2024-12-10 20:26:33 +01:00
|
|
|
];
|
2022-04-13 17:40:11 +02:00
|
|
|
example = [
|
|
|
|
"0.0.0.0/0"
|
2024-12-10 20:26:33 +01:00
|
|
|
"::/0"
|
2022-04-13 17:40:11 +02:00
|
|
|
];
|
2017-01-18 00:29:59 +01:00
|
|
|
description = ''
|
|
|
|
IP address ranges of clients allowed to make DNS queries.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
api.address = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "0.0.0.0";
|
|
|
|
description = ''
|
|
|
|
IP address Recursor REST API server will bind to.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
api.port = mkOption {
|
2022-11-30 17:15:00 +01:00
|
|
|
type = types.port;
|
2017-01-18 00:29:59 +01:00
|
|
|
default = 8082;
|
|
|
|
description = ''
|
|
|
|
Port number Recursor REST API server will bind to.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
api.allowFrom = mkOption {
|
|
|
|
type = types.listOf types.str;
|
2022-04-13 17:40:11 +02:00
|
|
|
default = [
|
|
|
|
"127.0.0.1"
|
|
|
|
"::1"
|
|
|
|
];
|
|
|
|
example = [
|
|
|
|
"0.0.0.0/0"
|
|
|
|
"::/0"
|
|
|
|
];
|
2017-01-18 00:29:59 +01:00
|
|
|
description = ''
|
|
|
|
IP address ranges of clients allowed to make API requests.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
exportHosts = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
Whether to export names and IP addresses defined in /etc/hosts.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
forwardZones = mkOption {
|
2019-11-07 17:08:09 +01:00
|
|
|
type = types.attrs;
|
|
|
|
default = { };
|
|
|
|
description = ''
|
|
|
|
DNS zones to be forwarded to other authoritative servers.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
forwardZonesRecurse = mkOption {
|
2017-01-18 00:29:59 +01:00
|
|
|
type = types.attrs;
|
2022-04-13 17:40:11 +02:00
|
|
|
example = {
|
|
|
|
eth = "[::1]:5353";
|
|
|
|
};
|
2017-01-18 00:29:59 +01:00
|
|
|
default = { };
|
|
|
|
description = ''
|
2019-11-07 17:08:09 +01:00
|
|
|
DNS zones to be forwarded to other recursive servers.
|
2017-01-18 00:29:59 +01:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
dnssecValidation = mkOption {
|
|
|
|
type = types.enum [
|
|
|
|
"off"
|
|
|
|
"process-no-validate"
|
|
|
|
"process"
|
|
|
|
"log-fail"
|
|
|
|
"validate"
|
|
|
|
];
|
|
|
|
default = "validate";
|
|
|
|
description = ''
|
|
|
|
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 {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
|
|
|
description = ''
|
|
|
|
Whether to directly resolve the RFC1918 reverse-mapping domains:
|
|
|
|
`10.in-addr.arpa`,
|
|
|
|
`168.192.in-addr.arpa`,
|
|
|
|
`16-31.172.in-addr.arpa`
|
|
|
|
This saves load on the AS112 servers.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2019-08-22 14:02:02 +02:00
|
|
|
settings = mkOption {
|
|
|
|
type = configType;
|
|
|
|
default = { };
|
2021-10-03 18:06:03 +02:00
|
|
|
example = literalExpression ''
|
2019-08-22 14:02:02 +02:00
|
|
|
{
|
|
|
|
loglevel = 8;
|
|
|
|
log-common-errors = true;
|
|
|
|
}
|
|
|
|
'';
|
2017-01-18 00:29:59 +01:00
|
|
|
description = ''
|
2019-08-22 14:02:02 +02:00
|
|
|
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
|
|
|
|
<https://doc.powerdns.com/recursor/settings.html>
|
|
|
|
for the available options.
|
2017-01-18 00:29:59 +01:00
|
|
|
'';
|
|
|
|
};
|
2019-08-22 14:02:02 +02:00
|
|
|
|
2019-08-22 15:03:14 +02:00
|
|
|
luaConfig = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
The content Lua configuration file for PowerDNS Recursor. See
|
|
|
|
<https://doc.powerdns.com/recursor/lua-config/index.html>.
|
|
|
|
'';
|
|
|
|
};
|
2017-01-18 00:29:59 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
|
2023-06-29 12:42:01 +02:00
|
|
|
environment.etc."pdns-recursor".source = configDir;
|
2023-02-25 16:33:36 +01:00
|
|
|
|
2019-08-22 14:02:02 +02:00
|
|
|
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;
|
|
|
|
|
2019-11-07 17:08:09 +01:00
|
|
|
forward-zones = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZones;
|
|
|
|
forward-zones-recurse = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZonesRecurse;
|
2019-08-22 14:02:02 +02:00
|
|
|
export-etc-hosts = cfg.exportHosts;
|
|
|
|
dnssec = cfg.dnssecValidation;
|
|
|
|
serve-rfc1918 = cfg.serveRFC1918;
|
2019-08-22 15:03:14 +02:00
|
|
|
lua-config-file = pkgs.writeText "recursor.lua" cfg.luaConfig;
|
2019-08-22 14:02:02 +02:00
|
|
|
|
2020-10-17 17:59:18 -04:00
|
|
|
daemon = false;
|
|
|
|
write-pid = false;
|
2019-08-22 14:02:02 +02:00
|
|
|
log-timestamp = false;
|
|
|
|
disable-syslog = true;
|
|
|
|
};
|
|
|
|
|
2020-10-17 17:59:18 -04:00
|
|
|
systemd.packages = [ pkgs.pdns-recursor ];
|
2017-01-18 00:29:59 +01:00
|
|
|
|
|
|
|
systemd.services.pdns-recursor = {
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
|
|
|
|
serviceConfig = {
|
2020-10-17 17:59:18 -04:00
|
|
|
ExecStart = [
|
|
|
|
""
|
|
|
|
"${pkgs.pdns-recursor}/bin/pdns_recursor --config-dir=${configDir}"
|
|
|
|
];
|
2017-01-18 00:29:59 +01:00
|
|
|
};
|
2020-10-17 17:59:18 -04:00
|
|
|
};
|
2017-01-18 00:29:59 +01:00
|
|
|
|
2020-10-17 17:59:18 -04:00
|
|
|
users.users.pdns-recursor = {
|
|
|
|
isSystemUser = true;
|
|
|
|
group = "pdns-recursor";
|
|
|
|
description = "PowerDNS Recursor daemon user";
|
2017-01-18 00:29:59 +01:00
|
|
|
};
|
2020-10-17 17:59:18 -04:00
|
|
|
|
|
|
|
users.groups.pdns-recursor = { };
|
|
|
|
|
2017-01-18 00:29:59 +01:00
|
|
|
};
|
2019-08-22 14:02:02 +02:00
|
|
|
|
|
|
|
imports = [
|
|
|
|
(mkRemovedOptionModule [
|
|
|
|
"services"
|
|
|
|
"pdns-recursor"
|
|
|
|
"extraConfig"
|
|
|
|
] "To change extra Recursor settings use services.pdns-recursor.settings instead.")
|
|
|
|
];
|
|
|
|
|
2019-12-04 17:07:45 +01:00
|
|
|
meta.maintainers = with lib.maintainers; [ rnhmjoj ];
|
|
|
|
|
2017-01-18 00:29:59 +01:00
|
|
|
}
|