#!/usr/bin/env python3 """Verify DNS, attempt tunnel route via API endpoints we can access, restart cloudflared.""" import json import re import time import urllib.error import urllib.request import paramiko PASS = "Bbt9115xty9176!" ACCOUNT = "2599c23bbb1255dbb73e8d34b4115fda" TUNNEL = "03079a26-f14c-4622-b463-ba54a24f7472" ZID = "b9e032992b315331c8b0571473fedc89" CF = "https://api.cloudflare.com/client/v4" HOSTS = ["exposedgays.com", "www.exposedgays.com"] c = paramiko.SSHClient() c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) c.connect("10.10.0.1", username="admin", password=PASS, timeout=15) _, o, e = c.exec_command("cat /usr/local/etc/wan-dns-failover.env", timeout=30) o.channel.recv_exit_status() TOK = re.search(r"CLOUDFLARE_API_TOKEN=([^\s\"']+)", (o.read() + e.read()).decode()).group(1) c.close() def cf(path, method="GET", body=None): req = urllib.request.Request( CF + path, data=json.dumps(body).encode() if body else None, method=method, headers={"Authorization": f"Bearer {TOK}", "Content-Type": "application/json"}, ) try: with urllib.request.urlopen(req, timeout=45) as r: return r.status, json.load(r) except urllib.error.HTTPError as e: raw = e.read().decode() try: return e.code, json.loads(raw) except Exception: return e.code, {"raw": raw[:300]} # Ensure DNS records are correct (re-upsert proxied CNAMEs) print("=== CF DNS records ===") code, recs = cf(f"/zones/{ZID}/dns_records?per_page=100") records = recs.get("result", []) for name in HOSTS: body = { "type": "CNAME", "name": name, "content": f"{TUNNEL}.cfargotunnel.com", "ttl": 1, "proxied": True, } existing = next((r for r in records if r["name"] == name and r["type"] in ("A", "CNAME")), None) if existing: code, res = cf(f"/zones/{ZID}/dns_records/{existing['id']}", "PATCH", body) act = "PATCH" else: code, res = cf(f"/zones/{ZID}/dns_records", "POST", body) act = "POST" print(f" {act} {name}: HTTP {code} success={res.get('success')}") # Try teamnet hostname route endpoints (some accounts expose these) for path, method, body in [ (f"/accounts/{ACCOUNT}/teamnet/routes", "POST", {"network": "exposedgays.com", "tunnel_id": TUNNEL, "comment": "exposedgays apex"}), (f"/accounts/{ACCOUNT}/teamnet/routes", "POST", {"network": "www.exposedgays.com", "tunnel_id": TUNNEL, "comment": "exposedgays www"}), ]: code, res = cf(path, method, body) print(f"\n{method} {path}: HTTP {code} success={res.get('success')} errors={res.get('errors')}") # Restart cloudflared and verify ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect("10.10.0.10", username="localadministrator", password=PASS, timeout=30) ssh.exec_command(f"echo '{PASS}' | sudo -S systemctl restart cloudflared") time.sleep(12) cmds = [ "dig @annabel.ns.cloudflare.com exposedgays.com A +short", "dig @annabel.ns.cloudflare.com www.exposedgays.com A +short", "sudo journalctl -u cloudflared --no-pager -n 4 | grep -o 'exposedgays' | head -3 || echo NO_EXPOSEDGAYS_IN_REMOTE", "curl -sSI --max-time 25 https://exposedgays.com/ 2>&1 | head -15", "curl -sSI --max-time 25 https://www.exposedgays.com/ 2>&1 | head -15", "curl -sSL --max-time 25 https://www.exposedgays.com/ 2>&1 | head -c 400", ] for cmd in cmds: print(f"\n$ {cmd}") _, o, e = ssh.exec_command(cmd, timeout=40) o.channel.recv_exit_status() print((o.read() + e.read()).decode(errors="replace")[:2500]) ssh.close()