diff options
-rw-r--r-- | hosts/surtr/tls.nix | 12 | ||||
-rw-r--r-- | modules/knot.nix | 126 |
2 files changed, 133 insertions, 5 deletions
diff --git a/hosts/surtr/tls.nix b/hosts/surtr/tls.nix index 17c49d1e..5b583235 100644 --- a/hosts/surtr/tls.nix +++ b/hosts/surtr/tls.nix | |||
@@ -1,5 +1,7 @@ | |||
1 | { pkgs, ... }: | 1 | { config, pkgs, ... }: |
2 | let | 2 | let |
3 | knotCfg = config.services.knot; | ||
4 | |||
3 | knotDNSCredentials = zone: pkgs.writeText "lego-credentials" '' | 5 | knotDNSCredentials = zone: pkgs.writeText "lego-credentials" '' |
4 | EXEC_PATH=${knotDNSExec zone}/bin/update-dns.sh | 6 | EXEC_PATH=${knotDNSExec zone}/bin/update-dns.sh |
5 | ''; | 7 | ''; |
@@ -12,21 +14,21 @@ let | |||
12 | 14 | ||
13 | owner=''${fqdn%"${zone}."} | 15 | owner=''${fqdn%"${zone}."} |
14 | 16 | ||
15 | knotc zone-begin "${zone}" | 17 | ${knotCfg.cliWrappers}/bin/knotc zone-begin "${zone}" |
16 | 18 | ||
17 | case "''${mode}" in | 19 | case "''${mode}" in |
18 | present) | 20 | present) |
19 | knotc zone-set ${zone} "''${owner}" 300 TXT "''${challenge}" | 21 | ${knotCfg.cliWrappers}/bin/knotc zone-set ${zone} "''${owner}" 300 TXT "''${challenge}" |
20 | ;; | 22 | ;; |
21 | cleanup) | 23 | cleanup) |
22 | knotc zone-unset ${zone} "''${owner}" TXT "''${challenge}" | 24 | ${knotCfg.cliWrappers}/bin/knotc zone-unset ${zone} "''${owner}" TXT "''${challenge}" |
23 | ;; | 25 | ;; |
24 | *) | 26 | *) |
25 | exit 2 | 27 | exit 2 |
26 | ;; | 28 | ;; |
27 | esac | 29 | esac |
28 | 30 | ||
29 | knotc zone-commit "${zone}" | 31 | ${knotCfg.cliWrappers}/bin/knotc zone-commit "${zone}" |
30 | ''; | 32 | ''; |
31 | in { | 33 | in { |
32 | config = { | 34 | config = { |
diff --git a/modules/knot.nix b/modules/knot.nix new file mode 100644 index 00000000..a4691324 --- /dev/null +++ b/modules/knot.nix | |||
@@ -0,0 +1,126 @@ | |||
1 | { config, lib, pkgs, ... }: | ||
2 | |||
3 | with lib; | ||
4 | |||
5 | let | ||
6 | cfg = config.services.knot; | ||
7 | |||
8 | configFile = pkgs.writeTextFile { | ||
9 | name = "knot.conf"; | ||
10 | text = (concatMapStringsSep "\n" (file: "include: ${file}") cfg.keyFiles) + "\n" + | ||
11 | cfg.extraConfig; | ||
12 | checkPhase = lib.optionalString (cfg.keyFiles == []) '' | ||
13 | ${cfg.package}/bin/knotc --config=$out conf-check | ||
14 | ''; | ||
15 | }; | ||
16 | |||
17 | socketFile = "/run/knot/knot.sock"; | ||
18 | |||
19 | knot-cli-wrappers = pkgs.stdenv.mkDerivation { | ||
20 | name = "knot-cli-wrappers"; | ||
21 | buildInputs = [ pkgs.makeWrapper ]; | ||
22 | buildCommand = '' | ||
23 | mkdir -p $out/bin | ||
24 | makeWrapper ${cfg.package}/bin/knotc "$out/bin/knotc" \ | ||
25 | --add-flags "--config=${configFile}" \ | ||
26 | --add-flags "--socket=${socketFile}" | ||
27 | makeWrapper ${cfg.package}/bin/keymgr "$out/bin/keymgr" \ | ||
28 | --add-flags "--config=${configFile}" | ||
29 | for executable in kdig khost kjournalprint knsec3hash knsupdate kzonecheck | ||
30 | do | ||
31 | ln -s "${cfg.package}/bin/$executable" "$out/bin/$executable" | ||
32 | done | ||
33 | mkdir -p "$out/share" | ||
34 | ln -s '${cfg.package}/share/man' "$out/share/" | ||
35 | ''; | ||
36 | }; | ||
37 | in { | ||
38 | disabledModules = [ "services/networking/knot.nix" ]; | ||
39 | |||
40 | options = { | ||
41 | services.knot = { | ||
42 | enable = mkEnableOption "Knot authoritative-only DNS server"; | ||
43 | |||
44 | extraArgs = mkOption { | ||
45 | type = types.listOf types.str; | ||
46 | default = []; | ||
47 | description = '' | ||
48 | List of additional command line paramters for knotd | ||
49 | ''; | ||
50 | }; | ||
51 | |||
52 | keyFiles = mkOption { | ||
53 | type = types.listOf types.path; | ||
54 | default = []; | ||
55 | description = '' | ||
56 | A list of files containing additional configuration | ||
57 | to be included using the include directive. This option | ||
58 | allows to include configuration like TSIG keys without | ||
59 | exposing them to the nix store readable to any process. | ||
60 | Note that using this option will also disable configuration | ||
61 | checks at build time. | ||
62 | ''; | ||
63 | }; | ||
64 | |||
65 | extraConfig = mkOption { | ||
66 | type = types.lines; | ||
67 | default = ""; | ||
68 | description = '' | ||
69 | Extra lines to be added verbatim to knot.conf | ||
70 | ''; | ||
71 | }; | ||
72 | |||
73 | package = mkOption { | ||
74 | type = types.package; | ||
75 | default = pkgs.knot-dns; | ||
76 | defaultText = "pkgs.knot-dns"; | ||
77 | description = '' | ||
78 | Which Knot DNS package to use | ||
79 | ''; | ||
80 | }; | ||
81 | |||
82 | cliWrappers = mkOption { | ||
83 | readOnly = true; | ||
84 | type = types.package; | ||
85 | default = knot-cli-wrappers; | ||
86 | defaultText = "knot-cli-wrappers"; | ||
87 | }; | ||
88 | }; | ||
89 | }; | ||
90 | |||
91 | config = mkIf cfg.enable { | ||
92 | users.users.knot = { | ||
93 | isSystemUser = true; | ||
94 | group = "knot"; | ||
95 | description = "Knot daemon user"; | ||
96 | }; | ||
97 | |||
98 | users.groups.knot.gid = null; | ||
99 | systemd.services.knot = { | ||
100 | unitConfig.Documentation = "man:knotd(8) man:knot.conf(5) man:knotc(8) https://www.knot-dns.cz/docs/${cfg.package.version}/html/"; | ||
101 | description = cfg.package.meta.description; | ||
102 | wantedBy = [ "multi-user.target" ]; | ||
103 | wants = [ "network.target" ]; | ||
104 | after = ["network.target" ]; | ||
105 | |||
106 | serviceConfig = { | ||
107 | Type = "notify"; | ||
108 | ExecStart = "${cfg.package}/bin/knotd --config=${configFile} --socket=${socketFile} ${concatStringsSep " " cfg.extraArgs}"; | ||
109 | ExecReload = "${cfg.cliWrappers}/bin/knotc reload"; | ||
110 | CapabilityBoundingSet = "CAP_NET_BIND_SERVICE CAP_SETPCAP"; | ||
111 | AmbientCapabilities = "CAP_NET_BIND_SERVICE CAP_SETPCAP"; | ||
112 | NoNewPrivileges = true; | ||
113 | User = "knot"; | ||
114 | RuntimeDirectory = "knot"; | ||
115 | StateDirectory = "knot"; | ||
116 | StateDirectoryMode = "0700"; | ||
117 | PrivateDevices = true; | ||
118 | RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6"; | ||
119 | SystemCallArchitectures = "native"; | ||
120 | Restart = "on-abort"; | ||
121 | }; | ||
122 | }; | ||
123 | |||
124 | environment.systemPackages = [ cfg.cliWrappers ]; | ||
125 | }; | ||
126 | } | ||