diff options
Diffstat (limited to 'tests/by-name/em/email-dns/nodes/name_server.nix')
-rw-r--r-- | tests/by-name/em/email-dns/nodes/name_server.nix | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/tests/by-name/em/email-dns/nodes/name_server.nix b/tests/by-name/em/email-dns/nodes/name_server.nix new file mode 100644 index 0000000..ef657f4 --- /dev/null +++ b/tests/by-name/em/email-dns/nodes/name_server.nix @@ -0,0 +1,320 @@ +{extraModules}: { + config, + lib, + nodes, + pkgs, + ... +}: let + keyAlgoToKeyType = keyAlgo: + if keyAlgo == "ed25519-sha256" + then "ed25519" + else if keyAlgo == "rsa-sha-256" || keyAlgo == "rsa-sha-1" + then "rsa" + else builtins.throw "Impossible"; + + mkZone = user: nodes: lib: cfg: { + SOA = { + nameServer = "ns.server.com"; + adminEmail = "${user}@${user}.com"; + serial = 2024012301; + }; + + MX = [ + { + preference = 10; + exchange = "${cfg.fqdn}."; + } + ]; + + # https://www.rfc-editor.org/rfc/rfc8461.html#section-3.1 + # Also see the policy in the hmtl part. + MTA-STS = [ + { + id = "20250228Z"; + } + ]; + + # https://www.rfc-editor.org/rfc/rfc7208.html + # https://en.wikipedia.org/wiki/Sender_Policy_Framework + TXT = [ + (builtins.concatStringsSep " " + [ + "v=spf1" # The version. + "+mx" # Allow mail from this domain MX record. + "-all" # Reject all other emails if the previous mechanism did not match. + ]) + ]; + + # https://www.rfc-editor.org/rfc/rfc6376.html#section-3.6.1 + # https://www.rfc-editor.org/rfc/rfc6376.html#section-7.5 + DKIM = [ + { + selector = "mail"; + k = keyAlgoToKeyType cfg.security.dkimKeys."${user}.com".keyAlgorithm; + p = cfg.security.dkimKeys."${user}.com".dkimPublicKey; + s = ["email"]; + t = ["s"]; + } + ]; + + # https://www.rfc-editor.org/rfc/rfc7489.html#section-6.3 + DMARC = [ + { + adkim = "strict"; + aspf = "strict"; + fo = ["0" "1" "d" "s"]; + p = "quarantine"; + rua = cfg.admin; + ruf = [cfg.admin]; + } + ]; + + A = [ + nodes.${user}.networking.primaryIPAddress + ]; + AAAA = [ + nodes.${user}.networking.primaryIPv6Address + ]; + }; + mkServerZone = serverName: nodes: lib: let + cfg = nodes."${serverName}_server".vhack.stalwart-mail; + in { + SOA = { + nameServer = "ns.server.com"; + adminEmail = "admin@server.com"; + serial = 2024012301; + }; + MX = [ + { + preference = 10; + exchange = "${serverName}.server.com."; + } + ]; + + # https://www.rfc-editor.org/rfc/rfc6376.html#section-3.6.1 + # https://www.rfc-editor.org/rfc/rfc6376.html#section-7.5 + DKIM = [ + { + selector = "mail"; + k = keyAlgoToKeyType cfg.security.dkimKeys."${serverName}.server.com".keyAlgorithm; + p = cfg.security.dkimKeys."${serverName}.server.com".dkimPublicKey; + s = ["email"]; + t = ["s"]; + } + ]; + + # https://www.rfc-editor.org/rfc/rfc7489.html#section-6.3 + DMARC = [ + { + adkim = "strict"; + aspf = "strict"; + fo = ["0" "1" "d" "s"]; + p = "quarantine"; + rua = cfg.admin; + ruf = [cfg.admin]; + } + ]; + + # https://www.rfc-editor.org/rfc/rfc7208.html + # NOTE(@bpeetz): This server might not be directly sending mail, but it is still required for + # the SMTP EHLO check. <2025-02-25> + TXT = [ + (builtins.concatStringsSep " " + [ + "v=spf1" # The version. + "+mx" # Allow mail from this domain MX record. + "-all" # Reject all other emails if the previous mechanism did not match. + ]) + ]; + + A = [ + nodes."${serverName}_server".networking.primaryIPAddress + ]; + AAAA = [ + nodes."${serverName}_server".networking.primaryIPv6Address + ]; + }; +in { + imports = + extraModules + ++ [ + ../../../../../modules + ./acme/client.nix + ]; + + networking.nameservers = lib.mkForce [ + nodes.name_server.networking.primaryIPAddress + nodes.name_server.networking.primaryIPv6Address + ]; + + services.nginx = { + logError = "stderr debug"; + virtualHosts = let + mkStsHost = mx: { + forceSSL = true; + enableACME = true; + root = pkgs.runCommandLocal "mkPolicy" {} '' + mkdir --parents $out/.well-known/ + + # https://www.rfc-editor.org/rfc/rfc8461.html#section-3.2 + cat << EOF > $out/.well-known/mta-sts.txt + version: STSv1 + mode: enforce + mx: ${mx} + max_age: 604800 + EOF + ''; + }; + in { + "mta-sts.alice.com" = mkStsHost "mail2.server.com"; + "mta-sts.bob.com" = mkStsHost "mail1.server.com"; + }; + }; + + vhack = { + nginx = { + enable = true; + }; + dns = { + enable = true; + openFirewall = true; + interfaces = [ + nodes.name_server.networking.primaryIPAddress + nodes.name_server.networking.primaryIPv6Address + ]; + + zones = let + stsZone = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; + }; + + useOrigin = false; + + A = [ + nodes.name_server.networking.primaryIPAddress + ]; + AAAA = [ + nodes.name_server.networking.primaryIPv6Address + ]; + }; + in { + "arpa" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; + }; + useOrigin = false; + + PTR = [ + { + name = "acme.test"; + ip.v4 = nodes.acme.networking.primaryIPAddress; + } + { + name = "acme.test"; + ip.v6 = nodes.acme.networking.primaryIPv6Address; + } + + { + name = "alice.com"; + ip.v4 = nodes.alice.networking.primaryIPAddress; + } + { + name = "alice.com"; + ip.v6 = nodes.alice.networking.primaryIPv6Address; + } + + { + name = "bob"; + ip.v4 = nodes.bob.networking.primaryIPAddress; + } + { + name = "bob"; + ip.v6 = nodes.bob.networking.primaryIPv6Address; + } + + { + name = "mail1.server.com"; + ip.v4 = nodes.mail1_server.networking.primaryIPAddress; + } + { + name = "mail1.server.com"; + ip.v6 = nodes.mail1_server.networking.primaryIPv6Address; + } + + { + name = "mail2.server.com"; + ip.v4 = nodes.mail2_server.networking.primaryIPAddress; + } + { + name = "mail2.server.com"; + ip.v6 = nodes.mail2_server.networking.primaryIPv6Address; + } + + { + name = "ns.server.com"; + ip.v4 = nodes.name_server.networking.primaryIPAddress; + } + { + name = "ns.server.com"; + ip.v6 = nodes.name_server.networking.primaryIPv6Address; + } + ]; + }; + + "alice.com" = mkZone "alice" nodes lib nodes.mail2_server.vhack.stalwart-mail; + "mta-sts.alice.com" = stsZone; + "bob.com" = mkZone "bob" nodes lib nodes.mail1_server.vhack.stalwart-mail; + "mta-sts.bob.com" = stsZone; + "mail1.server.com" = mkServerZone "mail1" nodes lib; + "mail2.server.com" = mkServerZone "mail2" nodes lib; + "ns.server.com" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; + }; + useOrigin = false; + + A = [ + nodes.name_server.networking.primaryIPAddress + ]; + AAAA = [ + nodes.name_server.networking.primaryIPv6Address + ]; + }; + "acme.test" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; + }; + useOrigin = false; + + A = [ + nodes.acme.networking.primaryIPAddress + ]; + AAAA = [ + nodes.acme.networking.primaryIPv6Address + ]; + }; + "server.com" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; + }; + + useOrigin = false; + NS = [ + "ns.server.com." + ]; + }; + }; + }; + }; +} |