From 9ab2c7619ecb7c7bea3dcba1f523a8483042446f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=B7=F0=90=91=91=F0=90=91=B4=F0=90=91=95=F0=90=91=91?= =?UTF-8?q?=F0=90=91=A9=F0=90=91=A4?= Date: Sun, 9 Nov 2025 12:49:23 +0700 Subject: [PATCH 1/2] nixos/tests/h2o: use ports from the actual machines --- nixos/tests/web-servers/h2o/basic.nix | 27 ++++---- nixos/tests/web-servers/h2o/mruby.nix | 8 +-- .../web-servers/h2o/tls-recommendations.nix | 63 +++++++++++-------- 3 files changed, 53 insertions(+), 45 deletions(-) diff --git a/nixos/tests/web-servers/h2o/basic.nix b/nixos/tests/web-servers/h2o/basic.nix index 622bb96929bf..9b67f3397536 100644 --- a/nixos/tests/web-servers/h2o/basic.nix +++ b/nixos/tests/web-servers/h2o/basic.nix @@ -8,11 +8,6 @@ let TLS = "acme.test"; }; - port = { - HTTP = 8080; - TLS = 8443; - }; - sawatdi_chao_lok = "สวัสดีชาวโลก"; hello_world_txt = hostPkgs.writeTextFile { @@ -41,7 +36,7 @@ in nodes = { server = - { pkgs, ... }: + { pkgs, config, ... }: { environment.systemPackages = [ pkgs.curl @@ -49,8 +44,8 @@ in services.h2o = { enable = true; - defaultHTTPListenPort = port.HTTP; - defaultTLSListenPort = port.TLS; + defaultHTTPListenPort = 8080; + defaultTLSListenPort = 8443; hosts = { "${domain.HTTP}" = { settings = { @@ -107,12 +102,12 @@ in networking = { firewall = { - allowedTCPPorts = with port; [ - HTTP - TLS + allowedTCPPorts = with config.services.h2o; [ + defaultHTTPListenPort + defaultTLSListenPort ]; - allowedUDPPorts = with port; [ - TLS + allowedUDPPorts = with config.services.h2o; [ + defaultTLSListenPort ]; }; extraHosts = '' @@ -123,9 +118,11 @@ in }; }; testScript = + { nodes, ... }: let - portStrHTTP = builtins.toString port.HTTP; - portStrTLS = builtins.toString port.TLS; + inherit (nodes) server; + portStrHTTP = builtins.toString server.services.h2o.defaultHTTPListenPort; + portStrTLS = builtins.toString server.services.h2o.defaultTLSListenPort; in # python '' diff --git a/nixos/tests/web-servers/h2o/mruby.nix b/nixos/tests/web-servers/h2o/mruby.nix index b99a4c840b15..803e6c96de83 100644 --- a/nixos/tests/web-servers/h2o/mruby.nix +++ b/nixos/tests/web-servers/h2o/mruby.nix @@ -3,8 +3,6 @@ let domain = "h2o.local"; - port = 8080; - sawatdi_chao_lok = "สวัสดีชาวโลก"; in { @@ -22,7 +20,7 @@ in enable = true; package = pkgs.h2o.override { withMruby = true; }; settings = { - listen = port; + listen = 8080; hosts = { "${domain}" = { paths = { @@ -50,8 +48,10 @@ in }; testScript = + { nodes, ... }: let - portStr = builtins.toString port; + inherit (nodes) server; + portStr = builtins.toString server.services.h2o.settings.listen; in # python '' diff --git a/nixos/tests/web-servers/h2o/tls-recommendations.nix b/nixos/tests/web-servers/h2o/tls-recommendations.nix index a99725f19b10..be80b9ee9e38 100644 --- a/nixos/tests/web-servers/h2o/tls-recommendations.nix +++ b/nixos/tests/web-servers/h2o/tls-recommendations.nix @@ -2,7 +2,6 @@ let domain = "acme.test"; - port = 8443; hello_txt = name: @@ -13,7 +12,12 @@ let mkH2OServer = recommendations: - { pkgs, lib, ... }: + { + pkgs, + lib, + config, + ... + }: { services.h2o = { enable = true; @@ -31,7 +35,8 @@ let hosts = { "${domain}" = { tls = { - inherit port recommendations; + inherit recommendations; + port = 8443; policy = "force"; identity = [ { @@ -59,7 +64,9 @@ let ]; networking = { - firewall.allowedTCPPorts = [ port ]; + firewall.allowedTCPPorts = [ + config.services.h2o.hosts.${domain}.tls.port + ]; extraHosts = "127.0.0.1 ${domain}"; }; }; @@ -78,43 +85,47 @@ in }; testScript = + { nodes, ... }: let - portStr = builtins.toString port; + inherit (nodes) server_modern server_intermediate server_old; + modernPortStr = builtins.toString server_modern.services.h2o.hosts.${domain}.tls.port; + intermediatePortStr = builtins.toString server_intermediate.services.h2o.hosts.${domain}.tls.port; + oldPortStr = builtins.toString server_old.services.h2o.hosts.${domain}.tls.port; in # python '' - curl_basic = "curl -v --tlsv1.3 --http2 'https://${domain}:${portStr}/'" - curl_head = "curl -v --head 'https://${domain}:${portStr}/'" - curl_max_tls1_2 ="curl -v --tlsv1.0 --tls-max 1.2 'https://${domain}:${portStr}/'" - curl_max_tls1_2_intermediate_cipher ="curl -v --tlsv1.0 --tls-max 1.2 --ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256' 'https://${domain}:${portStr}/'" - curl_max_tls1_2_old_cipher ="curl -v --tlsv1.0 --tls-max 1.2 --ciphers 'ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256' 'https://${domain}:${portStr}/'" + curl_basic = "curl -v --tlsv1.3 --http2 'https://${domain}:{port}/'" + curl_head = "curl -v --head 'https://${domain}:{port}/'" + curl_max_tls1_2 ="curl -v --tlsv1.0 --tls-max 1.2 'https://${domain}:{port}/'" + curl_max_tls1_2_intermediate_cipher ="curl -v --tlsv1.0 --tls-max 1.2 --ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256' 'https://${domain}:{port}/'" + curl_max_tls1_2_old_cipher ="curl -v --tlsv1.0 --tls-max 1.2 --ciphers 'ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256' 'https://${domain}:{port}/'" server_modern.wait_for_unit("h2o.service") - server_modern.wait_for_open_port(${portStr}) - modern_response = server_modern.succeed(curl_basic) + server_modern.wait_for_open_port(${modernPortStr}) + modern_response = server_modern.succeed(curl_basic.format(port="${modernPortStr}")) assert "Hello, modern!" in modern_response - modern_head = server_modern.succeed(curl_head) + modern_head = server_modern.succeed(curl_head.format(port="${modernPortStr}")) assert "strict-transport-security" in modern_head - server_modern.fail(curl_max_tls1_2) + server_modern.fail(curl_max_tls1_2.format(port="${modernPortStr}")) server_intermediate.wait_for_unit("h2o.service") - server_intermediate.wait_for_open_port(${portStr}) - intermediate_response = server_intermediate.succeed(curl_basic) + server_intermediate.wait_for_open_port(${intermediatePortStr}) + intermediate_response = server_intermediate.succeed(curl_basic.format(port="${intermediatePortStr}")) assert "Hello, intermediate!" in intermediate_response - intermediate_head = server_modern.succeed(curl_head) + intermediate_head = server_modern.succeed(curl_head.format(port="${intermediatePortStr}")) assert "strict-transport-security" in intermediate_head - server_intermediate.succeed(curl_max_tls1_2) - server_intermediate.succeed(curl_max_tls1_2_intermediate_cipher) - server_intermediate.fail(curl_max_tls1_2_old_cipher) + server_intermediate.succeed(curl_max_tls1_2.format(port="${intermediatePortStr}")) + server_intermediate.succeed(curl_max_tls1_2_intermediate_cipher.format(port="${intermediatePortStr}")) + server_intermediate.fail(curl_max_tls1_2_old_cipher.format(port="${intermediatePortStr}")) server_old.wait_for_unit("h2o.service") - server_old.wait_for_open_port(${portStr}) - old_response = server_old.succeed(curl_basic) + server_old.wait_for_open_port(${oldPortStr}) + old_response = server_old.succeed(curl_basic.format(port="${oldPortStr}")) assert "Hello, old!" in old_response - old_head = server_modern.succeed(curl_head) + old_head = server_modern.succeed(curl_head.format(port="${oldPortStr}")) assert "strict-transport-security" in old_head - server_old.succeed(curl_max_tls1_2) - server_old.succeed(curl_max_tls1_2_intermediate_cipher) - server_old.succeed(curl_max_tls1_2_old_cipher) + server_old.succeed(curl_max_tls1_2.format(port="${oldPortStr}")) + server_old.succeed(curl_max_tls1_2_intermediate_cipher.format(port="${oldPortStr}")) + server_old.succeed(curl_max_tls1_2_old_cipher.format(port="${oldPortStr}")) ''; } From cb89189157d6db26a9eb37b155defee5a6a9a1a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=B7=F0=90=91=91=F0=90=91=B4=F0=90=91=95=F0=90=91=91?= =?UTF-8?q?=F0=90=91=A9=F0=90=91=A4?= Date: Sun, 9 Nov 2025 13:21:23 +0700 Subject: [PATCH 2/2] nixos/tests/h2o: use client to check + start_all() machines --- nixos/tests/web-servers/h2o/basic.nix | 46 +++++++++++++------ nixos/tests/web-servers/h2o/mruby.nix | 23 +++++++--- .../web-servers/h2o/tls-recommendations.nix | 4 ++ 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/nixos/tests/web-servers/h2o/basic.nix b/nixos/tests/web-servers/h2o/basic.nix index 9b67f3397536..6c8c863475c0 100644 --- a/nixos/tests/web-servers/h2o/basic.nix +++ b/nixos/tests/web-servers/h2o/basic.nix @@ -36,12 +36,8 @@ in nodes = { server = - { pkgs, config, ... }: + { config, ... }: { - environment.systemPackages = [ - pkgs.curl - ]; - services.h2o = { enable = true; defaultHTTPListenPort = 8080; @@ -111,12 +107,30 @@ in ]; }; extraHosts = '' - 127.0.0.1 ${domain.HTTP} - 127.0.0.1 ${domain.TLS} + ${config.networking.primaryIPAddress} ${domain.HTTP} + ${config.networking.primaryIPAddress} ${domain.TLS} ''; }; }; + + client = + { nodes, pkgs, ... }: + { + environment.systemPackages = [ + pkgs.curl + ]; + + security.pki.certificates = [ + (builtins.readFile ../../common/acme/server/ca.cert.pem) + ]; + + networking.extraHosts = '' + ${nodes.server.networking.primaryIPAddress} ${domain.HTTP} + ${nodes.server.networking.primaryIPAddress} ${domain.TLS} + ''; + }; }; + testScript = { nodes, ... }: let @@ -126,30 +140,32 @@ in in # python '' + start_all() + server.wait_for_unit("h2o.service") server.wait_for_open_port(${portStrHTTP}) server.wait_for_open_port(${portStrTLS}) - assert "${sawatdi_chao_lok}" in server.succeed("curl --fail-with-body 'http://${domain.HTTP}:${portStrHTTP}/hello_world.txt'") + assert "${sawatdi_chao_lok}" in client.succeed("curl --fail-with-body 'http://${domain.HTTP}:${portStrHTTP}/hello_world.txt'") - tls_hello_world_head = server.succeed("curl -v --head --compressed --http2 --tlsv1.3 --fail-with-body 'https://${domain.TLS}:${portStrTLS}/hello_world.rst'").lower() + tls_hello_world_head = client.succeed("curl -v --head --compressed --http2 --tlsv1.3 --fail-with-body 'https://${domain.TLS}:${portStrTLS}/hello_world.rst'").lower() assert "http/2 200" in tls_hello_world_head assert "server: h2o" in tls_hello_world_head assert "content-type: text/x-rst" in tls_hello_world_head - assert "${sawatdi_chao_lok}" in server.succeed("curl -v --http2 --tlsv1.3 --compressed --fail-with-body 'https://${domain.TLS}:${portStrTLS}/hello_world.rst'") + assert "${sawatdi_chao_lok}" in client.succeed("curl -v --http2 --tlsv1.3 --compressed --fail-with-body 'https://${domain.TLS}:${portStrTLS}/hello_world.rst'") - quic_hello_world_head = server.succeed("curl -v --head --compressed --http3-only --fail-with-body 'https://${domain.TLS}:${portStrTLS}/hello_world.rst'").lower() + quic_hello_world_head = client.succeed("curl -v --head --compressed --http3-only --fail-with-body 'https://${domain.TLS}:${portStrTLS}/hello_world.rst'").lower() assert "http/3 200" in quic_hello_world_head assert "server: h2o" in quic_hello_world_head assert "content-type: text/x-rst" in quic_hello_world_head - assert "${sawatdi_chao_lok}" in server.succeed("curl -v --http3-only --compressed --fail-with-body 'https://${domain.TLS}:${portStrTLS}/hello_world.rst'") + assert "${sawatdi_chao_lok}" in client.succeed("curl -v --http3-only --compressed --fail-with-body 'https://${domain.TLS}:${portStrTLS}/hello_world.rst'") - assert "redirected" in server.succeed("curl -v --head --fail-with-body 'http://${domain.TLS}:${portStrHTTP}/hello_world.rst'").lower() + assert "redirected" in client.succeed("curl -v --head --fail-with-body 'http://${domain.TLS}:${portStrHTTP}/hello_world.rst'").lower() - server.fail("curl --location --max-redirs 0 'http://${domain.TLS}:${portStrHTTP}/hello_world.rst'") + client.fail("curl --location --max-redirs 0 'http://${domain.TLS}:${portStrHTTP}/hello_world.rst'") - assert "${sawatdi_chao_lok}" in server.succeed("curl -v --location --fail-with-body 'http://${domain.TLS}:${portStrHTTP}/hello_world.rst'") + assert "${sawatdi_chao_lok}" in client.succeed("curl -v --location --fail-with-body 'http://${domain.TLS}:${portStrHTTP}/hello_world.rst'") ''; } diff --git a/nixos/tests/web-servers/h2o/mruby.nix b/nixos/tests/web-servers/h2o/mruby.nix index 803e6c96de83..c9a4d95c056b 100644 --- a/nixos/tests/web-servers/h2o/mruby.nix +++ b/nixos/tests/web-servers/h2o/mruby.nix @@ -14,7 +14,7 @@ in nodes = { server = - { pkgs, ... }: + { pkgs, config, ... }: { services.h2o = { enable = true; @@ -41,9 +41,17 @@ in }; }; - networking.extraHosts = '' - 127.0.0.1 ${domain} - ''; + networking.firewall.allowedTCPPorts = [ + config.services.h2o.settings.listen + ]; + }; + + client = + { pkgs, ... }: + { + environment.systemPackages = [ + pkgs.curl + ]; }; }; @@ -52,14 +60,17 @@ in let inherit (nodes) server; portStr = builtins.toString server.services.h2o.settings.listen; + origin = "http://server:${portStr}"; in # python '' + start_all() + server.wait_for_unit("h2o.service") server.wait_for_open_port(${portStr}) - assert "${sawatdi_chao_lok}" in server.succeed("curl --fail-with-body http://${domain}:${portStr}/hello_world") + assert "${sawatdi_chao_lok}" in client.succeed("curl --fail-with-body ${origin}/hello_world") - assert "FILE_HANDLER" in server.succeed("curl --fail-with-body http://${domain}:${portStr}/file_handler") + assert "FILE_HANDLER" in client.succeed("curl --fail-with-body ${origin}/file_handler") ''; } diff --git a/nixos/tests/web-servers/h2o/tls-recommendations.nix b/nixos/tests/web-servers/h2o/tls-recommendations.nix index be80b9ee9e38..0fca6dbbb1b9 100644 --- a/nixos/tests/web-servers/h2o/tls-recommendations.nix +++ b/nixos/tests/web-servers/h2o/tls-recommendations.nix @@ -78,6 +78,8 @@ in maintainers = with lib.maintainers; [ toastal ]; }; + # not using a `client` since it’s easiest to test with acme.test pointing at + # localhost for these machines nodes = { server_modern = mkH2OServer "modern"; server_intermediate = mkH2OServer "intermediate"; @@ -100,6 +102,8 @@ in curl_max_tls1_2_intermediate_cipher ="curl -v --tlsv1.0 --tls-max 1.2 --ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256' 'https://${domain}:{port}/'" curl_max_tls1_2_old_cipher ="curl -v --tlsv1.0 --tls-max 1.2 --ciphers 'ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256' 'https://${domain}:{port}/'" + start_all() + server_modern.wait_for_unit("h2o.service") server_modern.wait_for_open_port(${modernPortStr}) modern_response = server_modern.succeed(curl_basic.format(port="${modernPortStr}"))