hake89/openclaw-cf2
0
1#!/usr/bin/env python32"""3DNS-over-HTTPS resolver for HF Spaces.4 5HF Spaces containers cannot resolve certain domains (e.g. web.whatsapp.com)6via the default DNS resolver. This script resolves key domains using7Cloudflare DoH (DNS-over-HTTPS) and writes results to a JSON file8for the Node.js DNS fix script to consume.9 10Usage: python3 dns-resolve.py [output-file]11"""12 13import json14import os15import ssl16import sys17import urllib.request18 19DOH_ENDPOINTS = [20 "https://1.1.1.1/dns-query", # Cloudflare21 "https://8.8.8.8/resolve", # Google22 "https://dns.google/resolve", # Google (hostname)23]24 25# Domains that WhatsApp/Baileys and Telegram need to connect to26DOMAINS = [27 # WhatsApp / Baileys28 "web.whatsapp.com",29 "g.whatsapp.net",30 "mmg.whatsapp.net",31 "pps.whatsapp.net",32 "static.whatsapp.net",33 "media.fmed1-1.fna.whatsapp.net",34 # Telegram Bot API35 "api.telegram.org",36]37 38 39def resolve_via_doh(domain: str, endpoint: str, timeout: int = 10) -> list[str]:40 """Resolve a domain via DNS-over-HTTPS, return list of IPv4 addresses."""41 url = f"{endpoint}?name={domain}&type=A"42 req = urllib.request.Request(url, headers={"Accept": "application/dns-json"})43 44 ctx = ssl.create_default_context()45 resp = urllib.request.urlopen(req, timeout=timeout, context=ctx)46 data = json.loads(resp.read().decode())47 48 ips = []49 for answer in data.get("Answer", []):50 if answer.get("type") == 1: # A record51 ips.append(answer["data"])52 elif answer.get("type") == 5: # CNAME — follow chain53 continue54 return ips55 56 57def resolve_domain(domain: str) -> list[str]:58 """Try multiple DoH endpoints until one succeeds."""59 for endpoint in DOH_ENDPOINTS:60 try:61 ips = resolve_via_doh(domain, endpoint)62 if ips:63 return ips64 except Exception:65 continue66 return []67 68 69def main() -> None:70 output_file = sys.argv[1] if len(sys.argv) > 1 else "/tmp/dns-resolved.json"71 72 # First check if system DNS works at all73 try:74 import socket75 socket.getaddrinfo("web.whatsapp.com", 443, socket.AF_INET)76 socket.getaddrinfo("api.telegram.org", 443, socket.AF_INET)77 print("[dns] System DNS works for WhatsApp & Telegram — DoH not needed")78 # Write empty file so dns-fix.cjs knows it's not needed79 with open(output_file, "w") as f:80 json.dump({}, f)81 return82 except (socket.gaierror, OSError) as e:83 print(f"[dns] System DNS failed ({e}) — using DoH fallback")84 85 results = {}86 for domain in DOMAINS:87 ips = resolve_domain(domain)88 if ips:89 results[domain] = ips[0]90 print(f"[dns] {domain} -> {ips[0]}")91 else:92 print(f"[dns] WARNING: could not resolve {domain}")93 94 with open(output_file, "w") as f:95 json.dump(results, f, indent=2)96 97 # Also write to /etc/hosts so undici/fetch (which bypasses dns.lookup) works98 if results:99 try:100 with open("/etc/hosts", "a") as f:101 f.write("\n# === HuggingClaw DoH resolved domains ===\n")102 for domain, ip in results.items():103 f.write(f"{ip} {domain}\n")104 print(f"[dns] Wrote {len(results)} entries to /etc/hosts")105 except PermissionError:106 print("[dns] WARNING: cannot write /etc/hosts (permission denied)")107 108 print(f"[dns] Resolved {len(results)}/{len(DOMAINS)} domains -> {output_file}")109 110 111if __name__ == "__main__":112 main()113 