diff options
Diffstat (limited to '')
| -rw-r--r-- | tests/by-name/em/email-dns/nodes/mail_server.nix | 6 | ||||
| -rw-r--r-- | tests/by-name/em/email-dns/nodes/name_server.nix | 232 | ||||
| -rw-r--r-- | tests/by-name/em/email-dns/nodes/user.nix | 6 | ||||
| -rw-r--r-- | tests/by-name/em/email-dns/test.nix | 34 | ||||
| -rw-r--r-- | tests/by-name/em/email-http/nodes/name_server.nix | 210 | ||||
| -rw-r--r-- | tests/by-name/em/email-http/test.nix | 137 | ||||
| -rw-r--r-- | tests/by-name/sh/sharkey/test.nix | 118 |
7 files changed, 299 insertions, 444 deletions
diff --git a/tests/by-name/em/email-dns/nodes/mail_server.nix b/tests/by-name/em/email-dns/nodes/mail_server.nix index 89dbc4a..279d289 100644 --- a/tests/by-name/em/email-dns/nodes/mail_server.nix +++ b/tests/by-name/em/email-dns/nodes/mail_server.nix @@ -14,6 +14,7 @@ ++ [ ../../../../../modules ../../../../common/acme/client.nix + ../../../../common/dns/client.nix ]; environment.systemPackages = [ @@ -21,11 +22,6 @@ pkgs.openssl ]; - networking.nameservers = lib.mkForce [ - nodes.name_server.networking.primaryIPAddress - nodes.name_server.networking.primaryIPv6Address - ]; - age.identityPaths = ["${../../../../common/email/hostKey}"]; vhack = { diff --git a/tests/by-name/em/email-dns/nodes/name_server.nix b/tests/by-name/em/email-dns/nodes/name_server.nix index 48ce496..d9d3617 100644 --- a/tests/by-name/em/email-dns/nodes/name_server.nix +++ b/tests/by-name/em/email-dns/nodes/name_server.nix @@ -140,13 +140,9 @@ in { ++ [ ../../../../../modules ../../../../common/acme/client.nix + ../../../../common/dns/server.nix ]; - networking.nameservers = lib.mkForce [ - nodes.name_server.networking.primaryIPAddress - nodes.name_server.networking.primaryIPv6Address - ]; - services.nginx = { logError = "stderr debug"; virtualHosts = let @@ -175,145 +171,121 @@ in { 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; - }; + dns.zones = let + stsZone = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; + }; - useOrigin = false; + useOrigin = false; - A = [ - nodes.name_server.networking.primaryIPAddress - ]; - AAAA = [ - nodes.name_server.networking.primaryIPv6Address - ]; + A = [ + nodes.name_server.networking.primaryIPAddress + ]; + AAAA = [ + nodes.name_server.networking.primaryIPv6Address + ]; + }; + in { + "arpa" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; }; - in { - "arpa" = { - SOA = { - nameServer = "ns"; - adminEmail = "admin@server.com"; - serial = 2025012301; - }; - useOrigin = false; + useOrigin = false; - PTR = [ - { - name = "acme.test"; - ip.v4 = nodes.acme.networking.primaryIPAddress; - } - { - name = "acme.test"; - ip.v6 = nodes.acme.networking.primaryIPv6Address; - } + 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 = "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 = "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 = "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 = "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; + { + name = "ns.server.com"; + ip.v4 = nodes.name_server.networking.primaryIPAddress; + } + { + name = "ns.server.com"; + ip.v6 = nodes.name_server.networking.primaryIPv6Address; + } + ]; + }; - A = [ - nodes.name_server.networking.primaryIPAddress - ]; - AAAA = [ - 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; }; - "acme.test" = { - SOA = { - nameServer = "ns"; - adminEmail = "admin@server.com"; - serial = 2025012301; - }; - useOrigin = false; + useOrigin = false; - A = [ - nodes.acme.networking.primaryIPAddress - ]; - AAAA = [ - nodes.acme.networking.primaryIPv6Address - ]; + A = [ + nodes.name_server.networking.primaryIPAddress + ]; + AAAA = [ + nodes.name_server.networking.primaryIPv6Address + ]; + }; + "server.com" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; }; - "server.com" = { - SOA = { - nameServer = "ns"; - adminEmail = "admin@server.com"; - serial = 2025012301; - }; - useOrigin = false; - NS = [ - "ns.server.com." - ]; - }; + useOrigin = false; + NS = [ + "ns.server.com." + ]; }; }; }; diff --git a/tests/by-name/em/email-dns/nodes/user.nix b/tests/by-name/em/email-dns/nodes/user.nix index 55a4609..fba02ce 100644 --- a/tests/by-name/em/email-dns/nodes/user.nix +++ b/tests/by-name/em/email-dns/nodes/user.nix @@ -9,6 +9,7 @@ }: { imports = [ ../../../../common/acme/client.nix + ../../../../common/dns/client.nix ]; environment.systemPackages = [ @@ -20,11 +21,6 @@ pkgs.openssl ]; - networking.nameservers = lib.mkForce [ - nodes.name_server.networking.primaryIPAddress - nodes.name_server.networking.primaryIPv6Address - ]; - users.users."${user}" = {isNormalUser = true;}; systemd.tmpfiles.rules = [ diff --git a/tests/by-name/em/email-dns/test.nix b/tests/by-name/em/email-dns/test.nix index 0e4d9a0..f0399a5 100644 --- a/tests/by-name/em/email-dns/test.nix +++ b/tests/by-name/em/email-dns/test.nix @@ -31,9 +31,9 @@ in lib, ... }: { - imports = [../../../common/acme]; - networking.nameservers = lib.mkForce [ - nodes.name_server.networking.primaryIPAddress + imports = [ + ../../../common/acme/server.nix + ../../../common/dns/client.nix ]; }; @@ -89,7 +89,8 @@ in exit 1 } ''; - inherit (pkgs) lib; + + acme_scripts = import ../../../common/acme/scripts.nix {inherit pkgs;}; in /* python @@ -121,30 +122,7 @@ in with subtest("Add pebble ca key to all services"): for node in [name_server, mail1_server, mail2_server, alice, bob]: - node.succeed("${pkgs.writeShellScript "fetch-and-set-ca" '' - set -xe - - # Fetch the randomly generated ca certificate - curl https://acme.test:15000/roots/0 > /tmp/ca.crt - curl https://acme.test:15000/intermediates/0 >> /tmp/ca.crt - - # Append it to the various system stores - # The file paths are from <nixpgks>/modules/security/ca.nix - for cert_path in "ssl/certs/ca-certificates.crt" "ssl/certs/ca-bundle.crt" "pki/tls/certs/ca-bundle.crt"; do - cert_path="/etc/$cert_path" - - mv "$cert_path" "$cert_path.old" - cat "$cert_path.old" > "$cert_path" - cat /tmp/ca.crt >> "$cert_path" - done - - export NIX_SSL_CERT_FILE=/tmp/ca.crt - export SSL_CERT_FILE=/tmp/ca.crt - - # TODO - # # P11-Kit trust source. - # environment.etc."ssl/trust-source".source = "$${cacertPackage.p11kit}/etc/ssl/trust-source"; - ''}") + node.succeed("${acme_scripts.add_pebble_acme_ca}") with subtest("Both mailserver successfully started all services"): import json diff --git a/tests/by-name/em/email-http/nodes/name_server.nix b/tests/by-name/em/email-http/nodes/name_server.nix deleted file mode 100644 index a7e3ce9..0000000 --- a/tests/by-name/em/email-http/nodes/name_server.nix +++ /dev/null @@ -1,210 +0,0 @@ -{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/test.nix b/tests/by-name/em/email-http/test.nix index 2c7921d..f508b9f 100644 --- a/tests/by-name/em/email-http/test.nix +++ b/tests/by-name/em/email-http/test.nix @@ -31,13 +31,38 @@ in lib, ... }: { - imports = [../../../common/acme]; - networking.nameservers = lib.mkForce [ - nodes.name_server.networking.primaryIPAddress + imports = [ + ../../../common/acme/server.nix + ../../../common/dns/client.nix ]; }; - name_server = import ./nodes/name_server.nix {inherit extraModules;}; + name_server = {nodes, ...}: { + imports = + extraModules + ++ [ + ../../../common/acme/client.nix + ../../../common/dns/server.nix + ]; + + vhack.dns.zones = { + "mail.server.com" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; + }; + useOrigin = false; + + A = [ + nodes.mail_server.networking.primaryIPAddress + ]; + AAAA = [ + nodes.mail_server.networking.primaryIPv6Address + ]; + }; + }; + }; mail_server = mkMailServer "mail" null; @@ -45,66 +70,46 @@ in }; # TODO(@bpeetz): This test should also test the http JMAP features of stalwart-mail. <2025-04-12> - testScript = _: - /* - python - */ - '' - # Start dependencies for the other services - acme.start() - acme.wait_for_unit("pebble.service") - name_server.start() - name_server.wait_for_unit("nsd.service") - - # Start the actual testing machines - start_all() - - mail_server.wait_for_unit("stalwart-mail.service") - mail_server.wait_for_open_port(993) # imap - mail_server.wait_for_open_port(465) # smtp - - bob.wait_for_unit("multi-user.target") - - with subtest("Add pebble ca key to all services"): - for node in [name_server, mail_server, bob]: - node.succeed("${pkgs.writeShellScript "fetch-and-set-ca" '' - set -xe - - # Fetch the randomly generated ca certificate - curl https://acme.test:15000/roots/0 > /tmp/ca.crt - curl https://acme.test:15000/intermediates/0 >> /tmp/ca.crt - - # Append it to the various system stores - # The file paths are from <nixpgks>/modules/security/ca.nix - for cert_path in "ssl/certs/ca-certificates.crt" "ssl/certs/ca-bundle.crt" "pki/tls/certs/ca-bundle.crt"; do - cert_path="/etc/$cert_path" - - mv "$cert_path" "$cert_path.old" - cat "$cert_path.old" > "$cert_path" - cat /tmp/ca.crt >> "$cert_path" - done - - export NIX_SSL_CERT_FILE=/tmp/ca.crt - export SSL_CERT_FILE=/tmp/ca.crt - - # TODO - # # P11-Kit trust source. - # environment.etc."ssl/trust-source".source = "$${cacertPackage.p11kit}/etc/ssl/trust-source"; - ''}") - - with subtest("The mailserver successfully started all services"): - import json - def all_services_running(host): - (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json") - host_failed = json.loads(output) - assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}" - all_services_running(mail_server) - - with subtest("Bob can use the self-service interface"): - bob.succeed("${pkgs.writeShellScript "check-self-service" '' - curl mail.server.com --location --output /home/bob/output.html; - ''}") - - bob.copy_from_vm("/home/bob", "") - ''; + testScript = _: let + acme_scripts = import ../../../common/acme/scripts.nix {inherit pkgs;}; + in + /* + python + */ + '' + # Start dependencies for the other services + acme.start() + acme.wait_for_unit("pebble.service") + name_server.start() + name_server.wait_for_unit("nsd.service") + + # Start the actual testing machines + start_all() + + mail_server.wait_for_unit("stalwart-mail.service") + mail_server.wait_for_open_port(993) # imap + mail_server.wait_for_open_port(465) # smtp + + bob.wait_for_unit("multi-user.target") + + with subtest("Add pebble ca key to all services"): + for node in [name_server, mail_server, bob]: + node.wait_for_unit("network-online.target") + node.succeed("${acme_scripts.add_pebble_acme_ca}") + + with subtest("The mailserver successfully started all services"): + import json + def all_services_running(host): + (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json") + host_failed = json.loads(output) + assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}" + all_services_running(mail_server) + + with subtest("Bob can use the self-service interface"): + bob.succeed("${pkgs.writeShellScript "check-self-service" '' + curl mail.server.com --location --output /home/bob/output.html; + ''}") + + bob.copy_from_vm("/home/bob", "") + ''; } diff --git a/tests/by-name/sh/sharkey/test.nix b/tests/by-name/sh/sharkey/test.nix new file mode 100644 index 0000000..40efe17 --- /dev/null +++ b/tests/by-name/sh/sharkey/test.nix @@ -0,0 +1,118 @@ +{ + nixos-lib, + pkgsUnstable, + nixpkgs-unstable, + vhackPackages, + pkgs, + extraModules, + nixLib, + ... +}: +nixos-lib.runTest { + hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs + + name = "sharkey"; + + node = { + specialArgs = {inherit pkgsUnstable extraModules vhackPackages nixpkgs-unstable nixLib;}; + + # Use the nixpkgs as constructed by the `nixpkgs.*` options + pkgs = null; + }; + + nodes = { + acme = {...}: { + imports = [ + ../../../common/acme/server.nix + ../../../common/dns/client.nix + ]; + }; + name_server = {nodes, ...}: { + imports = + extraModules + ++ [ + ../../../common/acme/client.nix + ../../../common/dns/server.nix + ]; + + vhack.dns.zones = { + "sharkey.server" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; + }; + useOrigin = false; + + A = [ + nodes.server.networking.primaryIPAddress + ]; + AAAA = [ + nodes.server.networking.primaryIPv6Address + ]; + }; + }; + }; + + server = {config, ...}: { + imports = + extraModules + ++ [ + ../../../../modules + ../../../common/acme/client.nix + ../../../common/dns/client.nix + ]; + + vhack = { + persist.enable = true; + nginx.enable = true; + sharkey = { + enable = true; + fqdn = "sharkey.server"; + }; + }; + }; + + client = {...}: { + imports = [ + ../../../common/acme/client.nix + ../../../common/dns/client.nix + ]; + }; + }; + + testScript = {nodes, ...}: let + acme_scripts = import ../../../common/acme/scripts.nix {inherit pkgs;}; + in + /* + python + */ + '' + # Start dependencies for the other services + acme.start() + acme.wait_for_unit("pebble.service") + name_server.start() + name_server.wait_for_unit("nsd.service") + + # Start the actual testing machines + start_all() + + + with subtest("Add pebble ca key to all services"): + for node in [name_server, server, client]: + node.wait_for_unit("network-online.target") + node.succeed("${acme_scripts.add_pebble_acme_ca}") + + server.wait_for_unit("sharkey.service") + + with subtest("All services running"): + import json + def all_services_running(host): + (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json") + host_failed = json.loads(output) + assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}" + all_services_running(server) + + client.wait_until_succeeds("curl --silent https://sharkey.server | grep 'Thank you for using Sharkey!'") + ''; +} |
