at master 3.3 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 domain = "example.test"; 9 10 dnsServerIP = nodes: nodes.dnsserver.networking.primaryIPAddress; 11 12 dnsScript = pkgs.writeShellScript "dns-hook.sh" '' 13 set -euo pipefail 14 echo '[INFO]' "[$2]" 'dns-hook.sh' $* 15 if [ "$1" = "present" ]; then 16 ${pkgs.curl}/bin/curl --data @- http://dnsserver.test:8055/set-txt << EOF 17 {"host": "$2", "value": "$3"} 18 EOF 19 else 20 ${pkgs.curl}/bin/curl --data @- http://dnsserver.test:8055/clear-txt << EOF 21 {"host": "$2"} 22 EOF 23 fi 24 ''; 25in 26{ 27 name = "dns01"; 28 meta = { 29 maintainers = lib.teams.acme.members; 30 # Hard timeout in seconds. Average run time is about 60 seconds. 31 timeout = 180; 32 }; 33 34 nodes = { 35 # The fake ACME server which will respond to client requests 36 acme = 37 { nodes, ... }: 38 { 39 imports = [ ../common/acme/server ]; 40 networking.nameservers = lib.mkForce [ (dnsServerIP nodes) ]; 41 }; 42 43 # A fake DNS server which can be configured with records as desired 44 # Used to test DNS-01 challenge 45 dnsserver = 46 { nodes, ... }: 47 { 48 networking = { 49 firewall.allowedTCPPorts = [ 50 8055 51 53 52 ]; 53 firewall.allowedUDPPorts = [ 53 ]; 54 55 # nixos/lib/testing/network.nix will provide name resolution via /etc/hosts 56 # for all nodes based on their host names and domain 57 hostName = "dnsserver"; 58 domain = "test"; 59 }; 60 systemd.services.pebble-challtestsrv = { 61 enable = true; 62 description = "Pebble ACME challenge test server"; 63 wantedBy = [ "network.target" ]; 64 serviceConfig = { 65 ExecStart = "${pkgs.pebble}/bin/pebble-challtestsrv -dns01 ':53' -defaultIPv6 '' -defaultIPv4 '${nodes.client.networking.primaryIPAddress}'"; 66 # Required to bind on privileged ports. 67 AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; 68 }; 69 }; 70 }; 71 72 client = 73 { nodes, ... }: 74 { 75 imports = [ ../common/acme/client ]; 76 networking.domain = domain; 77 networking.nameservers = lib.mkForce [ (dnsServerIP nodes) ]; 78 79 # OpenSSL will be used for more thorough certificate validation 80 environment.systemPackages = [ pkgs.openssl ]; 81 82 security.acme.certs."${domain}" = { 83 domain = "*.${domain}"; 84 dnsProvider = "exec"; 85 dnsPropagationCheck = false; 86 environmentFile = pkgs.writeText "wildcard.env" '' 87 EXEC_PATH=${dnsScript} 88 EXEC_POLLING_INTERVAL=1 89 EXEC_PROPAGATION_TIMEOUT=1 90 EXEC_SEQUENCE_INTERVAL=1 91 ''; 92 }; 93 }; 94 }; 95 96 testScript = '' 97 ${(import ./utils.nix).pythonUtils} 98 99 cert = "${domain}" 100 101 dnsserver.start() 102 acme.start() 103 104 wait_for_running(dnsserver) 105 dnsserver.wait_for_open_port(53) 106 wait_for_running(acme) 107 acme.wait_for_open_port(443) 108 109 with subtest("Boot and acquire a new cert"): 110 client.start() 111 wait_for_running(client) 112 113 check_issuer(client, cert, "pebble") 114 check_domain(client, cert, cert, fail=True) 115 check_domain(client, cert, f"toodeep.nesting.{cert}", fail=True) 116 check_domain(client, cert, f"whatever.{cert}") 117 ''; 118}