diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2023-10-10 10:44:24 +0200 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2023-10-12 00:24:46 +0200 |
commit | 97787a9dd8b136c8dc327fab42aedf2aa1109ec0 (patch) | |
tree | 4b7ea0d889a4c2c27bfec351693995f1fcba2bbb /systems/eldiron | |
parent | 450e0db1a1ad900f93519c00f0ef132ec42a3728 (diff) | |
download | Nix-97787a9dd8b136c8dc327fab42aedf2aa1109ec0.tar.gz Nix-97787a9dd8b136c8dc327fab42aedf2aa1109ec0.tar.zst Nix-97787a9dd8b136c8dc327fab42aedf2aa1109ec0.zip |
Add dnssec
Diffstat (limited to 'systems/eldiron')
-rw-r--r-- | systems/eldiron/dns.nix | 117 | ||||
-rw-r--r-- | systems/eldiron/ejabberd/default.nix | 2 | ||||
-rw-r--r-- | systems/eldiron/flake.lock | 2 | ||||
-rw-r--r-- | systems/eldiron/mail/postfix.nix | 4 | ||||
-rw-r--r-- | systems/eldiron/mail/sympa.nix | 2 | ||||
-rw-r--r-- | systems/eldiron/websites/tools/default.nix | 2 |
6 files changed, 93 insertions, 36 deletions
diff --git a/systems/eldiron/dns.nix b/systems/eldiron/dns.nix index 486fcc1..7645b69 100644 --- a/systems/eldiron/dns.nix +++ b/systems/eldiron/dns.nix | |||
@@ -1,4 +1,18 @@ | |||
1 | { lib, pkgs, config, dns-nix, ... }: | 1 | { lib, pkgs, config, dns-nix, ... }: |
2 | let | ||
3 | zonesWithDNSSec = lib.filterAttrs (k: v: v.dnssec.enable) config.myServices.dns.zones; | ||
4 | zoneToFile = name: v: pkgs.runCommand "${name}.zone" { | ||
5 | text = v; | ||
6 | passAsFile = [ "text" ]; | ||
7 | # Automatically change the increment when relevant change | ||
8 | # happened (both serial and mta-sts) | ||
9 | } '' | ||
10 | mv "$textPath" $out | ||
11 | increment=$(( 100*($(date -u +%-H) * 60 + $(date -u +%-M))/1440 )) | ||
12 | sed -i -e "s/2022121902/$(date -u +%Y%m%d)$increment/g" $out | ||
13 | sed -i -e "s/20200109150200Z/$(date -u +%Y%m%d%H%M%SZ)/g" $out | ||
14 | ''; | ||
15 | in | ||
2 | { | 16 | { |
3 | options.myServices.dns = { | 17 | options.myServices.dns = { |
4 | enable = lib.mkEnableOption "enable DNS resolver"; | 18 | enable = lib.mkEnableOption "enable DNS resolver"; |
@@ -11,7 +25,10 @@ | |||
11 | servers = config.myEnv.servers; | 25 | servers = config.myEnv.servers; |
12 | ips = i: { A = i.ip4; AAAA = i.ip6; }; | 26 | ips = i: { A = i.ip4; AAAA = i.ip6; }; |
13 | letsencrypt = [ { tag = "issue"; value = "letsencrypt.org"; issuerCritical = false; } ]; | 27 | letsencrypt = [ { tag = "issue"; value = "letsencrypt.org"; issuerCritical = false; } ]; |
14 | toKV = a: builtins.concatStringsSep ";" (builtins.attrValues (builtins.mapAttrs (n: v: "${n}=${v}") a)); | 28 | toKV = a: let |
29 | removeOrder = n: lib.last (builtins.split "__" n); | ||
30 | in | ||
31 | builtins.concatStringsSep ";" (builtins.attrValues (builtins.mapAttrs (n: v: "${removeOrder n}=${v}") a)); | ||
15 | mailMX = { | 32 | mailMX = { |
16 | hasEmail = true; | 33 | hasEmail = true; |
17 | subdomains = let | 34 | subdomains = let |
@@ -24,10 +41,10 @@ | |||
24 | SOA = { | 41 | SOA = { |
25 | # yyyymmdd?? (increment ?? at each change) | 42 | # yyyymmdd?? (increment ?? at each change) |
26 | serial = 2022121902; # Don't change this value, it is replaced automatically! | 43 | serial = 2022121902; # Don't change this value, it is replaced automatically! |
27 | refresh = 10800; | 44 | refresh = 3*60*60; |
28 | retry = 3600; | 45 | retry = 60*60; |
29 | expire = 604800; | 46 | expire = 14*24*60*60; |
30 | minimum = 10800; # negative cache ttl | 47 | minimum = 3*60*60; # negative cache ttl |
31 | adminEmail = "hostmaster@immae.eu"; #email-address s/@/./ | 48 | adminEmail = "hostmaster@immae.eu"; #email-address s/@/./ |
32 | nameServer = "ns1.immae.eu."; | 49 | nameServer = "ns1.immae.eu."; |
33 | }; | 50 | }; |
@@ -42,7 +59,7 @@ | |||
42 | (toKV config.myEnv.mail.dkim.immae_eu.public) | 59 | (toKV config.myEnv.mail.dkim.immae_eu.public) |
43 | ]; | 60 | ]; |
44 | }; | 61 | }; |
45 | mailCommon = name: { | 62 | mailCommon = name: quarantine: { |
46 | MX = let | 63 | MX = let |
47 | mxes = lib.filterAttrs (n: v: v ? mx && v.mx.enable) servers; | 64 | mxes = lib.filterAttrs (n: v: v ? mx && v.mx.enable) servers; |
48 | in | 65 | in |
@@ -65,16 +82,17 @@ | |||
65 | # MTA-STS | 82 | # MTA-STS |
66 | # https://blog.delouw.ch/2018/12/16/using-mta-sts-to-enhance-email-transport-security-and-privacy/ | 83 | # https://blog.delouw.ch/2018/12/16/using-mta-sts-to-enhance-email-transport-security-and-privacy/ |
67 | # https://support.google.com/a/answer/9261504 | 84 | # https://support.google.com/a/answer/9261504 |
68 | _mta-sts.TXT = [ (toKV { v = "STSv1"; id = "20200109150200Z"; }) ]; # Don't change this value, it is updated automatically! | 85 | _mta-sts.TXT = [ (toKV { _00__v = "STSv1"; id = "20200109150200Z"; }) ]; # Don't change this value, it is updated automatically! |
69 | _tls.subdomains._smtp.TXT = [ (toKV { v = "TLSRPTv1"; "rua" = "mailto:postmaster+mta-sts@immae.eu"; }) ]; | 86 | _tls.subdomains._smtp.TXT = [ (toKV { _00__v = "TLSRPTv1"; rua = "mailto:postmaster+mta-sts@immae.eu"; }) ]; |
70 | mta-sts = ips servers.eldiron.ips.main; | 87 | mta-sts = ips servers.eldiron.ips.main; |
71 | 88 | ||
72 | # DMARC | 89 | # DMARC |
73 | _dmarc.TXT = [ (toKV { v = "DMARC1"; p = "none"; adkim = "r"; aspf = "r"; fo = "1"; rua = "mailto:postmaster+rua@immae.eu"; ruf = "mailto:postmaster+ruf@immae.eu"; }) ]; | 90 | # p needs to be the first tag |
91 | _dmarc.TXT = [ (toKV { _00__v = "DMARC1"; _01__p = if quarantine then "quarantine" else "none"; adkim = "s"; aspf = "s"; fo = "1"; rua = "mailto:postmaster+rua@immae.eu"; ruf = "mailto:postmaster+ruf@immae.eu"; }) ]; | ||
74 | }; | 92 | }; |
75 | 93 | ||
76 | # SPF | 94 | # SPF |
77 | TXT = [ (toKV { v = "spf1 mx ~all"; }) ]; | 95 | TXT = [ (toKV { _00__v = "spf1 mx ~all"; }) ]; |
78 | }; | 96 | }; |
79 | }; | 97 | }; |
80 | }; | 98 | }; |
@@ -83,6 +101,14 @@ | |||
83 | dns-nix.lib.types.zone.getSubModules ++ [ | 101 | dns-nix.lib.types.zone.getSubModules ++ [ |
84 | ({ name, ... }: { | 102 | ({ name, ... }: { |
85 | options = { | 103 | options = { |
104 | dnssec = lib.mkOption { | ||
105 | default.enable = false; | ||
106 | type = lib.types.submodule { | ||
107 | options = { | ||
108 | enable = lib.mkEnableOption "Configure dnssec for this domain"; | ||
109 | }; | ||
110 | }; | ||
111 | }; | ||
86 | hasEmail = lib.mkEnableOption "This domain has e-mails configuration"; | 112 | hasEmail = lib.mkEnableOption "This domain has e-mails configuration"; |
87 | emailPolicies = lib.mkOption { | 113 | emailPolicies = lib.mkOption { |
88 | default = {}; | 114 | default = {}; |
@@ -154,12 +180,18 @@ | |||
154 | zoneHeader | 180 | zoneHeader |
155 | (ips servers.eldiron.ips.main) | 181 | (ips servers.eldiron.ips.main) |
156 | { | 182 | { |
157 | ns = [ "immae" ]; | 183 | dnssec.enable = true; |
184 | ns = [ "immae" "raito" ]; | ||
158 | CAA = letsencrypt; | 185 | CAA = letsencrypt; |
186 | extraConfig = '' | ||
187 | notify yes; | ||
188 | ''; | ||
189 | slaves = [ "raito" ]; | ||
159 | } | 190 | } |
160 | ]; | 191 | ]; |
161 | "immae.dev" = lib.mkMerge [ | 192 | "immae.dev" = lib.mkMerge [ |
162 | { | 193 | { |
194 | dnssec.enable = true; | ||
163 | extraConfig = '' | 195 | extraConfig = '' |
164 | notify yes; | 196 | notify yes; |
165 | ''; | 197 | ''; |
@@ -174,6 +206,7 @@ | |||
174 | ]; | 206 | ]; |
175 | "immae.eu" = lib.mkMerge [ | 207 | "immae.eu" = lib.mkMerge [ |
176 | { | 208 | { |
209 | dnssec.enable = true; | ||
177 | extraConfig = '' | 210 | extraConfig = '' |
178 | notify yes; | 211 | notify yes; |
179 | ''; | 212 | ''; |
@@ -182,7 +215,10 @@ | |||
182 | zoneHeader | 215 | zoneHeader |
183 | (ips servers.eldiron.ips.production) | 216 | (ips servers.eldiron.ips.production) |
184 | { | 217 | { |
185 | ns = [ "immae" "raito" ]; | 218 | ns = [ "immae" ]; |
219 | # Cannot put ns2.immae.eu as glue record as it takes ages to propagate. | ||
220 | # And gandi only accepts NS records with glues in their interface | ||
221 | NS = [ "kurisu.dual.lahfa.xyz." ]; | ||
186 | CAA = letsencrypt; | 222 | CAA = letsencrypt; |
187 | 223 | ||
188 | # ns1 has glue records in gandi.net | 224 | # ns1 has glue records in gandi.net |
@@ -194,9 +230,9 @@ | |||
194 | { | 230 | { |
195 | # Machines local users | 231 | # Machines local users |
196 | emailPolicies.localhost.receive = false; | 232 | emailPolicies.localhost.receive = false; |
197 | subdomains.localhost = lib.mkMerge [ (mailCommon "immae.eu") mailSend ]; | 233 | subdomains.localhost = lib.mkMerge [ (mailCommon "immae.eu" true) mailSend ]; |
198 | emailPolicies.eldiron.receive = true; | 234 | emailPolicies.eldiron.receive = true; |
199 | subdomains.eldiron = lib.mkMerge [ (mailCommon "immae.eu") mailSend ]; | 235 | subdomains.eldiron = lib.mkMerge [ (mailCommon "immae.eu" true) mailSend ]; |
200 | } | 236 | } |
201 | { | 237 | { |
202 | # For each server "server" and each server ip group "ipgroup", | 238 | # For each server "server" and each server ip group "ipgroup", |
@@ -248,23 +284,24 @@ | |||
248 | zones = | 284 | zones = |
249 | builtins.mapAttrs (name: v: { | 285 | builtins.mapAttrs (name: v: { |
250 | master = true; | 286 | master = true; |
251 | extraConfig = v.extraConfig; | 287 | extraConfig = v.extraConfig + lib.optionalString v.dnssec.enable '' |
288 | key-directory "/var/lib/named/dnssec_keys"; | ||
289 | dnssec-policy default; | ||
290 | inline-signing yes; | ||
291 | ''; | ||
252 | masters = []; | 292 | masters = []; |
253 | slaves = | 293 | slaves = |
254 | lib.flatten (map (n: builtins.attrValues config.myEnv.dns.ns.${n}) v.slaves); | 294 | lib.flatten (map (n: builtins.attrValues config.myEnv.dns.ns.${n}) v.slaves); |
255 | file = pkgs.runCommand "${name}.zone" { | 295 | file = if v.dnssec.enable then "/var/run/named/dnssec-${name}.zone" else zoneToFile name v; |
256 | text = v; | ||
257 | passAsFile = [ "text" ]; | ||
258 | # Automatically change the increment when relevant change | ||
259 | # happened (both serial and mta-sts) | ||
260 | } '' | ||
261 | mv "$textPath" $out | ||
262 | increment=$(( 100*($(date -u +%-H) * 60 + $(date -u +%-M))/1440 )) | ||
263 | sed -i -e "s/2022121902/$(date -u +%Y%m%d)$increment/g" $out | ||
264 | sed -i -e "s/20200109150200Z/$(date -u +%Y%m%d%H%M%SZ)/g" $out | ||
265 | ''; | ||
266 | }) config.myServices.dns.zones; | 296 | }) config.myServices.dns.zones; |
267 | }; | 297 | }; |
298 | systemd.services.bind.serviceConfig.StateDirectory = "named"; | ||
299 | systemd.services.bind.preStart = lib.mkAfter | ||
300 | (builtins.concatStringsSep "\n" (lib.mapAttrsToList (name: v: '' | ||
301 | install -m444 ${zoneToFile name v} /var/run/named/dnssec-${name}.zone | ||
302 | '') zonesWithDNSSec) + '' | ||
303 | install -dm755 -o named /var/lib/named/dnssec_keys | ||
304 | ''); | ||
268 | myServices.monitoring.fromMasterActivatedPlugins = [ "dns" ]; | 305 | myServices.monitoring.fromMasterActivatedPlugins = [ "dns" ]; |
269 | myServices.monitoring.fromMasterObjects.service = lib.mkMerge (lib.mapAttrsToList (name: z: | 306 | myServices.monitoring.fromMasterObjects.service = lib.mkMerge (lib.mapAttrsToList (name: z: |
270 | lib.optional (builtins.elem "immae" z.ns) { | 307 | lib.optional (builtins.elem "immae" z.ns) { |
@@ -276,14 +313,34 @@ | |||
276 | servicegroups = "webstatus-dns"; | 313 | servicegroups = "webstatus-dns"; |
277 | _webstatus_name = name; | 314 | _webstatus_name = name; |
278 | } ++ | 315 | } ++ |
279 | lib.optional (builtins.elem "raito" z.ns) { | 316 | lib.optionals (builtins.elem "raito" z.ns) [ |
280 | service_description = "raito dns is active and authoritative for ${name}"; | 317 | { |
318 | service_description = "raito dns is active and authoritative for ${name}"; | ||
319 | host_name = config.hostEnv.fqdn; | ||
320 | use = "dns-service"; | ||
321 | check_command = ["check_external_dns" "kurisu.dual.lahfa.xyz" name "-A"]; | ||
322 | |||
323 | servicegroups = "webstatus-dns"; | ||
324 | _webstatus_name = "${name} (Secondary DNS Raito)"; | ||
325 | } | ||
326 | { | ||
327 | service_description = "raito dns is up to date for ${name}"; | ||
328 | host_name = config.hostEnv.fqdn; | ||
329 | use = "dns-service"; | ||
330 | check_command = ["check_dns_soa" "kurisu.dual.lahfa.xyz" name config.hostEnv.fqdn]; | ||
331 | |||
332 | servicegroups = "webstatus-dns"; | ||
333 | _webstatus_name = "${name} (Secondary DNS Raito up to date)"; | ||
334 | } | ||
335 | ] ++ | ||
336 | lib.optional z.dnssec.enable { | ||
337 | service_description = "DNSSEC is active and not expired for ${name}"; | ||
281 | host_name = config.hostEnv.fqdn; | 338 | host_name = config.hostEnv.fqdn; |
282 | use = "dns-service"; | 339 | use = "dns-service"; |
283 | check_command = ["check_external_dns" "kurisu.dual.lahfa.xyz" name "-A"]; | 340 | check_command = ["check_dnssec" name]; |
284 | 341 | ||
285 | servicegroups = "webstatus-dns"; | 342 | servicegroups = "webstatus-dns"; |
286 | _webstatus_name = "${name} (Secondary DNS Raito)"; | 343 | _webstatus_name = "${name} (DNSSEC)"; |
287 | } | 344 | } |
288 | ) config.myServices.dns.zones); | 345 | ) config.myServices.dns.zones); |
289 | }; | 346 | }; |
diff --git a/systems/eldiron/ejabberd/default.nix b/systems/eldiron/ejabberd/default.nix index 5268516..463d255 100644 --- a/systems/eldiron/ejabberd/default.nix +++ b/systems/eldiron/ejabberd/default.nix | |||
@@ -25,7 +25,7 @@ in | |||
25 | } | 25 | } |
26 | zoneHeader | 26 | zoneHeader |
27 | mailMX | 27 | mailMX |
28 | (mailCommon "immae.fr") | 28 | (mailCommon "immae.fr" true) |
29 | (ips servers.eldiron.ips.main) | 29 | (ips servers.eldiron.ips.main) |
30 | { | 30 | { |
31 | ns = [ "immae" "raito" ]; | 31 | ns = [ "immae" "raito" ]; |
diff --git a/systems/eldiron/flake.lock b/systems/eldiron/flake.lock index c52dd61..5a60dab 100644 --- a/systems/eldiron/flake.lock +++ b/systems/eldiron/flake.lock | |||
@@ -2038,7 +2038,7 @@ | |||
2038 | }, | 2038 | }, |
2039 | "locked": { | 2039 | "locked": { |
2040 | "lastModified": 1, | 2040 | "lastModified": 1, |
2041 | "narHash": "sha256-rybO4c9UB9a34Xgoh+ToYz36Dz2OM1sgYxi3m00+W+E=", | 2041 | "narHash": "sha256-DN3hgnw6hXCrSGXep4mumwksWSggsuyyaKXuKvswXl8=", |
2042 | "path": "../../flakes/private/monitoring", | 2042 | "path": "../../flakes/private/monitoring", |
2043 | "type": "path" | 2043 | "type": "path" |
2044 | }, | 2044 | }, |
diff --git a/systems/eldiron/mail/postfix.nix b/systems/eldiron/mail/postfix.nix index f95ee1b..93d1e1e 100644 --- a/systems/eldiron/mail/postfix.nix +++ b/systems/eldiron/mail/postfix.nix | |||
@@ -12,7 +12,7 @@ in | |||
12 | config = lib.mkIf config.myServices.mail.enable { | 12 | config = lib.mkIf config.myServices.mail.enable { |
13 | myServices.dns.zones."immae.eu" = with config.myServices.dns.helpers; lib.mkMerge [ | 13 | myServices.dns.zones."immae.eu" = with config.myServices.dns.helpers; lib.mkMerge [ |
14 | mailMX | 14 | mailMX |
15 | (mailCommon "immae.eu") | 15 | (mailCommon "immae.eu" true) |
16 | mailSend | 16 | mailSend |
17 | { | 17 | { |
18 | # Virtual forwards and mailboxes for real users | 18 | # Virtual forwards and mailboxes for real users |
@@ -22,7 +22,7 @@ in | |||
22 | # system virtual mailboxes: | 22 | # system virtual mailboxes: |
23 | # devnull, printer, testconnect | 23 | # devnull, printer, testconnect |
24 | emailPolicies."".receive = true; | 24 | emailPolicies."".receive = true; |
25 | subdomains.mail = lib.mkMerge [ (mailCommon "immae.eu") mailSend ]; | 25 | subdomains.mail = lib.mkMerge [ (mailCommon "immae.eu" true) mailSend ]; |
26 | subdomains.smtp = ips servers.eldiron.ips.main; | 26 | subdomains.smtp = ips servers.eldiron.ips.main; |
27 | 27 | ||
28 | # DMARC reports | 28 | # DMARC reports |
diff --git a/systems/eldiron/mail/sympa.nix b/systems/eldiron/mail/sympa.nix index 8e801dd..07175e8 100644 --- a/systems/eldiron/mail/sympa.nix +++ b/systems/eldiron/mail/sympa.nix | |||
@@ -9,7 +9,7 @@ in | |||
9 | myServices.dns.zones."immae.eu".subdomains.lists = | 9 | myServices.dns.zones."immae.eu".subdomains.lists = |
10 | with config.myServices.dns.helpers; lib.mkMerge [ | 10 | with config.myServices.dns.helpers; lib.mkMerge [ |
11 | (ips servers.eldiron.ips.main) | 11 | (ips servers.eldiron.ips.main) |
12 | (mailCommon "immae.eu") | 12 | (mailCommon "immae.eu" false) |
13 | mailSend | 13 | mailSend |
14 | ]; | 14 | ]; |
15 | 15 | ||
diff --git a/systems/eldiron/websites/tools/default.nix b/systems/eldiron/websites/tools/default.nix index 397b644..338ed0b 100644 --- a/systems/eldiron/websites/tools/default.nix +++ b/systems/eldiron/websites/tools/default.nix | |||
@@ -91,7 +91,7 @@ in { | |||
91 | { | 91 | { |
92 | outils = ips servers.eldiron.ips.main; | 92 | outils = ips servers.eldiron.ips.main; |
93 | tools = lib.mkMerge [ | 93 | tools = lib.mkMerge [ |
94 | (mailCommon "immae.eu") | 94 | (mailCommon "immae.eu" true) |
95 | mailSend | 95 | mailSend |
96 | (ips servers.eldiron.ips.main) | 96 | (ips servers.eldiron.ips.main) |
97 | ]; | 97 | ]; |