#!/usr/bin/env python3 """Fix exposedgays.com 404: route via direct A record like thepinkpulse.com.""" import json import re import time import urllib.error import urllib.request import paramiko PASS = "Bbt9115xty9176!" ZID = "b9e032992b315331c8b0571473fedc89" ORIGIN_IP = "68.248.192.234" HOSTS = ["exposedgays.com", "www.exposedgays.com"] CF = "https://api.cloudflare.com/client/v4" def get_token(): 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() text = (o.read() + e.read()).decode() c.close() return re.search(r"CLOUDFLARE_API_TOKEN=([^\s\"']+)", text).group(1) def cf(token, 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 {token}", "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: return e.code, json.loads(e.read().decode()) def ssh_check(): c = paramiko.SSHClient() c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) c.connect("10.10.0.10", username="localadministrator", password=PASS, timeout=30) cmds = [ "curl -sSI --max-time 20 https://exposedgays.com/ | head -12", "curl -sSI --max-time 20 https://www.exposedgays.com/ | head -12", "curl -sSL --max-time 20 https://exposedgays.com/ | head -c 200", ] out = [] for cmd in cmds: _, o, e = c.exec_command(cmd, timeout=35) o.channel.recv_exit_status() out.append(f"$ {cmd}\n" + (o.read() + e.read()).decode(errors="replace")[:1500]) c.close() return "\n\n".join(out) def main(): token = get_token() code, recs_body = cf(token, f"/zones/{ZID}/dns_records?per_page=100") if not recs_body.get("success"): raise SystemExit(f"list records failed: {recs_body.get('errors')}") records = recs_body["result"] for name in HOSTS: body = {"type": "A", "name": name, "content": ORIGIN_IP, "ttl": 1, "proxied": True} existing = next( (r for r in records if r["name"] == name and r["type"] in ("A", "CNAME", "AAAA")), None, ) if existing: code, res = cf(token, f"/zones/{ZID}/dns_records/{existing['id']}", "PATCH", body) action = "PATCH" else: code, res = cf(token, f"/zones/{ZID}/dns_records", "POST", body) action = "POST" print(f"{action} {name}: HTTP {code} success={res.get('success')} errors={res.get('errors')}") if not res.get("success"): raise SystemExit(1) print("\nFinal apex/www records:") _, final_body = cf(token, f"/zones/{ZID}/dns_records?per_page=100") for r in final_body.get("result", []): if r["name"] in HOSTS: print(f" {r['type']} {r['name']} -> {r['content']} proxied={r.get('proxied')}") print("\nWaiting 15s for DNS/proxy propagation...") time.sleep(15) print("\n=== verify ===") print(ssh_check()) return 0 if __name__ == "__main__": raise SystemExit(main())