diff options
-rw-r--r-- | nixos/doc/manual/release-notes/rl-2103.xml | 10 | ||||
-rw-r--r-- | nixos/modules/services/networking/powerdns.nix | 40 | ||||
-rw-r--r-- | nixos/tests/powerdns.nix | 60 | ||||
-rw-r--r-- | pkgs/servers/dns/powerdns/default.nix | 11 |
4 files changed, 90 insertions, 31 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2103.xml b/nixos/doc/manual/release-notes/rl-2103.xml index c160ab5783d3..374ea1cbd165 100644 --- a/nixos/doc/manual/release-notes/rl-2103.xml +++ b/nixos/doc/manual/release-notes/rl-2103.xml @@ -99,6 +99,16 @@ to <literal>/run/pdns-recursor</literal> to match upstream. </para> </listitem> + <listitem> + <para> + PowerDNS has been updated from <literal>4.2.x</literal> to <literal>4.3.x</literal>. Please + be sure to review the <link xlink:href="https://doc.powerdns.com/authoritative/upgrading.html#x-to-4-3-0">Upgrade Notes</link> + provided by upstream before upgrading. Worth specifically noting is that the service now runs + entirely as a dedicated <literal>pdns</literal> user, instead of starting as <literal>root</literal> + and dropping privileges, as well as the default <literal>socket-dir</literal> location changing from + <literal>/var/lib/powerdns</literal> to <literal>/run/pdns</literal>. + </para> + </listitem> </itemizedlist> </section> diff --git a/nixos/modules/services/networking/powerdns.nix b/nixos/modules/services/networking/powerdns.nix index ba05e15389f6..8cae61b83543 100644 --- a/nixos/modules/services/networking/powerdns.nix +++ b/nixos/modules/services/networking/powerdns.nix @@ -8,42 +8,40 @@ let in { options = { services.powerdns = { - enable = mkEnableOption "Powerdns domain name server"; + enable = mkEnableOption "PowerDNS domain name server"; extraConfig = mkOption { type = types.lines; default = "launch=bind"; description = '' - Extra lines to be added verbatim to pdns.conf. - Powerdns will chroot to /var/lib/powerdns. - So any file, powerdns is supposed to be read, - should be in /var/lib/powerdns and needs to specified - relative to the chroot. + PowerDNS configuration. Refer to + <link xlink:href="https://doc.powerdns.com/authoritative/settings.html"/> + for details on supported values. ''; }; }; }; - config = mkIf config.services.powerdns.enable { + config = mkIf cfg.enable { + + systemd.packages = [ pkgs.powerdns ]; + systemd.services.pdns = { - unitConfig.Documentation = "man:pdns_server(1) man:pdns_control(1)"; - description = "Powerdns name server"; wantedBy = [ "multi-user.target" ]; - after = ["network.target" "mysql.service" "postgresql.service" "openldap.service"]; + after = [ "network.target" "mysql.service" "postgresql.service" "openldap.service" ]; serviceConfig = { - Restart="on-failure"; - RestartSec="1"; - StartLimitInterval="0"; - PrivateDevices=true; - CapabilityBoundingSet="CAP_CHOWN CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT"; - NoNewPrivileges=true; - ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p /var/lib/powerdns"; - ExecStart = "${pkgs.powerdns}/bin/pdns_server --setuid=nobody --setgid=nogroup --chroot=/var/lib/powerdns --socket-dir=/ --daemon=no --guardian=no --disable-syslog --write-pid=no --config-dir=${configDir}"; - ProtectSystem="full"; - ProtectHome=true; - RestrictAddressFamilies="AF_UNIX AF_INET AF_INET6"; + ExecStart = [ "" "${pkgs.powerdns}/bin/pdns_server --config-dir=${configDir} --guardian=no --daemon=no --disable-syslog --log-timestamp=no --write-pid=no" ]; }; }; + + users.users.pdns = { + isSystemUser = true; + group = "pdns"; + description = "PowerDNS"; + }; + + users.groups.pdns = {}; + }; } diff --git a/nixos/tests/powerdns.nix b/nixos/tests/powerdns.nix index 75d71315e644..d025934ad2b3 100644 --- a/nixos/tests/powerdns.nix +++ b/nixos/tests/powerdns.nix @@ -1,13 +1,65 @@ -import ./make-test-python.nix ({ pkgs, ... }: { +# This test runs PowerDNS authoritative server with the +# generic MySQL backend (gmysql) to connect to a +# MariaDB server using UNIX sockets authentication. + +import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "powerdns"; nodes.server = { ... }: { services.powerdns.enable = true; - environment.systemPackages = [ pkgs.dnsutils ]; + services.powerdns.extraConfig = '' + launch=gmysql + gmysql-user=pdns + ''; + + services.mysql = { + enable = true; + package = pkgs.mariadb; + ensureDatabases = [ "powerdns" ]; + ensureUsers = lib.singleton + { name = "pdns"; + ensurePermissions = { "powerdns.*" = "ALL PRIVILEGES"; }; + }; + }; + + environment.systemPackages = with pkgs; + [ dnsutils powerdns mariadb ]; }; testScript = '' - server.wait_for_unit("pdns") - server.succeed("dig version.bind txt chaos \@127.0.0.1") + import re + + with subtest("PowerDNS database exists"): + server.wait_for_unit("mysql") + server.succeed("echo 'SHOW DATABASES;' | sudo -u pdns mysql -u pdns >&2") + + with subtest("Loading the MySQL schema works"): + server.succeed( + "sudo -u pdns mysql -u pdns -D powerdns <" + "${pkgs.powerdns}/share/doc/pdns/schema.mysql.sql" + ) + + with subtest("PowerDNS server starts"): + server.wait_for_unit("pdns") + server.succeed("dig version.bind txt chaos @127.0.0.1 >&2") + + with subtest("Adding an example zone works"): + # Extract configuration file needed by pdnsutil + unit = server.succeed("systemctl cat pdns") + conf = re.search("(--config-dir=[^ ]+)", unit).group(1) + pdnsutil = "sudo -u pdns pdnsutil " + conf + server.succeed(f"{pdnsutil} create-zone example.com ns1.example.com") + server.succeed(f"{pdnsutil} add-record example.com ns1 A 192.168.1.2") + + with subtest("Querying the example zone works"): + reply = server.succeed("dig +noall +answer ns1.example.com @127.0.0.1") + assert ( + "192.168.1.2" in reply + ), f"""" + The reply does not contain the expected IP address: + Expected: + ns1.example.com. 3600 IN A 192.168.1.2 + Reply: + {reply}""" ''; }) diff --git a/pkgs/servers/dns/powerdns/default.nix b/pkgs/servers/dns/powerdns/default.nix index cacd5b7c54fe..0f9f91ebf861 100644 --- a/pkgs/servers/dns/powerdns/default.nix +++ b/pkgs/servers/dns/powerdns/default.nix @@ -1,29 +1,28 @@ { stdenv, fetchurl, pkgconfig, nixosTests , boost, libyamlcpp, libsodium, sqlite, protobuf, openssl, systemd -, mysql57, postgresql, lua, openldap, geoip, curl, opendbx, unixODBC +, mysql57, postgresql, lua, openldap, geoip, curl, unixODBC }: stdenv.mkDerivation rec { pname = "powerdns"; - version = "4.2.3"; + version = "4.3.1"; src = fetchurl { url = "https://downloads.powerdns.com/releases/pdns-${version}.tar.bz2"; - sha256 = "1vf03hssk9rfhvhzfc5ca2r4ly67wq0czr0ysvdrk8pnb0yk6yfi"; + sha256 = "0if27znz528sir52y9i4gcfhdsym7yxiwjgffy9lpscf1426q56m"; }; nativeBuildInputs = [ pkgconfig ]; buildInputs = [ boost mysql57.connector-c postgresql lua openldap sqlite protobuf geoip - libyamlcpp libsodium curl opendbx unixODBC openssl systemd + libyamlcpp libsodium curl unixODBC openssl systemd ]; # nix destroy with-modules arguments, when using configureFlags preConfigure = '' configureFlagsArray=( - "--with-modules=bind gmysql geoip godbc gpgsql gsqlite3 ldap lua mydns opendbx pipe random remote" + "--with-modules=bind gmysql geoip godbc gpgsql gsqlite3 ldap lua2 pipe random remote" --with-sqlite3 - --with-socketdir=/var/lib/powerdns --with-libcrypto=${openssl.dev} --with-libsodium --enable-tools |