Files
nixpkgs/nixos/tests/web-servers/h2o/tls-recommendations.nix
2025-11-10 00:07:09 +07:00

136 lines
4.8 KiB
Nix
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{ hostPkgs, lib, ... }:
let
domain = "acme.test";
hello_txt =
name:
hostPkgs.writeTextFile {
name = "/hello_${name}.txt";
text = "Hello, ${name}!";
};
mkH2OServer =
recommendations:
{
pkgs,
lib,
config,
...
}:
{
services.h2o = {
enable = true;
package = pkgs.h2o.override (
lib.optionalAttrs
(builtins.elem recommendations [
"intermediate"
"old"
])
{
openssl = pkgs.openssl_legacy;
}
);
defaultTLSRecommendations = "modern"; # prove overridden
hosts = {
"${domain}" = {
tls = {
inherit recommendations;
port = 8443;
policy = "force";
identity = [
{
key-file = ../../common/acme/server/acme.test.key.pem;
certificate-file = ../../common/acme/server/acme.test.cert.pem;
}
];
extraSettings = {
# when using common ACME certs, disable talking to CA
ocsp-update-interval = 0;
};
};
settings = {
paths."/"."file.file" = "${hello_txt recommendations}";
};
};
};
settings = {
ssl-offload = "kernel";
};
};
security.pki.certificates = [
(builtins.readFile ../../common/acme/server/ca.cert.pem)
];
networking = {
firewall.allowedTCPPorts = [
config.services.h2o.hosts.${domain}.tls.port
];
extraHosts = "127.0.0.1 ${domain}";
};
};
in
{
name = "h2o-tls-recommendations";
meta = {
maintainers = with lib.maintainers; [ toastal ];
};
# not using a `client` since its easiest to test with acme.test pointing at
# localhost for these machines
nodes = {
server_modern = mkH2OServer "modern";
server_intermediate = mkH2OServer "intermediate";
server_old = mkH2OServer "old";
};
testScript =
{ nodes, ... }:
let
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}:{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}/'"
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}"))
assert "Hello, modern!" in modern_response
modern_head = server_modern.succeed(curl_head.format(port="${modernPortStr}"))
assert "strict-transport-security" in modern_head
server_modern.fail(curl_max_tls1_2.format(port="${modernPortStr}"))
server_intermediate.wait_for_unit("h2o.service")
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.format(port="${intermediatePortStr}"))
assert "strict-transport-security" in intermediate_head
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(${oldPortStr})
old_response = server_old.succeed(curl_basic.format(port="${oldPortStr}"))
assert "Hello, old!" in old_response
old_head = server_modern.succeed(curl_head.format(port="${oldPortStr}"))
assert "strict-transport-security" in old_head
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}"))
'';
}