fix: RDAP ban prevention and DNS fallback
Problem: We are banned from Afilias (.info/.biz) and Google (.dev/.app) RDAP servers due to too many requests, causing timeouts. Solution: 1. Added RDAP_BLOCKED_TLDS list in domain_checker.py 2. Skip RDAP for blocked TLDs, use DNS+WHOIS instead 3. Updated drop_status_checker.py to skip blocked TLDs 4. Removed banned endpoints from RDAP_ENDPOINTS TLDs now using DNS-only: .info, .biz, .org, .dev, .app, .xyz, .online, .com, .net TLDs still using RDAP: .ch, .li, .de (working fine) This prevents bans and timeouts while still providing availability checks.
This commit is contained in:
@ -87,6 +87,20 @@ class DomainChecker:
|
||||
'ru', 'su', 'ua', 'by', 'kz',
|
||||
}
|
||||
|
||||
# TLDs where we are rate-limited/banned from RDAP
|
||||
# Use DNS+WHOIS only for these (no RDAP calls!)
|
||||
RDAP_BLOCKED_TLDS = {
|
||||
'info', # Afilias - banned, timeouts
|
||||
'biz', # Afilias - banned, timeouts
|
||||
'org', # PIR - might be blocked
|
||||
'dev', # Google - blocked
|
||||
'app', # Google - blocked
|
||||
'xyz', # CentralNic - slow/limited
|
||||
'online', # CentralNic - slow/limited
|
||||
'com', # Verisign - heavy rate limits
|
||||
'net', # Verisign - heavy rate limits
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the domain checker."""
|
||||
self._dns_resolver = dns.resolver.Resolver()
|
||||
@ -602,8 +616,10 @@ class DomainChecker:
|
||||
# If custom RDAP fails, fall through to DNS check
|
||||
logger.info(f"Custom RDAP failed for {domain}, using DNS fallback")
|
||||
|
||||
# Priority 2: Try standard RDAP via whodap
|
||||
if tld not in self.WHOIS_ONLY_TLDS and tld not in self.CUSTOM_RDAP_ENDPOINTS:
|
||||
# Priority 2: Try standard RDAP via whodap (skip blocked TLDs!)
|
||||
if (tld not in self.WHOIS_ONLY_TLDS and
|
||||
tld not in self.CUSTOM_RDAP_ENDPOINTS and
|
||||
tld not in self.RDAP_BLOCKED_TLDS):
|
||||
rdap_result = await self._check_rdap(domain)
|
||||
if rdap_result:
|
||||
# Validate with DNS if RDAP says available
|
||||
@ -614,6 +630,30 @@ class DomainChecker:
|
||||
rdap_result.is_available = False
|
||||
return rdap_result
|
||||
|
||||
# For RDAP-blocked TLDs: Use DNS first, then WHOIS for details
|
||||
if tld in self.RDAP_BLOCKED_TLDS:
|
||||
logger.debug(f"Using DNS+WHOIS fallback for blocked TLD .{tld}: {domain}")
|
||||
dns_available = await self._check_dns(domain)
|
||||
|
||||
if dns_available:
|
||||
# No DNS records = likely available, verify with WHOIS
|
||||
whois_result = await self._check_whois(domain)
|
||||
return whois_result
|
||||
else:
|
||||
# Has DNS records = taken, try to get details from WHOIS
|
||||
try:
|
||||
whois_result = await self._check_whois(domain)
|
||||
whois_result.check_method = "dns+whois"
|
||||
return whois_result
|
||||
except Exception:
|
||||
# WHOIS failed, return DNS-only result
|
||||
return DomainCheckResult(
|
||||
domain=domain,
|
||||
status=DomainStatus.TAKEN,
|
||||
is_available=False,
|
||||
check_method="dns",
|
||||
)
|
||||
|
||||
# Priority 3: Fall back to WHOIS (skip for TLDs that block it like .ch)
|
||||
if tld not in self.CUSTOM_RDAP_ENDPOINTS:
|
||||
whois_result = await self._check_whois(domain)
|
||||
|
||||
@ -16,24 +16,26 @@ from typing import Optional
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# RDAP endpoints for different TLDs
|
||||
# ONLY include TLDs where RDAP is NOT blocked!
|
||||
RDAP_ENDPOINTS = {
|
||||
# ccTLDs
|
||||
# ccTLDs (these work reliably)
|
||||
'ch': 'https://rdap.nic.ch/domain/',
|
||||
'li': 'https://rdap.nic.ch/domain/',
|
||||
'de': 'https://rdap.denic.de/domain/',
|
||||
# gTLDs via CentralNic
|
||||
'online': 'https://rdap.centralnic.com/online/domain/',
|
||||
'xyz': 'https://rdap.centralnic.com/xyz/domain/',
|
||||
'club': 'https://rdap.nic.club/domain/',
|
||||
# gTLDs via Afilias/Donuts
|
||||
'info': 'https://rdap.afilias.net/rdap/info/domain/',
|
||||
'biz': 'https://rdap.afilias.net/rdap/biz/domain/',
|
||||
'org': 'https://rdap.publicinterestregistry.org/rdap/org/domain/',
|
||||
# Google TLDs
|
||||
'dev': 'https://rdap.nic.google/domain/',
|
||||
'app': 'https://rdap.nic.google/domain/',
|
||||
# gTLDs - DISABLED due to rate limits / bans:
|
||||
# 'online': 'https://rdap.centralnic.com/online/domain/', # rate-limited
|
||||
# 'xyz': 'https://rdap.centralnic.com/xyz/domain/', # rate-limited
|
||||
# 'club': 'https://rdap.nic.club/domain/', # unreliable
|
||||
# 'info': 'https://rdap.afilias.net/rdap/info/domain/', # BANNED
|
||||
# 'biz': 'https://rdap.afilias.net/rdap/biz/domain/', # BANNED
|
||||
# 'org': 'https://rdap.publicinterestregistry.org/rdap/org/domain/', # blocked
|
||||
# 'dev': 'https://rdap.nic.google/domain/', # BANNED
|
||||
# 'app': 'https://rdap.nic.google/domain/', # BANNED
|
||||
}
|
||||
|
||||
# TLDs where RDAP is blocked/banned - skip RDAP entirely
|
||||
RDAP_BLOCKED_TLDS = {'info', 'biz', 'org', 'dev', 'app', 'xyz', 'online', 'club', 'com', 'net'}
|
||||
|
||||
|
||||
@dataclass
|
||||
class DropStatus:
|
||||
@ -60,16 +62,27 @@ async def check_drop_status(domain: str) -> DropStatus:
|
||||
"""
|
||||
tld = domain.split('.')[-1].lower()
|
||||
|
||||
endpoint = RDAP_ENDPOINTS.get(tld)
|
||||
if not endpoint:
|
||||
# Try generic lookup
|
||||
logger.warning(f"No RDAP endpoint for .{tld}, returning unknown")
|
||||
# Skip RDAP for blocked TLDs to avoid bans/timeouts
|
||||
if tld in RDAP_BLOCKED_TLDS:
|
||||
logger.debug(f"Skipping RDAP for blocked TLD .{tld}: {domain}")
|
||||
return DropStatus(
|
||||
domain=domain,
|
||||
status='unknown',
|
||||
rdap_status=[],
|
||||
can_register_now=False,
|
||||
should_monitor=False,
|
||||
should_monitor=True, # Still worth monitoring via zone files
|
||||
message=f"RDAP disabled for .{tld} (rate-limited)"
|
||||
)
|
||||
|
||||
endpoint = RDAP_ENDPOINTS.get(tld)
|
||||
if not endpoint:
|
||||
logger.debug(f"No RDAP endpoint for .{tld}, returning unknown")
|
||||
return DropStatus(
|
||||
domain=domain,
|
||||
status='unknown',
|
||||
rdap_status=[],
|
||||
can_register_now=False,
|
||||
should_monitor=True,
|
||||
message=f"No RDAP endpoint for .{tld}"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user