scripts/check-public-tunnel.py
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env python3
"""Check public Firecrab Tunnel routing without tokens or state changes.
This is a preflight only. It does not create an address, connect an app, or
prove that public traffic reaches a VM.
"""
import argparse
import contextlib
import http.client
import json
import socket
import ssl
import sys
import uuid
DOMAIN = "firecrab.dev"
CONSOLE = "console." + DOMAIN
REGISTRATION = "tunnel." + DOMAIN
MAX_RESPONSE = 8192
class CheckError(Exception):
"""A public preflight did not establish the expected behavior."""
def check_dns(host):
try:
addresses = socket.getaddrinfo(host, 443, type=socket.SOCK_STREAM)
except OSError as error:
raise CheckError(f"DNS lookup failed for {host}") from error
if not addresses:
raise CheckError(f"DNS returned no addresses for {host}")
def check_https(host, path, expected_status, *, headers=None, json_error=False):
# Default TLS verification checks both the certificate chain and hostname.
try:
with contextlib.closing(http.client.HTTPSConnection(
host, timeout=10, context=ssl.create_default_context()
)) as connection:
connection.request("GET", path, headers=headers or {})
response = connection.getresponse()
status = response.status
content_type = response.getheader("Content-Type", "").split(";", 1)[0].lower()
body = response.read(MAX_RESPONSE + 1) if json_error else b""
except (OSError, ssl.SSLError, http.client.HTTPException) as error:
raise CheckError(f"HTTPS request failed for {host}") from error
if status != expected_status:
raise CheckError(f"{host}{path} returned HTTP {status}, expected {expected_status}")
if len(body) > MAX_RESPONSE:
raise CheckError(f"{host}{path} returned an oversized response")
if json_error:
try:
payload = json.loads(body)
except (ValueError, UnicodeError) as error:
raise CheckError(f"{host}{path} did not return JSON") from error
if content_type != "application/json" or not isinstance(payload, dict) or not isinstance(payload.get("error"), str):
raise CheckError(f"{host}{path} did not return the expected error response")
return status
def preflight():
# A fresh unregistered name tests wildcard DNS/TLS and the missing-address
# response without disclosing or modifying another user's reservation.
unknown = "qa-" + uuid.uuid4().hex + "." + DOMAIN
for host in (CONSOLE, REGISTRATION, unknown):
check_dns(host)
check_https(CONSOLE, "/", 200)
check_https(REGISTRATION, "/v1/register", 405,
headers={"X-Firecrab-Protocol": "2"}, json_error=True)
check_https(unknown, "/", 404, json_error=True)
return {
"consoleHttps": "passed",
"registrationHttps": "passed",
"wildcardDnsAndHttps": "passed",
"publicApplicationAcceptance": "not_run",
}
def main():
argparse.ArgumentParser(description=__doc__).parse_args()
try:
result = preflight()
except CheckError as error:
print(f"Public Tunnel preflight failed: {error}", file=sys.stderr)
return 1
print(json.dumps(result, sort_keys=True))
return 0
if __name__ == "__main__":
sys.exit(main())