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