aboutsummaryrefslogtreecommitdiffstats
path: root/tests/by-name/em/email-http/nodes
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-04-12 16:28:46 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-04-23 12:10:33 +0200
commit2452418a7a3aea1ecfd54f135f4814e0c51b946c (patch)
tree997a1107995930d3f036544f7690d4d46d5296dd /tests/by-name/em/email-http/nodes
parentmodules/stalwart-mail: Don't restart the systemd service (diff)
downloadnixos-server-2452418a7a3aea1ecfd54f135f4814e0c51b946c.zip
tests/email-http: Test the http self-service availability
Diffstat (limited to 'tests/by-name/em/email-http/nodes')
-rw-r--r--tests/by-name/em/email-http/nodes/mail_server.nix57
-rw-r--r--tests/by-name/em/email-http/nodes/name_server.nix210
-rw-r--r--tests/by-name/em/email-http/nodes/user.nix26
3 files changed, 293 insertions, 0 deletions
diff --git a/tests/by-name/em/email-http/nodes/mail_server.nix b/tests/by-name/em/email-http/nodes/mail_server.nix
new file mode 100644
index 0000000..e94c4e9
--- /dev/null
+++ b/tests/by-name/em/email-http/nodes/mail_server.nix
@@ -0,0 +1,57 @@
+{
+ extraModules,
+ pkgs,
+ vhackPackages,
+}: {
+ mkMailServer = serverName: principal: {
+ config,
+ lib,
+ nodes,
+ ...
+ }: {
+ imports =
+ extraModules
+ ++ [
+ ../../../../../modules
+ ../../../../common/acme/client.nix
+ ];
+
+ environment.systemPackages = [
+ pkgs.bind
+ pkgs.openssl
+ ];
+
+ networking.nameservers = lib.mkForce [
+ nodes.name_server.networking.primaryIPAddress
+ nodes.name_server.networking.primaryIPv6Address
+ ];
+
+ age.identityPaths = ["${../../../../common/email/hostKey}"];
+
+ vhack = {
+ stalwart-mail = {
+ enable = true;
+ fqdn = "${serverName}.server.com";
+ admin = "admin@${serverName}.server.com";
+ security = {
+ dkimKeys = let
+ loadKey = name: {
+ dkimPublicKey = builtins.readFile (../../../../common/email/dkim + "/${name}/public");
+ dkimPrivateKeyPath = ../../../../common/email/dkim + "/${name}/private.age";
+ keyAlgorithm = "ed25519-sha256";
+ };
+ in {
+ "mail.server.com" = loadKey "mail1.server.com";
+ "bob.com" = loadKey "bob.com";
+ };
+ verificationMode = "strict";
+ };
+ openFirewall = true;
+ principals =
+ if principal == null
+ then null
+ else [principal];
+ };
+ };
+ };
+}
diff --git a/tests/by-name/em/email-http/nodes/name_server.nix b/tests/by-name/em/email-http/nodes/name_server.nix
new file mode 100644
index 0000000..a7e3ce9
--- /dev/null
+++ b/tests/by-name/em/email-http/nodes/name_server.nix
@@ -0,0 +1,210 @@
+{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 = "reject";
+ 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
+ ../../../../common/acme/client.nix
+ ];
+
+ networking.nameservers = lib.mkForce [
+ nodes.name_server.networking.primaryIPAddress
+ nodes.name_server.networking.primaryIPv6Address
+ ];
+
+ vhack = {
+ nginx = {
+ enable = true;
+ };
+ dns = {
+ enable = true;
+ openFirewall = true;
+ interfaces = [
+ nodes.name_server.networking.primaryIPAddress
+ nodes.name_server.networking.primaryIPv6Address
+ ];
+
+ zones = {
+ "bob.com" = mkZone "bob" nodes lib nodes.mail_server.vhack.stalwart-mail;
+ "mail.server.com" = mkServerZone "mail" 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."
+ ];
+ };
+ };
+ };
+ };
+}
diff --git a/tests/by-name/em/email-http/nodes/user.nix b/tests/by-name/em/email-http/nodes/user.nix
new file mode 100644
index 0000000..73b9ff7
--- /dev/null
+++ b/tests/by-name/em/email-http/nodes/user.nix
@@ -0,0 +1,26 @@
+{
+ pkgs,
+ vhackPackages,
+}: {
+ mkUser = user: serverName: {
+ nodes,
+ lib,
+ ...
+ }: {
+ imports = [
+ ../../../../common/acme/client.nix
+ ];
+
+ environment.systemPackages = [
+ pkgs.bind
+ pkgs.openssl
+ ];
+
+ networking.nameservers = lib.mkForce [
+ nodes.name_server.networking.primaryIPAddress
+ nodes.name_server.networking.primaryIPv6Address
+ ];
+
+ users.users."${user}" = {isNormalUser = true;};
+ };
+}