]> Git — Sourcephile - sourcephile-nix.git/blob - hosts/mermet/knot.nix
upnpc: add miniupnpc in the environment
[sourcephile-nix.git] / hosts / mermet / knot.nix
1 { pkgs, lib, config, info, ... }:
2 let
3 inherit (lib) types;
4 inherit (config.services) knot;
5 inherit (config.users) users groups;
6 settingsFormat = pkgs.formats.yaml { };
7 in
8 {
9 imports = [
10 knot/autogeree.net.nix
11 knot/sourcephile.fr.nix
12 ];
13 options.services.knot = {
14 # WARNING: multiple settings do not merge yet
15 # https://github.com/NixOS/nixpkgs/pull/81460#pullrequestreview-1793815097
16 settingsFreeform = lib.mkOption {
17 type = types.submodule {
18 freeformType = settingsFormat.type;
19 };
20 default = { };
21 description = "";
22 };
23 zones = lib.mkOption {
24 default = { };
25 type = types.attrsOf (types.submodule ({ ... }: {
26 #config.domain = lib.mkDefault name;
27 options = {
28 data = lib.mkOption {
29 type = types.nullOr types.lines;
30 };
31 };
32 }));
33 };
34 };
35 config = {
36 systemd.services.knot.serviceConfig.ExecStartPre =
37 lib.mapAttrsToList
38 (domain: { data, ... }: ''
39 +${pkgs.coreutils}/bin/install -D -o ${users.knot.name} -g ${groups."knot".name} -m 700 \
40 ${pkgs.writeText "${domain}.zone" data} \
41 /var/lib/knot/zones/${domain}.zone
42 '')
43 knot.zones;
44 /*
45 systemd.services.knot.postStart = lib.mkAfter ''
46 PATH="/run/current-system/sw/bin:$PATH"
47 knotc zone-freeze ${domain}.
48 while ! knotc zone-status ${domain}. +freeze | grep -q 'freeze: yes'; do sleep 1; done
49 knotc zone-flush ${domain}.
50 install -o knot -g knot -m 700 ${zone} /var/lib/knot/signed/${domain}.zone
51 knotc zone-reload ${domain}.
52 knotc zone-thaw ${domain}.
53 '';
54 */
55 networking.nftables.ruleset = ''
56 table inet filter {
57 chain input-net {
58 meta l4proto { udp, tcp } th dport domain counter accept comment "knot: DNS"
59 }
60 set output-net-knot-ipv4 { type ipv4_addr; }
61 set output-net-knot-ipv6 { type ipv6_addr; }
62 chain output-net {
63 skuid ${users.knot.name} \
64 meta l4proto { udp, tcp } th dport domain \
65 ip daddr @output-net-knot-ipv4 \
66 counter accept \
67 comment "knot: DNS notify"
68 skuid ${users.knot.name} \
69 meta l4proto { udp, tcp } th dport domain \
70 ip6 daddr @output-net-knot-ipv6 \
71 counter accept \
72 comment "knot: DNS notify"
73 }
74 }
75 '';
76 services.knot = {
77 enable = true;
78 extraArgs = [ "-v" ];
79 # https://www.knot-dns.cz/docs/2.6/html/reference.html
80 settingsFreeform = {
81 server.listen = [
82 # Listen on localhost to allow only there
83 # dynamic updates for ACME challenges.
84 "127.0.0.1@5353"
85 ];
86 template.default = {
87 dnssec-signing = false;
88 # move databases below the state directory, because they need to be writable
89 storage = "/var/lib/knot/zones";
90 # Input-only zone files
91 # https://www.knot-dns.cz/docs/2.8/html/operation.html#example-3
92 # prevents modification of the zonefiles, since the zonefiles are immutable
93 #zonefile-sync: -1
94 zonefile-load = "difference";
95 journal-content = "changes";
96 global-module = "mod-rrl/default";
97 };
98 mod-rrl.default = {
99 rate-limit = 200;
100 slip = 2;
101 };
102 database = {
103 journal-db = "/var/lib/knot/journal";
104 kasp-db = "/var/lib/knot/kasp";
105 timer-db = "/var/lib/knot/timer";
106 };
107 log.syslog.any = "info";
108 remote.local_resolver.address = "127.0.0.1@53";
109 remote.secondary_gandi.address = "${info.gandi.dns.secondary.axfr.ipv4}@53";
110 remote.secondary_muarf.address = "78.192.65.63@53";
111 submission.dnssec_validating_resolver = {
112 parent = "local_resolver";
113 };
114 policy.rsa = {
115 single-type-signing = false;
116 ksk-shared = false;
117 algorithm = "RSASHA256";
118 ksk-size = 4096;
119 zsk-size = 2048;
120 zsk-lifetime = "30d";
121 ksk-lifetime = "365d";
122 ksk-submission = "dnssec_validating_resolver";
123 };
124 policy.ed25519 = {
125 single-type-signing = false;
126 ksk-shared = false;
127 algorithm = "ED25519";
128 ksk-size = 256;
129 zsk-size = 256;
130 zsk-lifetime = "30d";
131 ksk-lifetime = "365d";
132 cds-cdnskey-publish = "always";
133 ksk-submission = "dnssec_validating_resolver";
134 };
135 acl.acl_gandi = {
136 address = info.gandi.dns.secondary.axfr.ipv4;
137 action = "transfer";
138 };
139 acl.acl_muarf = {
140 address = "78.192.65.63";
141 action = "transfer";
142 };
143 };
144 settings = knot.settingsFreeform;
145 };
146 };
147 }