1
0
Fork 1
mirror of https://github.com/NixOS/nixpkgs.git synced 2024-12-25 03:17:13 +00:00
nixpkgs/nixos/tests/curl-impersonate.nix
Silvan Mosberger 4f0dadbf38 treewide: format all inactive Nix files
After final improvements to the official formatter implementation,
this commit now performs the first treewide reformat of Nix files using it.
This is part of the implementation of RFC 166.

Only "inactive" files are reformatted, meaning only files that
aren't being touched by any PR with activity in the past 2 months.
This is to avoid conflicts for PRs that might soon be merged.
Later we can do a full treewide reformat to get the rest,
which should not cause as many conflicts.

A CI check has already been running for some time to ensure that new and
already-formatted files are formatted, so the files being reformatted here
should also stay formatted.

This commit was automatically created and can be verified using

    nix-build a08b3a4d19.tar.gz \
      --argstr baseRev b32a094368
    result/bin/apply-formatting $NIXPKGS_PATH
2024-12-10 20:26:33 +01:00

203 lines
6.1 KiB
Nix

/*
Test suite for curl-impersonate
Abstract:
Uses the test suite from the curl-impersonate source repo which:
1. Performs requests with libcurl and captures the TLS client-hello
packets with tcpdump to compare against known-good signatures
2. Spins up an nghttpd2 server to test client HTTP/2 headers against
known-good headers
See https://github.com/lwthiker/curl-impersonate/tree/main/tests/signatures
for details.
Notes:
- We need to have our own web server running because the tests expect to be able
to hit domains like wikipedia.org and the sandbox has no internet
- We need to be able to do (verifying) TLS handshakes without internet access.
We do that by creating a trusted CA and issuing a cert that includes
all of the test domains as subject-alternative names and then spoofs the
hostnames in /etc/hosts.
*/
import ./make-test-python.nix (
{ pkgs, lib, ... }:
let
# Update with domains in TestImpersonate.TEST_URLS if needed from:
# https://github.com/lwthiker/curl-impersonate/blob/main/tests/test_impersonate.py
domains = [
"www.wikimedia.org"
"www.wikipedia.org"
"www.mozilla.org"
"www.apache.org"
"www.kernel.org"
"git-scm.com"
];
tls-certs =
let
# Configure CA with X.509 v3 extensions that would be trusted by curl
ca-cert-conf = pkgs.writeText "curl-impersonate-ca.cnf" ''
basicConstraints = critical, CA:TRUE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer:always
keyUsage = critical, cRLSign, digitalSignature, keyCertSign
'';
# Configure leaf certificate with X.509 v3 extensions that would be trusted
# by curl and set subject-alternative names for test domains
tls-cert-conf = pkgs.writeText "curl-impersonate-tls.cnf" ''
basicConstraints = critical, CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer:always
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment, keyAgreement
extendedKeyUsage = critical, serverAuth
subjectAltName = @alt_names
[alt_names]
${lib.concatStringsSep "\n" (lib.imap0 (idx: domain: "DNS.${toString idx} = ${domain}") domains)}
'';
in
pkgs.runCommand "curl-impersonate-test-certs"
{
nativeBuildInputs = [ pkgs.openssl ];
}
''
# create CA certificate and key
openssl req -newkey rsa:4096 -keyout ca-key.pem -out ca-csr.pem -nodes -subj '/CN=curl-impersonate-ca.nixos.test'
openssl x509 -req -sha512 -in ca-csr.pem -key ca-key.pem -out ca.pem -extfile ${ca-cert-conf} -days 36500
openssl x509 -in ca.pem -text
# create server certificate and key
openssl req -newkey rsa:4096 -keyout key.pem -out csr.pem -nodes -subj '/CN=curl-impersonate.nixos.test'
openssl x509 -req -sha512 -in csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile ${tls-cert-conf} -days 36500
openssl x509 -in cert.pem -text
# output CA cert and server cert and key
mkdir -p $out
cp key.pem cert.pem ca.pem $out
'';
# Test script
curl-impersonate-test =
let
# Build miniature libcurl client used by test driver
minicurl =
pkgs.runCommandCC "minicurl"
{
buildInputs = [ pkgs.curl ];
}
''
mkdir -p $out/bin
$CC -Wall -Werror -o $out/bin/minicurl ${pkgs.curl-impersonate.src}/tests/minicurl.c `curl-config --libs`
'';
in
pkgs.writeShellScript "curl-impersonate-test" ''
set -euxo pipefail
# Test driver requirements
export PATH="${
with pkgs;
lib.makeBinPath [
bash
coreutils
python3Packages.pytest
nghttp2
tcpdump
]
}"
export PYTHONPATH="${
with pkgs.python3Packages;
makePythonPath [
pyyaml
pytest-asyncio
dpkt
ts1-signatures
]
}"
# Prepare test root prefix
mkdir -p usr/{bin,lib}
cp -rs ${pkgs.curl-impersonate}/* ${minicurl}/* usr/
cp -r ${pkgs.curl-impersonate.src}/tests ./
# Run tests
cd tests
pytest . --install-dir ../usr --capture-interface eth1
'';
in
{
name = "curl-impersonate";
meta = with lib.maintainers; {
maintainers = [ ];
};
nodes = {
web =
{
nodes,
pkgs,
lib,
config,
...
}:
{
networking.firewall.allowedTCPPorts = [
80
443
];
services = {
nginx = {
enable = true;
virtualHosts."curl-impersonate.nixos.test" = {
default = true;
addSSL = true;
sslCertificate = "${tls-certs}/cert.pem";
sslCertificateKey = "${tls-certs}/key.pem";
};
};
};
};
curl =
{
nodes,
pkgs,
lib,
config,
...
}:
{
networking.extraHosts = lib.concatStringsSep "\n" (
map (domain: "${nodes.web.networking.primaryIPAddress} ${domain}") domains
);
security.pki.certificateFiles = [ "${tls-certs}/ca.pem" ];
};
};
testScript =
{ nodes, ... }:
''
start_all()
with subtest("Wait for network"):
web.systemctl("start network-online.target")
curl.systemctl("start network-online.target")
web.wait_for_unit("network-online.target")
curl.wait_for_unit("network-online.target")
with subtest("Wait for web server"):
web.wait_for_unit("nginx.service")
web.wait_for_open_port(443)
with subtest("Run curl-impersonate tests"):
curl.succeed("${curl-impersonate-test}")
'';
}
)