From 6bcf89f2174275d11bacb4076e3318c5578708b1 Mon Sep 17 00:00:00 2001 From: rnhmjoj Date: Wed, 18 Jan 2017 00:29:59 +0100 Subject: [PATCH] pdns-recursor: add service --- nixos/modules/misc/ids.nix | 1 + nixos/modules/module-list.nix | 1 + .../services/networking/pdns-recursor.nix | 168 ++++++++++++++++++ 3 files changed, 170 insertions(+) create mode 100644 nixos/modules/services/networking/pdns-recursor.nix diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 5058d41bf753..db8b66c9768f 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -284,6 +284,7 @@ glance = 266; couchpotato = 267; gogs = 268; + pdns-recursor = 269; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index e99e344b932d..f3996564fd95 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -426,6 +426,7 @@ ./services/networking/pdnsd.nix ./services/networking/polipo.nix ./services/networking/powerdns.nix + ./services/networking/pdns-recursor.nix ./services/networking/pptpd.nix ./services/networking/prayer.nix ./services/networking/privoxy.nix diff --git a/nixos/modules/services/networking/pdns-recursor.nix b/nixos/modules/services/networking/pdns-recursor.nix new file mode 100644 index 000000000000..26be72d2a61e --- /dev/null +++ b/nixos/modules/services/networking/pdns-recursor.nix @@ -0,0 +1,168 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + 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"} + + ${cfg.extraConfig} + ''; + +in { + options.services.pdns-recursor = { + enable = mkEnableOption "PowerDNS Recursor, a recursive DNS server"; + + dns.address = mkOption { + type = types.str; + default = "0.0.0.0"; + description = '' + IP address Recursor DNS server will bind to. + ''; + }; + + dns.port = mkOption { + type = types.int; + default = 53; + description = '' + 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" ]; + 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 { + type = types.int; + default = 8082; + description = '' + Port number Recursor REST API server will bind to. + ''; + }; + + api.allowFrom = mkOption { + type = types.listOf types.str; + default = [ "0.0.0.0/0" ]; + 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 { + type = types.attrs; + example = { eth = "127.0.0.1:5353"; }; + default = {}; + description = '' + DNS zones to be forwarded to other servers. + ''; + }; + + 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. + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra options to be appended to the configuration file. + ''; + }; + }; + + config = mkIf cfg.enable { + + users.extraUsers."${username}" = { + home = dataDir; + createHome = true; + 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" ]; + + serviceConfig = { + User = username; + Restart ="on-failure"; + RestartSec = "5"; + PrivateTmp = true; + PrivateDevices = true; + AmbientCapabilities = "cap_net_bind_service"; + ExecStart = ''${pkgs.pdns-recursor}/bin/pdns_recursor \ + --config-dir=${dataDir} \ + --socket-dir=${dataDir} \ + --disable-syslog + ''; + }; + + preStart = '' + # Link configuration file into recursor home directory + configPath=${dataDir}/recursor.conf + if [ "$(realpath $configPath)" != "${configFile}" ]; then + rm -f $configPath + ln -s ${configFile} $configPath + fi + ''; + }; + }; +}