sync from local backup
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import logging
|
||||
import dns.resolver
|
||||
from django.core.cache import caches
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
default_cache = caches['default']
|
||||
|
||||
MX_CACHE_TTL = 3600 # MX 验证结果缓存1小时,避免每次请求都做慢速DNS查询
|
||||
|
||||
# 常用邮箱域名白名单:大概率可正常收发,直接放行,无需DNS查询
|
||||
COMMON_EMAIL_DOMAINS = {
|
||||
'qq.com', 'foxmail.com', '163.com', '126.com', 'yeah.net',
|
||||
'139.com', '189.cn', 'sina.com', 'sohu.com', '21cn.com',
|
||||
'gmail.com', 'googlemail.com', 'outlook.com', 'hotmail.com',
|
||||
'live.com', 'msn.com', 'icloud.com', 'me.com', 'yahoo.com',
|
||||
'proton.me', 'protonmail.com', 'gmx.com', 'gmx.net', 'aol.com', 'zoho.com',
|
||||
}
|
||||
|
||||
|
||||
def validate_email_mx(email):
|
||||
"""验证邮箱域名是否有MX记录(通过DNS MX查询),排除 null MX (MX 0 .) 的情况"""
|
||||
try:
|
||||
domain = email.split('@')[1].lower()
|
||||
except IndexError:
|
||||
return False
|
||||
|
||||
# 常用邮箱域名直接放行,免DNS查询
|
||||
if domain in COMMON_EMAIL_DOMAINS:
|
||||
return True
|
||||
|
||||
cache_key = f'mx_valid_{domain}'
|
||||
try:
|
||||
cached = default_cache.get(cache_key)
|
||||
if cached is not None:
|
||||
return cached
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
valid = _query_mx(domain)
|
||||
try:
|
||||
default_cache.set(cache_key, valid, timeout=MX_CACHE_TTL)
|
||||
except Exception:
|
||||
pass
|
||||
return valid
|
||||
|
||||
|
||||
def _query_mx(domain):
|
||||
try:
|
||||
answers = dns.resolver.resolve(domain, 'MX')
|
||||
# 检查是否是 null MX (MX 0 .) — 域名明确拒绝收件
|
||||
for answer in answers:
|
||||
exchange = answer.exchange.to_text().rstrip('.')
|
||||
if exchange: # 有真实的邮件服务器
|
||||
return True
|
||||
# 所有 MX 记录都指向空(null MX),表示不接受邮件
|
||||
logger.warning(f'[Email] Domain has null MX (rejects mail): {domain}')
|
||||
return False
|
||||
except (dns.resolver.NoAnswer, dns.resolver.NXDOMAIN, dns.resolver.NoNameservers):
|
||||
logger.warning(f'[Email] No MX record found for domain: {domain}')
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.warning(f'[Email] MX record check failed: domain={domain}, error={str(e)}')
|
||||
return False
|
||||
Reference in New Issue
Block a user