1 import ./make-test-python.nix ({ lib, pkgs, ...}: {
17 log /dev/log local0 debug err
23 server httpd [::1]:8000 alpn http/1.1
27 bind :443 ssl strict-sni crt /etc/ssl/fullchain.pem alpn h2,http/1.1
28 bind quic4@:443 ssl strict-sni crt /etc/ssl/fullchain.pem alpn h3 allow-0rtt
30 http-after-response add-header alt-svc 'h3=":443"; ma=60' if { ssl_fc }
32 http-request use-service prometheus-exporter if { path /metrics }
33 use_backend http_server
35 frontend http-cert-auth
36 bind :8443 ssl strict-sni crt /etc/ssl/fullchain.pem verify required ca-file /etc/ssl/cacert.crt
37 bind quic4@:8443 ssl strict-sni crt /etc/ssl/fullchain.pem verify required ca-file /etc/ssl/cacert.crt alpn h3
39 use_backend http_server
44 virtualHosts.localhost = {
45 documentRoot = pkgs.writeTextDir "index.txt" "We are all good!";
46 adminAddr = "notme@yourhost.local";
53 networking.firewall.allowedTCPPorts = [ 80 443 8443 ];
54 networking.firewall.allowedUDPPorts = [ 443 8443 ];
57 environment.systemPackages = [ pkgs.curlHTTP3 ];
64 r = os.system(command)
66 raise Exception(f"Command {command} failed with exit code {r}")
69 cmd(f"${pkgs.openssl}/bin/openssl {command}")
72 openssl("req -new -newkey rsa:4096 -nodes -x509 -days 7 -subj '/C=ZZ/ST=Cloud/L=Unspecified/O=NixOS/OU=Tests/CN=CA Certificate' -keyout cacert.key -out cacert.crt")
74 # Generate and sign Server.
75 openssl("req -newkey rsa:4096 -nodes -subj '/CN=server/OU=Tests/O=NixOS' -keyout server.key -out server.csr")
76 openssl("x509 -req -in server.csr -out server.crt -CA cacert.crt -CAkey cacert.key -days 7")
77 cmd("cat server.crt server.key > fullchain.pem")
79 # Generate and sign Client.
80 openssl("req -newkey rsa:4096 -nodes -subj '/CN=client/OU=Tests/O=NixOS' -keyout client.key -out client.csr")
81 openssl("x509 -req -in client.csr -out client.crt -CA cacert.crt -CAkey cacert.key -days 7")
82 cmd("cat client.crt client.key > client.pem")
84 # Start the actual test.
86 server.copy_from_host("fullchain.pem", "/etc/ssl/fullchain.pem")
87 server.copy_from_host("cacert.crt", "/etc/ssl/cacert.crt")
88 server.succeed("chmod 0644 /etc/ssl/fullchain.pem /etc/ssl/cacert.crt")
90 client.copy_from_host("cacert.crt", "/etc/ssl/cacert.crt")
91 client.copy_from_host("client.pem", "/root/client.pem")
93 server.wait_for_unit("multi-user.target")
94 server.wait_for_unit("haproxy.service")
95 server.wait_for_unit("httpd.service")
97 assert "We are all good!" in client.succeed("curl -f http://server/index.txt")
98 assert "haproxy_process_pool_allocated_bytes" in client.succeed("curl -f http://server/metrics")
100 with subtest("https"):
101 assert "We are all good!" in client.succeed("curl -f --cacert /etc/ssl/cacert.crt https://server/index.txt")
103 with subtest("https-cert-auth"):
104 # Client must succeed in authenticating with the right certificate.
105 assert "We are all good!" in client.succeed("curl -f --cacert /etc/ssl/cacert.crt --cert-type pem --cert /root/client.pem https://server:8443/index.txt")
106 # Client must fail without certificate.
107 client.fail("curl --cacert /etc/ssl/cacert.crt https://server:8443/index.txt")
110 assert "We are all good!" in client.succeed("curl -f --http3-only --cacert /etc/ssl/cacert.crt https://server/index.txt")
112 with subtest("h3-cert-auth"):
113 # Client must succeed in authenticating with the right certificate.
114 assert "We are all good!" in client.succeed("curl -f --http3-only --cacert /etc/ssl/cacert.crt --cert-type pem --cert /root/client.pem https://server:8443/index.txt")
115 # Client must fail without certificate.
116 client.fail("curl -f --http3-only --cacert /etc/ssl/cacert.crt https://server:8443/index.txt")
118 with subtest("reload"):
119 server.succeed("systemctl reload haproxy")
120 # wait some time to ensure the following request hits the reloaded haproxy
122 assert "We are all good!" in client.succeed("curl -f http://server/index.txt")