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