lol

nixosTests.curl-impersonate: init

+161
+1
nixos/tests/all-tests.nix
··· 156 156 couchdb = handleTest ./couchdb.nix {}; 157 157 cri-o = handleTestOn ["aarch64-linux" "x86_64-linux"] ./cri-o.nix {}; 158 158 cups-pdf = handleTest ./cups-pdf.nix {}; 159 + curl-impersonate = handleTest ./curl-impersonate.nix {}; 159 160 custom-ca = handleTest ./custom-ca.nix {}; 160 161 croc = handleTest ./croc.nix {}; 161 162 deluge = handleTest ./deluge.nix {};
+157
nixos/tests/curl-impersonate.nix
··· 1 + /* 2 + Test suite for curl-impersonate 3 + 4 + Abstract: 5 + Uses the test suite from the curl-impersonate source repo which: 6 + 7 + 1. Performs requests with libcurl and captures the TLS client-hello 8 + packets with tcpdump to compare against known-good signatures 9 + 2. Spins up an nghttpd2 server to test client HTTP/2 headers against 10 + known-good headers 11 + 12 + See https://github.com/lwthiker/curl-impersonate/tree/main/tests/signatures 13 + for details. 14 + 15 + Notes: 16 + - We need to have our own web server running because the tests expect to be able 17 + to hit domains like wikipedia.org and the sandbox has no internet 18 + - We need to be able to do (verifying) TLS handshakes without internet access. 19 + We do that by creating a trusted CA and issuing a cert that includes 20 + all of the test domains as subject-alternative names and then spoofs the 21 + hostnames in /etc/hosts. 22 + */ 23 + 24 + import ./make-test-python.nix ({ pkgs, lib, ... }: let 25 + # Update with domains in TestImpersonate.TEST_URLS if needed from: 26 + # https://github.com/lwthiker/curl-impersonate/blob/main/tests/test_impersonate.py 27 + domains = [ 28 + "www.wikimedia.org" 29 + "www.wikipedia.org" 30 + "www.mozilla.org" 31 + "www.apache.org" 32 + "www.kernel.org" 33 + "git-scm.com" 34 + ]; 35 + 36 + tls-certs = let 37 + # Configure CA with X.509 v3 extensions that would be trusted by curl 38 + ca-cert-conf = pkgs.writeText "curl-impersonate-ca.cnf" '' 39 + basicConstraints = critical, CA:TRUE 40 + subjectKeyIdentifier = hash 41 + authorityKeyIdentifier = keyid:always, issuer:always 42 + keyUsage = critical, cRLSign, digitalSignature, keyCertSign 43 + ''; 44 + 45 + # Configure leaf certificate with X.509 v3 extensions that would be trusted 46 + # by curl and set subject-alternative names for test domains 47 + tls-cert-conf = pkgs.writeText "curl-impersonate-tls.cnf" '' 48 + basicConstraints = critical, CA:FALSE 49 + subjectKeyIdentifier = hash 50 + authorityKeyIdentifier = keyid:always, issuer:always 51 + keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment, keyAgreement 52 + extendedKeyUsage = critical, serverAuth 53 + subjectAltName = @alt_names 54 + 55 + [alt_names] 56 + ${lib.concatStringsSep "\n" (lib.imap0 (idx: domain: "DNS.${toString idx} = ${domain}") domains)} 57 + ''; 58 + in pkgs.runCommand "curl-impersonate-test-certs" { 59 + nativeBuildInputs = [ pkgs.openssl ]; 60 + } '' 61 + # create CA certificate and key 62 + openssl req -newkey rsa:4096 -keyout ca-key.pem -out ca-csr.pem -nodes -subj '/CN=curl-impersonate-ca.nixos.test' 63 + openssl x509 -req -sha512 -in ca-csr.pem -key ca-key.pem -out ca.pem -extfile ${ca-cert-conf} -days 36500 64 + openssl x509 -in ca.pem -text 65 + 66 + # create server certificate and key 67 + openssl req -newkey rsa:4096 -keyout key.pem -out csr.pem -nodes -subj '/CN=curl-impersonate.nixos.test' 68 + openssl x509 -req -sha512 -in csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile ${tls-cert-conf} -days 36500 69 + openssl x509 -in cert.pem -text 70 + 71 + # output CA cert and server cert and key 72 + mkdir -p $out 73 + cp key.pem cert.pem ca.pem $out 74 + ''; 75 + 76 + # Test script 77 + curl-impersonate-test = let 78 + # Build miniature libcurl client used by test driver 79 + minicurl = pkgs.runCommandCC "minicurl" { 80 + buildInputs = [ pkgs.curl ]; 81 + } '' 82 + mkdir -p $out/bin 83 + $CC -Wall -Werror -o $out/bin/minicurl ${pkgs.curl-impersonate.src}/tests/minicurl.c `curl-config --libs` 84 + ''; 85 + in pkgs.writeShellScript "curl-impersonate-test" '' 86 + set -euxo pipefail 87 + 88 + # Test driver requirements 89 + export PATH="${with pkgs; lib.makeBinPath [ 90 + bash 91 + coreutils 92 + python3Packages.pytest 93 + nghttp2 94 + tcpdump 95 + ]}" 96 + export PYTHONPATH="${with pkgs.python3Packages; makePythonPath [ 97 + pyyaml 98 + pytest-asyncio 99 + dpkt 100 + ]}" 101 + 102 + # Prepare test root prefix 103 + mkdir -p usr/{bin,lib} 104 + cp -rs ${pkgs.curl-impersonate}/* ${minicurl}/* usr/ 105 + 106 + cp -r ${pkgs.curl-impersonate.src}/tests ./ 107 + 108 + # Run tests 109 + cd tests 110 + pytest . --install-dir ../usr --capture-interface eth1 111 + ''; 112 + in { 113 + name = "curl-impersonate"; 114 + 115 + meta = with lib.maintainers; { 116 + maintainers = [ lilyinstarlight ]; 117 + }; 118 + 119 + nodes = { 120 + web = { nodes, pkgs, lib, config, ... }: { 121 + networking.firewall.allowedTCPPorts = [ 80 443 ]; 122 + 123 + services = { 124 + nginx = { 125 + enable = true; 126 + virtualHosts."curl-impersonate.nixos.test" = { 127 + default = true; 128 + addSSL = true; 129 + sslCertificate = "${tls-certs}/cert.pem"; 130 + sslCertificateKey = "${tls-certs}/key.pem"; 131 + }; 132 + }; 133 + }; 134 + }; 135 + 136 + curl = { nodes, pkgs, lib, config, ... }: { 137 + networking.extraHosts = lib.concatStringsSep "\n" (map (domain: "${nodes.web.networking.primaryIPAddress} ${domain}") domains); 138 + 139 + security.pki.certificateFiles = [ "${tls-certs}/ca.pem" ]; 140 + }; 141 + }; 142 + 143 + testScript = { nodes, ... }: '' 144 + start_all() 145 + 146 + with subtest("Wait for network"): 147 + web.wait_for_unit("network-online.target") 148 + curl.wait_for_unit("network-online.target") 149 + 150 + with subtest("Wait for web server"): 151 + web.wait_for_unit("nginx.service") 152 + web.wait_for_open_port(443) 153 + 154 + with subtest("Run curl-impersonate tests"): 155 + curl.succeed("${curl-impersonate-test}") 156 + ''; 157 + })
+3
pkgs/tools/networking/curl-impersonate/default.nix
··· 20 20 , unzip 21 21 , go 22 22 , p11-kit 23 + , nixosTests 23 24 }: 24 25 25 26 let ··· 179 180 updateScript = ./update.sh; 180 181 181 182 inherit (passthru.curl-impersonate-ff) src; 183 + 184 + tests = { inherit (nixosTests) curl-impersonate; }; 182 185 }; 183 186 }