diff --git a/backend/app/services/yield_dns.py b/backend/app/services/yield_dns.py index d3cde49..f2b0364 100644 --- a/backend/app/services/yield_dns.py +++ b/backend/app/services/yield_dns.py @@ -29,13 +29,20 @@ class YieldDNSCheckResult: error: Optional[str] -def _resolver() -> dns.resolver.Resolver: +def _resolver(nameserver: str | None = None) -> dns.resolver.Resolver: + """Create a DNS resolver, optionally using a specific nameserver.""" r = dns.resolver.Resolver() + if nameserver: + r.nameservers = [nameserver] r.timeout = 3 r.lifetime = 5 return r +# Multiple public DNS servers to check (for propagation consistency) +PUBLIC_DNS_SERVERS = ['8.8.8.8', '8.8.4.4', '9.9.9.9', '1.1.1.1'] + + def _normalize_host(host: str) -> str: return host.rstrip(".").lower().strip() @@ -58,6 +65,23 @@ def _resolve_a(host: str) -> list[str]: return sorted({str(rr) for rr in answers}) +def _resolve_a_from_multiple_dns(host: str) -> set[str]: + """ + Resolve A records from multiple public DNS servers. + Returns the union of all IPs found (handles propagation delays). + """ + all_ips: set[str] = set() + for ns in PUBLIC_DNS_SERVERS: + try: + r = _resolver(ns) + answers = r.resolve(host, "A") + for rr in answers: + all_ips.add(str(rr)) + except Exception: + continue + return all_ips + + def verify_yield_dns(domain: str, expected_nameservers: list[str], cname_target: str) -> YieldDNSCheckResult: """ Verify that a domain is connected for Yield. @@ -84,9 +108,11 @@ def verify_yield_dns(domain: str, expected_nameservers: list[str], cname_target: ) # Option A: Direct A-record to our server IP (SIMPLEST!) + # Check multiple DNS servers to handle propagation delays try: - actual_a = _resolve_a(domain) - if YIELD_SERVER_IP in actual_a: + all_ips = _resolve_a_from_multiple_dns(domain) + actual_a = sorted(all_ips) + if YIELD_SERVER_IP in all_ips: return YieldDNSCheckResult( verified=True, method="a_record", @@ -95,8 +121,6 @@ def verify_yield_dns(domain: str, expected_nameservers: list[str], cname_target: cname_ok=False, error=None, ) - except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer): - pass except Exception as e: return YieldDNSCheckResult( verified=False,