1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8with lib;
9
10let
11 cfg = config.services.powerdns;
12 configDir = pkgs.writeTextDir "pdns.conf" "${cfg.extraConfig}";
13 finalConfigDir = if cfg.secretFile == null then configDir else "/run/pdns";
14in
15{
16 options = {
17 services.powerdns = {
18 enable = mkEnableOption "PowerDNS domain name server";
19
20 extraConfig = mkOption {
21 type = types.lines;
22 default = "launch=bind";
23 description = ''
24 PowerDNS configuration. Refer to
25 <https://doc.powerdns.com/authoritative/settings.html>
26 for details on supported values.
27 '';
28 };
29
30 secretFile = mkOption {
31 type = types.nullOr types.path;
32 default = null;
33 example = "/run/keys/powerdns.env";
34 description = ''
35 Environment variables from this file will be interpolated into the
36 final config file using envsubst with this syntax: `$ENVIRONMENT`
37 or `''${VARIABLE}`.
38 The file should contain lines formatted as `SECRET_VAR=SECRET_VALUE`.
39 This is useful to avoid putting secrets into the nix store.
40 '';
41 };
42 };
43 };
44
45 config = mkIf cfg.enable {
46
47 environment.etc.pdns.source = finalConfigDir;
48
49 systemd.packages = [ pkgs.pdns ];
50
51 systemd.services.pdns = {
52 wantedBy = [ "multi-user.target" ];
53 after = [
54 "network.target"
55 "mysql.service"
56 "postgresql.service"
57 "openldap.service"
58 ];
59
60 serviceConfig = {
61 EnvironmentFile = lib.optional (cfg.secretFile != null) cfg.secretFile;
62 ExecStartPre = lib.optional (cfg.secretFile != null) (
63 pkgs.writeShellScript "pdns-pre-start" ''
64 umask 077
65 ${pkgs.envsubst}/bin/envsubst -i "${configDir}/pdns.conf" > ${finalConfigDir}/pdns.conf
66 ''
67 );
68 ExecStart = [
69 ""
70 "${pkgs.pdns}/bin/pdns_server --config-dir=${finalConfigDir} --guardian=no --daemon=no --disable-syslog --log-timestamp=no --write-pid=no"
71 ];
72 };
73 };
74
75 users.users.pdns = {
76 isSystemUser = true;
77 group = "pdns";
78 description = "PowerDNS";
79 };
80
81 users.groups.pdns = { };
82
83 };
84}