From 4fecaae82e6de19f9f1b5a5a5c9984e911d75bf1 Mon Sep 17 00:00:00 2001 From: Benedikt Peetz Date: Tue, 22 Apr 2025 21:34:56 +0200 Subject: tests/{common,email-dns}: Move last part of acme and dns handling to common This makes re-using it even easier. --- tests/by-name/em/email-dns/nodes/mail_server.nix | 6 +- tests/by-name/em/email-dns/nodes/name_server.nix | 232 ++++++++++------------- tests/by-name/em/email-dns/nodes/user.nix | 6 +- tests/by-name/em/email-dns/test.nix | 34 +--- tests/common/acme/default.nix | 114 ----------- tests/common/acme/scripts.nix | 30 +++ tests/common/acme/server.nix | 91 +++++++++ tests/common/dns/client.nix | 10 + tests/common/dns/server.nix | 43 +++++ 9 files changed, 284 insertions(+), 282 deletions(-) delete mode 100644 tests/common/acme/default.nix create mode 100644 tests/common/acme/scripts.nix create mode 100644 tests/common/acme/server.nix create mode 100644 tests/common/dns/client.nix create mode 100644 tests/common/dns/server.nix (limited to 'tests') 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 7391c86..6812d32 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 /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/common/acme/default.nix b/tests/common/acme/default.nix deleted file mode 100644 index 236ba6a..0000000 --- a/tests/common/acme/default.nix +++ /dev/null @@ -1,114 +0,0 @@ -# The certificate for the ACME service is exported as: -# -# config.test-support.acme.caCert -# -# This value can be used inside the configuration of other test nodes to inject -# the test certificate into security.pki.certificateFiles or into package -# overlays. -# -# { -# acme = { nodes, lib, ... }: { -# imports = [ ./common/acme/server ]; -# networking.nameservers = lib.mkForce [ -# nodes.mydnsresolver.networking.primaryIPAddress -# ]; -# }; -# -# dnsmyresolver = ...; -# } -# -# Keep in mind, that currently only _one_ resolver is supported, if you have -# more than one resolver in networking.nameservers only the first one will be -# used. -# -# Also make sure that whenever you use a resolver from a different test node -# that it has to be started _before_ the ACME service. -{ - config, - pkgs, - lib, - ... -}: let - testCerts = import ./certs/snakeoil-certs.nix; - inherit (testCerts) domain; - - pebbleConf.pebble = { - listenAddress = "0.0.0.0:443"; - managementListenAddress = "0.0.0.0:15000"; - - # The cert and key are used only for the Web Front End (WFE) - certificate = testCerts.${domain}.cert; - privateKey = testCerts.${domain}.key; - - httpPort = 80; - tlsPort = 443; - ocspResponderURL = "http://${domain}:4002"; - strict = true; - }; - - pebbleConfFile = pkgs.writeText "pebble.conf" (builtins.toJSON pebbleConf); -in { - options.test-support.acme = { - caDomain = lib.mkOption { - type = lib.types.str; - default = domain; - readOnly = true; - description = '' - A domain name to use with the `nodes` attribute to - identify the CA server in the `client` config. - ''; - }; - caCert = lib.mkOption { - type = lib.types.path; - readOnly = true; - default = testCerts.ca.cert; - description = '' - A certificate file to use with the `nodes` attribute to - inject the test CA certificate used in the ACME server into - {option}`security.pki.certificateFiles`. - ''; - }; - }; - - config = { - networking = { - # This has priority 140, because modules/testing/test-instrumentation.nix - # already overrides this with priority 150. - nameservers = lib.mkOverride 140 ["127.0.0.1"]; - firewall.allowedTCPPorts = [ - 80 - 443 - 15000 - 4002 - ]; - - extraHosts = '' - 127.0.0.1 ${domain} - ${config.networking.primaryIPAddress} ${domain} - ''; - }; - - systemd.services = { - pebble = { - enable = true; - description = "Pebble ACME server"; - wantedBy = ["network.target"]; - environment = { - # We're not testing lego, we're just testing our configuration. - # No need to sleep. - PEBBLE_VA_NOSLEEP = "1"; - }; - - serviceConfig = { - RuntimeDirectory = "pebble"; - WorkingDirectory = "/run/pebble"; - - # Required to bind on privileged ports. - AmbientCapabilities = ["CAP_NET_BIND_SERVICE"]; - - ExecStart = "${pkgs.pebble}/bin/pebble -config ${pebbleConfFile}"; - }; - }; - }; - }; -} diff --git a/tests/common/acme/scripts.nix b/tests/common/acme/scripts.nix new file mode 100644 index 0000000..2228823 --- /dev/null +++ b/tests/common/acme/scripts.nix @@ -0,0 +1,30 @@ +{pkgs}: +/* +* Extra functions useful for the test script. +*/ +{ + add_pebble_acme_ca = 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 /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"; + ''; +} diff --git a/tests/common/acme/server.nix b/tests/common/acme/server.nix new file mode 100644 index 0000000..997c944 --- /dev/null +++ b/tests/common/acme/server.nix @@ -0,0 +1,91 @@ +# Add this node as acme server. +# This also needs a DNS server. +{ + config, + pkgs, + lib, + ... +}: let + testCerts = import ./certs/snakeoil-certs.nix; + inherit (testCerts) domain; + + pebbleConf.pebble = { + listenAddress = "0.0.0.0:443"; + managementListenAddress = "0.0.0.0:15000"; + + # The cert and key are used only for the Web Front End (WFE) + certificate = testCerts.${domain}.cert; + privateKey = testCerts.${domain}.key; + + httpPort = 80; + tlsPort = 443; + ocspResponderURL = "http://${domain}:4002"; + strict = true; + }; + + pebbleConfFile = pkgs.writeText "pebble.conf" (builtins.toJSON pebbleConf); +in { + options.test-support.acme = { + caDomain = lib.mkOption { + type = lib.types.str; + default = domain; + readOnly = true; + description = '' + A domain name to use with the `nodes` attribute to + identify the CA server in the `client` config. + ''; + }; + caCert = lib.mkOption { + type = lib.types.path; + readOnly = true; + default = testCerts.ca.cert; + description = '' + A certificate file to use with the `nodes` attribute to + inject the test CA certificate used in the ACME server into + {option}`security.pki.certificateFiles`. + ''; + }; + }; + + config = { + networking = { + # This has priority 140, because modules/testing/test-instrumentation.nix + # already overrides this with priority 150. + nameservers = lib.mkOverride 140 ["127.0.0.1"]; + firewall.allowedTCPPorts = [ + 80 + 443 + 15000 + 4002 + ]; + + extraHosts = '' + 127.0.0.1 ${domain} + ${config.networking.primaryIPAddress} ${domain} + ''; + }; + + systemd.services = { + pebble = { + enable = true; + description = "Pebble ACME server"; + wantedBy = ["network.target"]; + environment = { + # We're not testing lego, we're just testing our configuration. + # No need to sleep. + PEBBLE_VA_NOSLEEP = "1"; + }; + + serviceConfig = { + RuntimeDirectory = "pebble"; + WorkingDirectory = "/run/pebble"; + + # Required to bind on privileged ports. + AmbientCapabilities = ["CAP_NET_BIND_SERVICE"]; + + ExecStart = "${pkgs.pebble}/bin/pebble -config ${pebbleConfFile}"; + }; + }; + }; + }; +} diff --git a/tests/common/dns/client.nix b/tests/common/dns/client.nix new file mode 100644 index 0000000..52f3267 --- /dev/null +++ b/tests/common/dns/client.nix @@ -0,0 +1,10 @@ +{ + lib, + nodes, + ... +}: { + networking.nameservers = lib.mkForce [ + nodes.name_server.networking.primaryIPAddress + nodes.name_server.networking.primaryIPv6Address + ]; +} diff --git a/tests/common/dns/server.nix b/tests/common/dns/server.nix new file mode 100644 index 0000000..0c8d72c --- /dev/null +++ b/tests/common/dns/server.nix @@ -0,0 +1,43 @@ +{ + lib, + nodes, + ... +}: { + imports = [ + ../../../modules + ]; + + networking.nameservers = lib.mkForce [ + nodes.name_server.networking.primaryIPAddress + nodes.name_server.networking.primaryIPv6Address + ]; + + vhack = { + dns = { + enable = true; + openFirewall = true; + interfaces = [ + nodes.name_server.networking.primaryIPAddress + nodes.name_server.networking.primaryIPv6Address + ]; + + zones = { + "acme.test" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; + }; + useOrigin = false; + + A = [ + nodes.acme.networking.primaryIPAddress + ]; + AAAA = [ + nodes.acme.networking.primaryIPv6Address + ]; + }; + }; + }; + }; +} -- cgit 1.4.1