From 97787a9dd8b136c8dc327fab42aedf2aa1109ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Bouya?= Date: Tue, 10 Oct 2023 10:44:24 +0200 Subject: Add dnssec --- systems/backup-2/flake.lock | 2 +- systems/dilion/flake.lock | 2 +- systems/eldiron/dns.nix | 117 +++++++++++++++++++++-------- systems/eldiron/ejabberd/default.nix | 2 +- systems/eldiron/flake.lock | 2 +- systems/eldiron/mail/postfix.nix | 4 +- systems/eldiron/mail/sympa.nix | 2 +- systems/eldiron/websites/tools/default.nix | 2 +- systems/monitoring-1/flake.lock | 2 +- systems/quatresaisons/flake.lock | 2 +- 10 files changed, 97 insertions(+), 40 deletions(-) (limited to 'systems') diff --git a/systems/backup-2/flake.lock b/systems/backup-2/flake.lock index 919a027..3ca1baf 100644 --- a/systems/backup-2/flake.lock +++ b/systems/backup-2/flake.lock @@ -389,7 +389,7 @@ }, "locked": { "lastModified": 1, - "narHash": "sha256-rybO4c9UB9a34Xgoh+ToYz36Dz2OM1sgYxi3m00+W+E=", + "narHash": "sha256-DN3hgnw6hXCrSGXep4mumwksWSggsuyyaKXuKvswXl8=", "path": "../../flakes/private/monitoring", "type": "path" }, diff --git a/systems/dilion/flake.lock b/systems/dilion/flake.lock index b6aef70..bd3cdd9 100644 --- a/systems/dilion/flake.lock +++ b/systems/dilion/flake.lock @@ -207,7 +207,7 @@ }, "locked": { "lastModified": 1, - "narHash": "sha256-rybO4c9UB9a34Xgoh+ToYz36Dz2OM1sgYxi3m00+W+E=", + "narHash": "sha256-DN3hgnw6hXCrSGXep4mumwksWSggsuyyaKXuKvswXl8=", "path": "../../flakes/private/monitoring", "type": "path" }, 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 @@ { lib, pkgs, config, dns-nix, ... }: +let + zonesWithDNSSec = lib.filterAttrs (k: v: v.dnssec.enable) config.myServices.dns.zones; + zoneToFile = name: v: pkgs.runCommand "${name}.zone" { + text = v; + passAsFile = [ "text" ]; + # Automatically change the increment when relevant change + # happened (both serial and mta-sts) + } '' + mv "$textPath" $out + increment=$(( 100*($(date -u +%-H) * 60 + $(date -u +%-M))/1440 )) + sed -i -e "s/2022121902/$(date -u +%Y%m%d)$increment/g" $out + sed -i -e "s/20200109150200Z/$(date -u +%Y%m%d%H%M%SZ)/g" $out + ''; +in { options.myServices.dns = { enable = lib.mkEnableOption "enable DNS resolver"; @@ -11,7 +25,10 @@ servers = config.myEnv.servers; ips = i: { A = i.ip4; AAAA = i.ip6; }; letsencrypt = [ { tag = "issue"; value = "letsencrypt.org"; issuerCritical = false; } ]; - toKV = a: builtins.concatStringsSep ";" (builtins.attrValues (builtins.mapAttrs (n: v: "${n}=${v}") a)); + toKV = a: let + removeOrder = n: lib.last (builtins.split "__" n); + in + builtins.concatStringsSep ";" (builtins.attrValues (builtins.mapAttrs (n: v: "${removeOrder n}=${v}") a)); mailMX = { hasEmail = true; subdomains = let @@ -24,10 +41,10 @@ SOA = { # yyyymmdd?? (increment ?? at each change) serial = 2022121902; # Don't change this value, it is replaced automatically! - refresh = 10800; - retry = 3600; - expire = 604800; - minimum = 10800; # negative cache ttl + refresh = 3*60*60; + retry = 60*60; + expire = 14*24*60*60; + minimum = 3*60*60; # negative cache ttl adminEmail = "hostmaster@immae.eu"; #email-address s/@/./ nameServer = "ns1.immae.eu."; }; @@ -42,7 +59,7 @@ (toKV config.myEnv.mail.dkim.immae_eu.public) ]; }; - mailCommon = name: { + mailCommon = name: quarantine: { MX = let mxes = lib.filterAttrs (n: v: v ? mx && v.mx.enable) servers; in @@ -65,16 +82,17 @@ # MTA-STS # https://blog.delouw.ch/2018/12/16/using-mta-sts-to-enhance-email-transport-security-and-privacy/ # https://support.google.com/a/answer/9261504 - _mta-sts.TXT = [ (toKV { v = "STSv1"; id = "20200109150200Z"; }) ]; # Don't change this value, it is updated automatically! - _tls.subdomains._smtp.TXT = [ (toKV { v = "TLSRPTv1"; "rua" = "mailto:postmaster+mta-sts@immae.eu"; }) ]; + _mta-sts.TXT = [ (toKV { _00__v = "STSv1"; id = "20200109150200Z"; }) ]; # Don't change this value, it is updated automatically! + _tls.subdomains._smtp.TXT = [ (toKV { _00__v = "TLSRPTv1"; rua = "mailto:postmaster+mta-sts@immae.eu"; }) ]; mta-sts = ips servers.eldiron.ips.main; # DMARC - _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"; }) ]; + # p needs to be the first tag + _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"; }) ]; }; # SPF - TXT = [ (toKV { v = "spf1 mx ~all"; }) ]; + TXT = [ (toKV { _00__v = "spf1 mx ~all"; }) ]; }; }; }; @@ -83,6 +101,14 @@ dns-nix.lib.types.zone.getSubModules ++ [ ({ name, ... }: { options = { + dnssec = lib.mkOption { + default.enable = false; + type = lib.types.submodule { + options = { + enable = lib.mkEnableOption "Configure dnssec for this domain"; + }; + }; + }; hasEmail = lib.mkEnableOption "This domain has e-mails configuration"; emailPolicies = lib.mkOption { default = {}; @@ -154,12 +180,18 @@ zoneHeader (ips servers.eldiron.ips.main) { - ns = [ "immae" ]; + dnssec.enable = true; + ns = [ "immae" "raito" ]; CAA = letsencrypt; + extraConfig = '' + notify yes; + ''; + slaves = [ "raito" ]; } ]; "immae.dev" = lib.mkMerge [ { + dnssec.enable = true; extraConfig = '' notify yes; ''; @@ -174,6 +206,7 @@ ]; "immae.eu" = lib.mkMerge [ { + dnssec.enable = true; extraConfig = '' notify yes; ''; @@ -182,7 +215,10 @@ zoneHeader (ips servers.eldiron.ips.production) { - ns = [ "immae" "raito" ]; + ns = [ "immae" ]; + # Cannot put ns2.immae.eu as glue record as it takes ages to propagate. + # And gandi only accepts NS records with glues in their interface + NS = [ "kurisu.dual.lahfa.xyz." ]; CAA = letsencrypt; # ns1 has glue records in gandi.net @@ -194,9 +230,9 @@ { # Machines local users emailPolicies.localhost.receive = false; - subdomains.localhost = lib.mkMerge [ (mailCommon "immae.eu") mailSend ]; + subdomains.localhost = lib.mkMerge [ (mailCommon "immae.eu" true) mailSend ]; emailPolicies.eldiron.receive = true; - subdomains.eldiron = lib.mkMerge [ (mailCommon "immae.eu") mailSend ]; + subdomains.eldiron = lib.mkMerge [ (mailCommon "immae.eu" true) mailSend ]; } { # For each server "server" and each server ip group "ipgroup", @@ -248,23 +284,24 @@ zones = builtins.mapAttrs (name: v: { master = true; - extraConfig = v.extraConfig; + extraConfig = v.extraConfig + lib.optionalString v.dnssec.enable '' + key-directory "/var/lib/named/dnssec_keys"; + dnssec-policy default; + inline-signing yes; + ''; masters = []; slaves = lib.flatten (map (n: builtins.attrValues config.myEnv.dns.ns.${n}) v.slaves); - file = pkgs.runCommand "${name}.zone" { - text = v; - passAsFile = [ "text" ]; - # Automatically change the increment when relevant change - # happened (both serial and mta-sts) - } '' - mv "$textPath" $out - increment=$(( 100*($(date -u +%-H) * 60 + $(date -u +%-M))/1440 )) - sed -i -e "s/2022121902/$(date -u +%Y%m%d)$increment/g" $out - sed -i -e "s/20200109150200Z/$(date -u +%Y%m%d%H%M%SZ)/g" $out - ''; + file = if v.dnssec.enable then "/var/run/named/dnssec-${name}.zone" else zoneToFile name v; }) config.myServices.dns.zones; }; + systemd.services.bind.serviceConfig.StateDirectory = "named"; + systemd.services.bind.preStart = lib.mkAfter + (builtins.concatStringsSep "\n" (lib.mapAttrsToList (name: v: '' + install -m444 ${zoneToFile name v} /var/run/named/dnssec-${name}.zone + '') zonesWithDNSSec) + '' + install -dm755 -o named /var/lib/named/dnssec_keys + ''); myServices.monitoring.fromMasterActivatedPlugins = [ "dns" ]; myServices.monitoring.fromMasterObjects.service = lib.mkMerge (lib.mapAttrsToList (name: z: lib.optional (builtins.elem "immae" z.ns) { @@ -276,14 +313,34 @@ servicegroups = "webstatus-dns"; _webstatus_name = name; } ++ - lib.optional (builtins.elem "raito" z.ns) { - service_description = "raito dns is active and authoritative for ${name}"; + lib.optionals (builtins.elem "raito" z.ns) [ + { + service_description = "raito dns is active and authoritative for ${name}"; + host_name = config.hostEnv.fqdn; + use = "dns-service"; + check_command = ["check_external_dns" "kurisu.dual.lahfa.xyz" name "-A"]; + + servicegroups = "webstatus-dns"; + _webstatus_name = "${name} (Secondary DNS Raito)"; + } + { + service_description = "raito dns is up to date for ${name}"; + host_name = config.hostEnv.fqdn; + use = "dns-service"; + check_command = ["check_dns_soa" "kurisu.dual.lahfa.xyz" name config.hostEnv.fqdn]; + + servicegroups = "webstatus-dns"; + _webstatus_name = "${name} (Secondary DNS Raito up to date)"; + } + ] ++ + lib.optional z.dnssec.enable { + service_description = "DNSSEC is active and not expired for ${name}"; host_name = config.hostEnv.fqdn; use = "dns-service"; - check_command = ["check_external_dns" "kurisu.dual.lahfa.xyz" name "-A"]; + check_command = ["check_dnssec" name]; servicegroups = "webstatus-dns"; - _webstatus_name = "${name} (Secondary DNS Raito)"; + _webstatus_name = "${name} (DNSSEC)"; } ) config.myServices.dns.zones); }; 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 } zoneHeader mailMX - (mailCommon "immae.fr") + (mailCommon "immae.fr" true) (ips servers.eldiron.ips.main) { 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 @@ }, "locked": { "lastModified": 1, - "narHash": "sha256-rybO4c9UB9a34Xgoh+ToYz36Dz2OM1sgYxi3m00+W+E=", + "narHash": "sha256-DN3hgnw6hXCrSGXep4mumwksWSggsuyyaKXuKvswXl8=", "path": "../../flakes/private/monitoring", "type": "path" }, 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 config = lib.mkIf config.myServices.mail.enable { myServices.dns.zones."immae.eu" = with config.myServices.dns.helpers; lib.mkMerge [ mailMX - (mailCommon "immae.eu") + (mailCommon "immae.eu" true) mailSend { # Virtual forwards and mailboxes for real users @@ -22,7 +22,7 @@ in # system virtual mailboxes: # devnull, printer, testconnect emailPolicies."".receive = true; - subdomains.mail = lib.mkMerge [ (mailCommon "immae.eu") mailSend ]; + subdomains.mail = lib.mkMerge [ (mailCommon "immae.eu" true) mailSend ]; subdomains.smtp = ips servers.eldiron.ips.main; # 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 myServices.dns.zones."immae.eu".subdomains.lists = with config.myServices.dns.helpers; lib.mkMerge [ (ips servers.eldiron.ips.main) - (mailCommon "immae.eu") + (mailCommon "immae.eu" false) mailSend ]; 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 { { outils = ips servers.eldiron.ips.main; tools = lib.mkMerge [ - (mailCommon "immae.eu") + (mailCommon "immae.eu" true) mailSend (ips servers.eldiron.ips.main) ]; diff --git a/systems/monitoring-1/flake.lock b/systems/monitoring-1/flake.lock index 6758db3..ec29221 100644 --- a/systems/monitoring-1/flake.lock +++ b/systems/monitoring-1/flake.lock @@ -277,7 +277,7 @@ }, "locked": { "lastModified": 1, - "narHash": "sha256-rybO4c9UB9a34Xgoh+ToYz36Dz2OM1sgYxi3m00+W+E=", + "narHash": "sha256-DN3hgnw6hXCrSGXep4mumwksWSggsuyyaKXuKvswXl8=", "path": "../../flakes/private/monitoring", "type": "path" }, diff --git a/systems/quatresaisons/flake.lock b/systems/quatresaisons/flake.lock index 653ce9c..e23bbde 100644 --- a/systems/quatresaisons/flake.lock +++ b/systems/quatresaisons/flake.lock @@ -239,7 +239,7 @@ }, "locked": { "lastModified": 1, - "narHash": "sha256-rybO4c9UB9a34Xgoh+ToYz36Dz2OM1sgYxi3m00+W+E=", + "narHash": "sha256-DN3hgnw6hXCrSGXep4mumwksWSggsuyyaKXuKvswXl8=", "path": "../../flakes/private/monitoring", "type": "path" }, -- cgit v1.2.3