forked from
lass.pds.lassul.us/superconfig
This repository has no description
6.0 kB
227 lines
1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 ip4 = "95.217.192.59";
9 ip6 = "2a01:4f9:4a:4f1a::2";
10 # Delegated from lassul.us (NS ns1 only, the Hetzner secondaries never see
11 # them) so lego can do DNS-01 for *.review.lassul.us (configs/crit-proxy.nix)
12 # and *.pds.lassul.us (configs/services/git/pds.nix) with RFC2136 updates,
13 # without touching the signed main zone.
14 acmeZone = domain: {
15 inherit domain;
16 file = "${pkgs.writeText "${domain}.zone" ''
17 @ 3600 IN SOA ns1.lassul.us. acme.lassul.us. 1 7200 3600 86400 60
18 @ 3600 IN NS ns1.lassul.us.
19 ''}";
20 acl = [ "acme_review" ];
21 zonefile-sync = "-1";
22 zonefile-load = "difference-no-serial";
23 journal-content = "all";
24 };
25 # dyndns = domain:
26 # pkgs.writeText "${domain}.zone" ''
27 # @ 3600 IN SOA ${domain}. ns1.lassul.us. 2023101213 7200 3600 86400 3600
28
29 # $TTL 300
30
31in
32# @ IN NS ns1.lassul.us.
33# '';
34{
35 # TSIG key for the acme-review updates, for knot and for lego
36 clan.core.vars.generators.knot-acme-review = {
37 files."knot-key.conf".owner = "knot";
38 files."lego.env".owner = "acme";
39 runtimeInputs = [ pkgs.openssl ];
40 script = ''
41 secret=$(openssl rand -base64 32)
42 printf 'key:\n - id: acme-review\n algorithm: hmac-sha256\n secret: %s\n' "$secret" \
43 > "$out/knot-key.conf"
44 printf 'RFC2136_NAMESERVER=%s\nRFC2136_TSIG_ALGORITHM=hmac-sha256.\nRFC2136_TSIG_KEY=acme-review\nRFC2136_TSIG_SECRET=%s\n' \
45 ${ip4} "$secret" > "$out/lego.env"
46 '';
47 };
48
49 services.knot = {
50 enable = true;
51 keyFiles = [
52 config.clan.core.vars.generators.knot-acme-review.files."knot-key.conf".path
53 ];
54 settings = {
55 server = {
56 listen = [
57 "${ip4}@53"
58 "${ip6}@53"
59 ];
60 };
61
62 remote = [
63 {
64 id = "hetzner_ip4_1";
65 address = "213.239.242.238@53";
66 }
67 {
68 id = "hetzner_ip4_2";
69 address = "213.133.100.103@53";
70 }
71 {
72 id = "hetzner_ip4_3";
73 address = "193.47.99.3@53";
74 }
75 {
76 id = "hetzner_ip6_1";
77 address = "2a01:4f8:0:a101::a:1@53";
78 }
79 {
80 id = "hetzner_ip6_2";
81 address = "2a01:4f8:0:1::5ddc:2@53";
82 }
83 {
84 id = "hetzner_ip6_3";
85 address = "2001:67c:192c::add:a3";
86 }
87 ];
88
89 # to generate TSIG key
90 # for i in host; do keymgr -t $i; done
91 acl = [
92 {
93 id = "hetzner_ip4_1";
94 address = "213.239.242.238";
95 action = "transfer";
96 }
97 {
98 id = "hetzner_ip4_2";
99 address = "213.133.100.103";
100 action = "transfer";
101 }
102 {
103 id = "hetzner_ip4_3";
104 address = "193.47.99.3";
105 action = "transfer";
106 }
107 {
108 id = "hetzner_ip6_1";
109 address = "2a01:4f8:0:a101::a:1";
110 action = "transfer";
111 }
112 {
113 id = "hetzner_ip6_2";
114 address = "2a01:4f8:0:1::5ddc:2";
115 action = "transfer";
116 }
117 {
118 id = "hetzner_ip6_3";
119 address = "2001:67c:192c::add:a3";
120 action = "transfer";
121 }
122 {
123 id = "acme_review";
124 key = "acme-review";
125 address = [
126 ip4
127 ip6
128 ];
129 action = "update";
130 update-type = [ "TXT" ];
131 }
132 ];
133
134 mod-rrl = [
135 {
136 id = "default";
137 rate-limit = 200;
138 slip = 2;
139 }
140 ];
141
142 policy = [
143 {
144 id = "rsa2k";
145 algorithm = "RSASHA256";
146 ksk-size = 4096;
147 zsk-size = 2048;
148 nsec3 = true;
149 }
150 ];
151
152 template = [
153 {
154 id = "default";
155 semantic-checks = "on";
156 global-module = "mod-rrl/default";
157 }
158 {
159 id = "master";
160 semantic-checks = "on";
161 notify = [
162 "hetzner_ip4_1"
163 "hetzner_ip4_2"
164 "hetzner_ip4_3"
165 "hetzner_ip6_1"
166 "hetzner_ip6_2"
167 "hetzner_ip6_3"
168 ];
169 acl = [
170 "hetzner_ip4_1"
171 "hetzner_ip4_2"
172 "hetzner_ip4_3"
173 "hetzner_ip6_1"
174 "hetzner_ip6_2"
175 "hetzner_ip6_3"
176 ];
177 zonefile-sync = "-1";
178 zonefile-load = "difference-no-serial";
179 serial-policy = "dateserial";
180 journal-content = "all";
181 }
182 ];
183
184 zone = [
185 {
186 domain = "lassul.us";
187 file = "${./lassul.us.zone}";
188 notify = [
189 "hetzner_ip4_1"
190 "hetzner_ip4_2"
191 "hetzner_ip4_3"
192 "hetzner_ip6_1"
193 "hetzner_ip6_2"
194 "hetzner_ip6_3"
195 ];
196 acl = [
197 "hetzner_ip4_1"
198 "hetzner_ip4_2"
199 "hetzner_ip4_3"
200 "hetzner_ip6_1"
201 "hetzner_ip6_2"
202 "hetzner_ip6_3"
203 ];
204 dnssec-signing = true;
205 dnssec-policy = "rsa2k";
206 # Disable zone file syncing since the zone file is in the read-only Nix store
207 # This prevents "flush event failed" errors when knot tries to write DNSSEC updates
208 zonefile-sync = "-1";
209 # Load zone changes from journal instead of rewriting the zone file
210 # Required when DNSSEC signing is enabled with read-only zone files
211 # Use difference-no-serial to auto-increment serial based on serial-policy
212 zonefile-load = "difference-no-serial";
213 serial-policy = "dateserial";
214 journal-content = "all";
215 }
216 (acmeZone "_acme-challenge.review.lassul.us")
217 (acmeZone "_acme-challenge.pds.lassul.us")
218 ];
219 };
220 };
221
222 # disable to enable auto key generation
223 systemd.services.knot.serviceConfig.SystemCallFilter = lib.mkForce [ ];
224
225 networking.firewall.allowedTCPPorts = [ 53 ];
226 networking.firewall.allowedUDPPorts = [ 53 ];
227}