脚本如何精准识别网络封锁?
📚 目录导读
- 域名被墙的真相 – 什么是“墙”?常见封锁类型解析
- 手动检测的痛点 – 从IP测到DNS,为什么手动效率低?
- 自动检测脚本原理 – 四大核心机制:TCP/HTTP/DNS/ICMP
- 主流脚本工具对比 – 开源方案 vs 商业服务谁更优?
- 实战:从零搭建检测脚本 – Python+多线程+代理池实现
- 常见陷阱与解决方案 – 误报、封禁IP、CDN干扰如何避免?
- Q&A问答专区 – 用户最关心的5个问题
域名被墙的真相
在中国大陆,所有境外网络流量需通过国家防火墙,当某个域名被判定为“非法”时,防火墙会执行以下操作之一:

- DNS污染:将域名解析至错误的IP(如返回虚假地址或劫持到钓鱼页面)
- IP封锁:直接阻断所有对该IP的访问(即使使用正确IP也无法连接)
- HTTP阻断:检测到域名关键词后,返回虚假证书或重置连接(RST)
关键点:被墙的域名并非完全无法访问,但中国境内用户无法正常访问(境外用户仍可访问),脚本的使命就是模拟中国境内用户,精确检测域名是否被封锁。
手动检测的痛点
传统手动检测方法包括:
- 浏览器测试:打开网页看是否弹出“无法访问此网站”
- Ping测试:检查丢包率(但防火墙可能只阻断HTTP而非ICMP)
- 在线检测工具:使用 whatsmydns.net 等网站查看解析结果
痛点:
- 效率低:单个域名需多次测试,批量时需重复操作
- 不全面:仅测试一种检测方式可能漏判(例如Ping成功但HTTP被墙)
- 地域限制:境外节点测试无意义,必须用国内服务器
- 结果不稳定:防火墙策略动态变化,手动测试无法捕捉细节
- 无法自动化:无法集成到CI/CD或监控系统中
手动检测只适合临时验证,批量域名管理必须借助脚本自动化。
自动检测脚本原理
一个合格的自动检测脚本需要结合以下四大检测机制:
1 TCP连接检测
原理:尝试与域名的80/443端口建立TCP连接,如果超时或收到RST包,说明该端口被封锁。
代码示例(Python):
import socket
def check_tcp(domain, port=443, timeout=5):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout)
sock.connect((socket.gethostbyname(domain), port))
return True
except Exception as e:
return False
2 HTTP(S)请求检测
原理:发送GET请求到域名,检查返回的HTTP状态码、证书信息、响应内容。
关键点:
- 被墙域名常见返回:
Connection reset by peer、SSL_ERROR_BAD_CERT_DOMAIN - 需使用中国大陆IP发起请求(否则结果无效)
3 DNS解析检测
原理:对比本地DNS(如114.114.114.114)和公共DNS(如8.8.8.8)的解析结果。
现象:
- DNS污染:本地解析返回虚假IP(如127.0.0.1或某个IP池)
- 正常:本地与公共DNS结果一致
4 ICMP Ping检测(辅助)
原理:检查ICMP包是否可达,若Ping失败但TCP成功,可能被墙;若Ping成功但HTTP被墙,则是应用层封锁。
组合逻辑:
if TCP失败 → 被墙(端口封锁) if TCP成功但HTTP返回RST → 被墙(HTTPS干扰) if DNS不一致 → 被墙(DNS污染) if TCP成功且HTTP正常 → 未墙
主流脚本工具对比
| 工具名称 | 检测方式 | 优势 | 劣势 |
|---|---|---|---|
| check-host.net | 多节点HTTP/TCP | 无需搭建环境 | 免费版限制次数 |
| DomainSEO Checker | 综合检测+API | 支持批量,输出报告 | 需付费 |
| OpenSource (GitHub) | 自定义脚本 | 灵活可控,免费 | 需自建国内节点 |
| Ping.pe | ICMP/TCP/HTTP | 多国节点结果直观 | 无API接口 |
推荐方案:自建脚本 + 国内云函数(如阿里云函数计算),成本低且可控。
实战:从零搭建检测脚本
步骤1:准备环境
- 一台国内云服务器(或云函数)
- Python 3.8+ 环境
- 安装依赖:
pip install requests dnspython
步骤2:编写核心检测函数
import requests, dns.resolver, socket
def multi_check(domain):
# DNS检测
try:
local_dns = dns.resolver.Resolver(configure=False)
local_dns.nameservers = ['114.114.114.114']
local_ips = [r.address for r in local_dns.resolve(domain, 'A')]
public_ips = [r.address for r in dns.resolver.resolve(domain, 'A')]
dns_poisoned = local_ips != public_ips
except: dns_poisoned = True
# HTTP检测
try:
r = requests.get(f'https://{domain}', timeout=10,
headers={'User-Agent':'Mozilla/5.0'})
http_blocked = 'Connection reset' in r.text or r.status_code == 0
except requests.exceptions.ConnectionError:
http_blocked = True
return {
'dns_poisoned': dns_poisoned,
'http_blocked': http_blocked,
'status': 'BLOCKED' if dns_poisoned or http_blocked else 'OK'
}
步骤3:批量检测与报告
- 读取域名列表(CSV或TXT)
- 加入多线程/协程(如asyncio)提升效率
- 输出结果包含:域名、状态、检测时间、节点IP
步骤4:部署为API(可选)
- 使用Flask/FastAPI包装,返回JSON
- 集成到监控系统(如Prometheus)
常见陷阱与解决方案
陷阱1:CDN干扰
许多域名使用Cloudflare等CDN,它们在全球有节点,如果用境外服务器检测,可能访问到CDN边缘节点而非原始IP。
解决:必须使用中国大陆IP,并强制指定DNS服务器为国内DNS。
陷阱2:防火墙动态策略
防火墙可能会对频繁检测的IP进行临时放行或精准封锁。
解决:每次检测间隔至少10秒,使用代理池轮换IP。
陷阱3:HTTPS证书误报
某些被墙域名返回“证书错误”,但实际只是配置问题。
解决:增加证书验证(如检查CN域名是否匹配),区分“证书无效”与“连接重置”。
陷阱4:误报为正常
某些域名仅在特定时间或特定地区被墙(如午夜间政策放宽)。
解决:多轮多次检测(每轮3次以上),取综合结果。
Q&A问答专区
Q1:脚本能100%检测出域名被墙吗?
A:不能,因为防火墙策略动态且复杂,脚本只能模拟常规访问模式,极少数域名可能使用特殊封锁手段(如仅对特定ISP封锁),脚本无法覆盖,但结合四大检测机制,准确率可达95%以上。
Q2:免费脚本和付费服务哪个好?
A:如果管理≤100个域名,推荐使用免费开源的Python脚本(如GitHub上的gfw-check),如果管理上千个域名,建议商业服务(如“域名检测专家”),它们有分布式节点和自动API,维护成本更低。
Q3:脚本检测频率如何设置才不被封IP?
A:建议每个域名至少间隔60秒检测一次,总并发数不超过10,如果使用云函数,每次检测前更换出口IP(例如通过阿里云弹性IP池)。
Q4:我可以用家用宽带跑脚本吗?
A:可以,但不推荐,家用宽带的IP可能被防火墙标记,导致检测结果不准确,甚至因频繁连接境外IP被运营商警告,建议使用国内云厂商的轻量服务器(如腾讯云轻量应用服务器)。
Q5:脚本检测结果和实际访问不一致怎么办?
A:首先确认脚本使用的节点是中国大陆IP,如果仍不一致,可能是浏览器缓存或代理设置影响,建议同时用手机4G网络访问该域名验证,两者一致才可信。
自动化检测域名是否被墙,本质是模拟中国境内用户访问链路并监控异常行为,虽然脚本无法做到100%准确,但结合TCP+HTTP+DNS+ICMP的多维检测,足以满足日常运维需求,建议将脚本集成到监控告警系统中,当检测到域名状态变化时自动通知,从而快速响应网络封锁事件。