at 24.11-pre 5.0 kB view raw
1import ./make-test-python.nix ({ lib, pkgs, ...}: { 2 name = "haproxy"; 3 nodes = { 4 server = { ... }: { 5 services.haproxy = { 6 enable = true; 7 config = '' 8 global 9 limited-quic 10 11 defaults 12 mode http 13 timeout connect 10s 14 timeout client 10s 15 timeout server 10s 16 17 log /dev/log local0 debug err 18 option logasap 19 option httplog 20 option httpslog 21 22 backend http_server 23 server httpd [::1]:8000 alpn http/1.1 24 25 frontend http 26 bind :80 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 29 30 http-after-response add-header alt-svc 'h3=":443"; ma=60' if { ssl_fc } 31 32 http-request use-service prometheus-exporter if { path /metrics } 33 use_backend http_server 34 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 38 39 use_backend http_server 40 ''; 41 }; 42 services.httpd = { 43 enable = true; 44 virtualHosts.localhost = { 45 documentRoot = pkgs.writeTextDir "index.txt" "We are all good!"; 46 adminAddr = "notme@yourhost.local"; 47 listen = [{ 48 ip = "::1"; 49 port = 8000; 50 }]; 51 }; 52 }; 53 networking.firewall.allowedTCPPorts = [ 80 443 8443 ]; 54 networking.firewall.allowedUDPPorts = [ 443 8443 ]; 55 }; 56 client = { ... }: { 57 environment.systemPackages = [ pkgs.curlHTTP3 ]; 58 }; 59 }; 60 testScript = '' 61 # Helpers 62 def cmd(command): 63 print(f"+{command}") 64 r = os.system(command) 65 if r != 0: 66 raise Exception(f"Command {command} failed with exit code {r}") 67 68 def openssl(command): 69 cmd(f"${pkgs.openssl}/bin/openssl {command}") 70 71 # Generate CA. 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") 73 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") 78 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") 83 84 # Start the actual test. 85 start_all() 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") 89 90 client.copy_from_host("cacert.crt", "/etc/ssl/cacert.crt") 91 client.copy_from_host("client.pem", "/root/client.pem") 92 93 server.wait_for_unit("multi-user.target") 94 server.wait_for_unit("haproxy.service") 95 server.wait_for_unit("httpd.service") 96 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") 99 100 with subtest("https"): 101 assert "We are all good!" in client.succeed("curl -f --cacert /etc/ssl/cacert.crt https://server/index.txt") 102 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") 108 109 with subtest("h3"): 110 assert "We are all good!" in client.succeed("curl -f --http3-only --cacert /etc/ssl/cacert.crt https://server/index.txt") 111 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") 117 118 with subtest("reload"): 119 server.succeed("systemctl reload haproxy") 120 # wait some time to ensure the following request hits the reloaded haproxy 121 server.sleep(5) 122 assert "We are all good!" in client.succeed("curl -f http://server/index.txt") 123 ''; 124})