at master 4.6 kB view raw
1{ hostPkgs, lib, ... }: 2{ 3 _class = "nixosTest"; 4 name = "ghostunnel"; 5 nodes = { 6 backend = 7 { pkgs, ... }: 8 { 9 services.nginx.enable = true; 10 services.nginx.virtualHosts."backend".root = pkgs.runCommand "webroot" { } '' 11 mkdir $out 12 echo hi >$out/hi.txt 13 ''; 14 networking.firewall.allowedTCPPorts = [ 80 ]; 15 }; 16 service = 17 { pkgs, ... }: 18 { 19 system.services."ghostunnel-plain-old" = { 20 imports = [ pkgs.ghostunnel.services.default ]; 21 ghostunnel = { 22 listen = "0.0.0.0:443"; 23 cert = "/root/service-cert.pem"; 24 key = "/root/service-key.pem"; 25 disableAuthentication = true; 26 target = "backend:80"; 27 unsafeTarget = true; 28 }; 29 }; 30 system.services."ghostunnel-client-cert" = { 31 imports = [ pkgs.ghostunnel.services.default ]; 32 ghostunnel = { 33 listen = "0.0.0.0:1443"; 34 cert = "/root/service-cert.pem"; 35 key = "/root/service-key.pem"; 36 cacert = "/root/ca.pem"; 37 target = "backend:80"; 38 allowCN = [ "client" ]; 39 unsafeTarget = true; 40 }; 41 }; 42 networking.firewall.allowedTCPPorts = [ 43 443 44 1443 45 ]; 46 }; 47 client = 48 { pkgs, ... }: 49 { 50 environment.systemPackages = [ 51 pkgs.curl 52 ]; 53 }; 54 }; 55 56 testScript = '' 57 58 # prepare certificates 59 60 def cmd(command): 61 print(f"+{command}") 62 r = os.system(command) 63 if r != 0: 64 raise Exception(f"Command {command} failed with exit code {r}") 65 66 # Create CA 67 cmd("${hostPkgs.openssl}/bin/openssl genrsa -out ca-key.pem 4096") 68 cmd("${hostPkgs.openssl}/bin/openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -subj '/C=NL/ST=Zuid-Holland/L=The Hague/O=Stevige Balken en Planken B.V./OU=OpSec/CN=Certificate Authority' -out ca.pem") 69 70 # Create service 71 cmd("${hostPkgs.openssl}/bin/openssl genrsa -out service-key.pem 4096") 72 cmd("${hostPkgs.openssl}/bin/openssl req -subj '/CN=service' -sha256 -new -key service-key.pem -out service.csr") 73 cmd("echo subjectAltName = DNS:service,IP:127.0.0.1 >> extfile.cnf") 74 cmd("echo extendedKeyUsage = serverAuth >> extfile.cnf") 75 cmd("${hostPkgs.openssl}/bin/openssl x509 -req -days 365 -sha256 -in service.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out service-cert.pem -extfile extfile.cnf") 76 77 # Create client 78 cmd("${hostPkgs.openssl}/bin/openssl genrsa -out client-key.pem 4096") 79 cmd("${hostPkgs.openssl}/bin/openssl req -subj '/CN=client' -new -key client-key.pem -out client.csr") 80 cmd("echo extendedKeyUsage = clientAuth > extfile-client.cnf") 81 cmd("${hostPkgs.openssl}/bin/openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -extfile extfile-client.cnf") 82 83 cmd("ls -al") 84 85 start_all() 86 87 # Configuration 88 service.copy_from_host("ca.pem", "/root/ca.pem") 89 service.copy_from_host("service-cert.pem", "/root/service-cert.pem") 90 service.copy_from_host("service-key.pem", "/root/service-key.pem") 91 client.copy_from_host("ca.pem", "/root/ca.pem") 92 client.copy_from_host("service-cert.pem", "/root/service-cert.pem") 93 client.copy_from_host("client-cert.pem", "/root/client-cert.pem") 94 client.copy_from_host("client-key.pem", "/root/client-key.pem") 95 96 backend.wait_for_unit("nginx.service") 97 service.wait_for_unit("multi-user.target") 98 service.wait_for_unit("multi-user.target") 99 client.wait_for_unit("multi-user.target") 100 101 # Check assumptions before the real test 102 client.succeed("bash -c 'diff <(curl -v --no-progress-meter http://backend/hi.txt) <(echo hi)'") 103 104 # Plain old simple TLS can connect, ignoring cert 105 client.succeed("bash -c 'diff <(curl -v --no-progress-meter --insecure https://service/hi.txt) <(echo hi)'") 106 107 # Plain old simple TLS provides correct signature with its cert 108 client.succeed("bash -c 'diff <(curl -v --no-progress-meter --cacert /root/ca.pem https://service/hi.txt) <(echo hi)'") 109 110 # Client can authenticate with certificate 111 client.succeed("bash -c 'diff <(curl -v --no-progress-meter --cert /root/client-cert.pem --key /root/client-key.pem --cacert /root/ca.pem https://service:1443/hi.txt) <(echo hi)'") 112 113 # Client must authenticate with certificate 114 client.fail("bash -c 'diff <(curl -v --no-progress-meter --cacert /root/ca.pem https://service:1443/hi.txt) <(echo hi)'") 115 ''; 116 117 meta.maintainers = with lib.maintainers; [ 118 roberth 119 ]; 120}