···
1
-
import ./make-test-python.nix (
5
-
networking.firewall.enable = false;
6
-
networking.useDHCP = false;
8
-
exampleZone = pkgs.writeTextDir "example.com.zone" ''
9
-
@ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800
17
-
www AAAA 2001:DB8::1
18
-
sub NS ns.example.com.
20
-
delegatedZone = pkgs.writeTextDir "sub.example.com.zone" ''
21
-
@ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800
22
-
@ NS ns1.example.com.
23
-
@ NS ns2.example.com.
8
+
networking.firewall.enable = false;
9
+
networking.useDHCP = false;
11
+
exampleZone = pkgs.writeTextDir "example.com.zone" ''
12
+
@ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800
20
+
www AAAA 2001:DB8::1
21
+
sub NS ns.example.com.
23
+
delegatedZone = pkgs.writeTextDir "sub.example.com.zone" ''
24
+
@ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800
25
+
@ NS ns1.example.com.
26
+
@ NS ns2.example.com.
28
-
knotZonesEnv = pkgs.buildEnv {
29
-
name = "knot-zones";
35
-
# DO NOT USE pkgs.writeText IN PRODUCTION. This put secrets in the nix store!
36
-
tsigFile = pkgs.writeText "tsig.conf" ''
39
-
algorithm: hmac-sha256
40
-
secret: zOYgOgnzx3TGe5J5I/0kxd7gTcxXhLYMEq3Ek3fY37s=
45
-
meta = with pkgs.lib.maintainers; {
46
-
maintainers = [ hexa ];
31
+
knotZonesEnv = pkgs.buildEnv {
32
+
name = "knot-zones";
38
+
# DO NOT USE pkgs.writeText IN PRODUCTION. This put secrets in the nix store!
39
+
tsigFile = pkgs.writeText "tsig.conf" ''
42
+
algorithm: hmac-sha256
43
+
secret: zOYgOgnzx3TGe5J5I/0kxd7gTcxXhLYMEq3Ek3fY37s=
48
+
meta = with pkgs.lib.maintainers; {
49
+
maintainers = [ hexa ];
53
-
imports = [ common ];
56
+
imports = [ common ];
55
-
# trigger sched_setaffinity syscall
56
-
virtualisation.cores = 2;
58
+
# trigger sched_setaffinity syscall
59
+
virtualisation.cores = 2;
58
-
networking.interfaces.eth1 = {
59
-
ipv4.addresses = lib.mkForce [
61
-
address = "192.168.0.1";
61
+
networking.interfaces.eth1 = {
62
+
ipv4.addresses = lib.mkForce [
64
+
address = "192.168.0.1";
68
+
ipv6.addresses = lib.mkForce [
70
+
address = "fd00::1";
75
+
services.knot.enable = true;
76
+
services.knot.extraArgs = [ "-v" ];
77
+
services.knot.keyFiles = [ tsigFile ];
78
+
services.knot.settings = {
65
-
ipv6.addresses = lib.mkForce [
67
-
address = "fd00::1";
88
+
automatic-acl = true;
72
-
services.knot.enable = true;
73
-
services.knot.extraArgs = [ "-v" ];
74
-
services.knot.keyFiles = [ tsigFile ];
75
-
services.knot.settings = {
85
-
automatic-acl = true;
88
-
acl.secondary_acl = {
89
-
address = "192.168.0.2";
91
-
action = "transfer";
91
+
acl.secondary_acl = {
92
+
address = "192.168.0.2";
94
+
action = "transfer";
94
-
remote.secondary.address = "192.168.0.2@53";
97
+
remote.secondary.address = "192.168.0.2@53";
96
-
template.default = {
97
-
storage = knotZonesEnv;
98
-
notify = [ "secondary" ];
99
-
acl = [ "secondary_acl" ];
100
-
dnssec-signing = true;
101
-
# Input-only zone files
102
-
# https://www.knot-dns.cz/docs/2.8/html/operation.html#example-3
103
-
# prevents modification of the zonefiles, since the zonefiles are immutable
104
-
zonefile-sync = -1;
105
-
zonefile-load = "difference";
106
-
journal-content = "changes";
110
-
"example.com".file = "example.com.zone";
111
-
"sub.example.com".file = "sub.example.com.zone";
99
+
template.default = {
100
+
storage = knotZonesEnv;
101
+
notify = [ "secondary" ];
102
+
acl = [ "secondary_acl" ];
103
+
dnssec-signing = true;
104
+
# Input-only zone files
105
+
# https://www.knot-dns.cz/docs/2.8/html/operation.html#example-3
106
+
# prevents modification of the zonefiles, since the zonefiles are immutable
107
+
zonefile-sync = -1;
108
+
zonefile-load = "difference";
109
+
journal-content = "changes";
114
-
log.syslog.any = "info";
113
+
"example.com".file = "example.com.zone";
114
+
"sub.example.com".file = "sub.example.com.zone";
117
+
log.syslog.any = "info";
121
-
imports = [ common ];
122
-
networking.interfaces.eth1 = {
123
-
ipv4.addresses = lib.mkForce [
125
-
address = "192.168.0.2";
129
-
ipv6.addresses = lib.mkForce [
131
-
address = "fd00::2";
124
+
imports = [ common ];
125
+
networking.interfaces.eth1 = {
126
+
ipv4.addresses = lib.mkForce [
128
+
address = "192.168.0.2";
132
+
ipv6.addresses = lib.mkForce [
134
+
address = "fd00::2";
139
+
services.knot.enable = true;
140
+
services.knot.keyFiles = [ tsigFile ];
141
+
services.knot.extraArgs = [ "-v" ];
142
+
services.knot.settings = {
144
+
automatic-acl = true;
136
-
services.knot.enable = true;
137
-
services.knot.keyFiles = [ tsigFile ];
138
-
services.knot.extraArgs = [ "-v" ];
139
-
services.knot.settings = {
141
-
automatic-acl = true;
155
+
address = "192.168.0.1@53";
152
-
address = "192.168.0.1@53";
159
+
remote.primary-quic = {
160
+
address = "192.168.0.1@853";
156
-
remote.primary-quic = {
157
-
address = "192.168.0.1@853";
165
+
template.default = {
166
+
# zonefileless setup
167
+
# https://www.knot-dns.cz/docs/2.8/html/operation.html#example-2
168
+
zonefile-sync = "-1";
169
+
zonefile-load = "none";
170
+
journal-content = "all";
162
-
template.default = {
163
-
# zonefileless setup
164
-
# https://www.knot-dns.cz/docs/2.8/html/operation.html#example-2
165
-
zonefile-sync = "-1";
166
-
zonefile-load = "none";
167
-
journal-content = "all";
175
+
master = "primary";
176
+
file = "example.com.zone";
172
-
master = "primary";
173
-
file = "example.com.zone";
175
-
"sub.example.com" = {
176
-
master = "primary-quic";
177
-
file = "sub.example.com.zone";
178
+
"sub.example.com" = {
179
+
master = "primary-quic";
180
+
file = "sub.example.com.zone";
181
-
log.syslog.any = "debug";
184
+
log.syslog.any = "debug";
185
-
{ lib, nodes, ... }:
187
-
imports = [ common ];
188
-
networking.interfaces.eth1 = {
191
-
address = "192.168.0.3";
197
-
address = "fd00::3";
202
-
environment.systemPackages = [ pkgs.knot-dns ];
188
+
{ lib, nodes, ... }:
190
+
imports = [ common ];
191
+
networking.interfaces.eth1 = {
194
+
address = "192.168.0.3";
200
+
address = "fd00::3";
205
+
environment.systemPackages = [ pkgs.knot-dns ];
209
-
primary4 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv4.addresses).address;
210
-
primary6 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv6.addresses).address;
212
+
primary4 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv4.addresses).address;
213
+
primary6 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv6.addresses).address;
212
-
secondary4 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv4.addresses).address;
213
-
secondary6 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv6.addresses).address;
215
+
secondary4 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv4.addresses).address;
216
+
secondary6 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv6.addresses).address;
220
-
client.wait_for_unit("network.target")
221
-
primary.wait_for_unit("knot.service")
222
-
secondary.wait_for_unit("knot.service")
223
+
client.wait_for_unit("network.target")
224
+
primary.wait_for_unit("knot.service")
225
+
secondary.wait_for_unit("knot.service")
224
-
for zone in ("example.com.", "sub.example.com."):
225
-
secondary.wait_until_succeeds(
226
-
f"knotc zone-status {zone} | grep -q 'serial: 2019031302'"
227
+
for zone in ("example.com.", "sub.example.com."):
228
+
secondary.wait_until_succeeds(
229
+
f"knotc zone-status {zone} | grep -q 'serial: 2019031302'"
229
-
def test(host, query_type, query, pattern):
230
-
out = client.succeed(f"khost -t {query_type} {query} {host}").strip()
231
-
client.log(f"{host} replied with: {out}")
232
-
assert re.search(pattern, out), f'Did not match "{pattern}"'
232
+
def test(host, query_type, query, pattern):
233
+
out = client.succeed(f"khost -t {query_type} {query} {host}").strip()
234
+
client.log(f"{host} replied with: {out}")
235
+
assert re.search(pattern, out), f'Did not match "{pattern}"'
235
-
for host in ("${primary4}", "${primary6}", "${secondary4}", "${secondary6}"):
236
-
with subtest(f"Interrogate {host}"):
237
-
test(host, "SOA", "example.com", r"start of authority.*noc\.example\.com\.")
238
-
test(host, "A", "example.com", r"has no [^ ]+ record")
239
-
test(host, "AAAA", "example.com", r"has no [^ ]+ record")
238
+
for host in ("${primary4}", "${primary6}", "${secondary4}", "${secondary6}"):
239
+
with subtest(f"Interrogate {host}"):
240
+
test(host, "SOA", "example.com", r"start of authority.*noc\.example\.com\.")
241
+
test(host, "A", "example.com", r"has no [^ ]+ record")
242
+
test(host, "AAAA", "example.com", r"has no [^ ]+ record")
241
-
test(host, "A", "www.example.com", r"address 192.0.2.1$")
242
-
test(host, "AAAA", "www.example.com", r"address 2001:db8::1$")
244
+
test(host, "A", "www.example.com", r"address 192.0.2.1$")
245
+
test(host, "AAAA", "www.example.com", r"address 2001:db8::1$")
244
-
test(host, "NS", "sub.example.com", r"nameserver is ns\d\.example\.com.$")
245
-
test(host, "A", "sub.example.com", r"address 192.0.2.2$")
246
-
test(host, "AAAA", "sub.example.com", r"address 2001:db8::2$")
247
+
test(host, "NS", "sub.example.com", r"nameserver is ns\d\.example\.com.$")
248
+
test(host, "A", "sub.example.com", r"address 192.0.2.2$")
249
+
test(host, "AAAA", "sub.example.com", r"address 2001:db8::2$")
248
-
test(host, "RRSIG", "www.example.com", r"RR set signature is")
249
-
test(host, "DNSKEY", "example.com", r"DNSSEC key is")
251
+
test(host, "RRSIG", "www.example.com", r"RR set signature is")
252
+
test(host, "DNSKEY", "example.com", r"DNSSEC key is")
251
-
primary.log(primary.succeed("systemd-analyze security knot.service | grep -v '✓'"))
254
+
primary.log(primary.succeed("systemd-analyze security knot.service | grep -v '✓'"))