在CDN边缘节点上,Bot管理策略经常陷入一种两难:如果放行所有标注为Googlebot的请求,恶意扫描器可以轻易改一个User-Agent就混进来;如果只拦非浏览器流量,又可能把正规搜索引擎的抓取请求挡在门外,导致收录下降甚至站点被降权。要解决这个问题,不能只盯着User-Agent字符串,而要从请求来源、网络身份、TLS握手特征和访问行为等维度,把搜索引擎爬虫与恶意扫描工具区分开。

搜索引擎爬虫和扫描器之间存在天然差异。Googlebot、Bingbot等正规爬虫通常来自公开可验证的IP段,会先抓取robots.txt,请求节奏相对克制,并且会复用同一连接连续抓取多个资源。而sqlmap、Nmap、Nikto、AWVS等工具往往直奔管理后台、备份文件、敏感配置文件,路径带有明显攻击意图,请求频率更高,TLS指纹也与真实浏览器不同。
一、搜索引擎爬虫与恶意扫描工具的流量特征差异
最容易被误解的识别方式是User-Agent。搜索引擎爬虫确实会在HTTP头中声明自己的名称,例如Googlebot、Bingbot、YandexBot,但这只能作为参考,不能作为安全判断依据。HTTP请求头完全由客户端控制,攻击者使用sqlmap时只需要加一个参数,就可以把User-Agent改成Googlebot/2.1。如果WAF规则只匹配UA字符串,那么这种伪造请求会直接进入源站。
真正稳定的差异体现在网络身份和访问路径上。Google和Bing等搜索引擎会公布自己的抓取IP段,并且可以通过反向DNS验证请求来源。恶意扫描工具通常运行在云主机、VPS、代理池或Tor出口节点上,这些IP的信誉值较低,与搜索引擎官方ASN没有关联。路径方面,搜索引擎爬虫优先抓取首页、内链、图片、CSS和JavaScript文件,并遵循robots.txt;扫描器则会反复请求/admin、/wp-login.php、/.env、/backup.zip、/phpinfo.php等敏感路径,这些路径通常不会被正常爬虫触碰。
访问节奏同样暴露意图。搜索引擎爬虫为了不对目标站点造成压力,会保持较低并发,遇到大量404后会降低抓取频率。扫描器恰恰相反,它会在短时间内用字典爆破目录,产生大量404和403,并且请求参数里经常出现单引号、union select、../../etc/passwd等攻击载荷。CDN边缘节点统计每个IP的请求速率、错误比例和路径熵值,就可以把行为异常的自动化流量从正常爬虫中筛出来。
| 特征 | 搜索引擎爬虫 | 恶意扫描工具 |
|---|---|---|
| User-Agent | 固定且公开 | 可随机伪造 |
| IP来源 | 官方ASN,可反向DNS验证 | 云主机、VPS、代理池 |
| 访问路径 | 首页、内链、静态资源 | 后台、备份、敏感配置 |
| 请求频率 | 低并发,克制抓取 | 高并发,短时爆破 |
二、CDN Bot管理的检测链路
CDN Bot管理通常不会只依赖单一规则,而是采用分层检测。第一层是快速预筛,根据User-Agent、请求头完整性和已知IP信誉库,把流量分成搜索引擎、普通浏览器、未知自动化、恶意扫描几类。第二层是对声称是搜索引擎的请求做主动验证,包括反向DNS和正反向IP比对。第三层是对未识别流量进行行为分析,用请求速率、敏感路径命中率、404比例等指标计算风险评分。最后根据评分执行放行、JS挑战、CAPTCHA验证或直接拦截。
预筛阶段可以先通过规则把明显恶意的工具名挑出来。下面这段Nginx配置用于给不同的User-Agent打标签,它只做分类,并不直接决定放行。
map $http_user_agent $bot_type {
default "unknown";
~*Googlebot "search";
~*Bingbot "search";
~*YandexBot "search";
~*sqlmap "malicious";
~*Nikto "malicious";
~*Nmap "malicious";
~*Nessus "malicious";
}
要给这个分类结果赋予安全意义,还需要在后续规则中做组合判断。例如,当bot_type为search时,可以按IP限速,并检查其请求路径是否包含敏感文件。一个自称Googlebot的IP如果反复请求/wp-admin.php,即使User-Agent完全正确,也应直接拦截。反过来,一个bot_type为unknown但请求速率很低、只抓取公开页面的IP,则可以先放行静态资源,避免误伤长尾爬虫或监控工具。
行为评分是第二层和第三层之间的缓冲。CDN运营人员可以给每个请求维度设置权重:命中敏感路径加20分,单个IP一分钟404超过30次加15分,请求参数包含SQL注入特征加30分,TLS指纹与常见扫描器一致加10分。得分超过60分就触发验证码,超过90分直接丢弃。这样比单一UA规则更灵活,也可以根据业务情况动态调整阈值。
三、反向DNS校验是核心手段
对搜索引擎爬虫来说,反向DNS校验是目前最可靠的身份验证方式。以Googlebot为例,正确流程是先对客户端IP做PTR反查,得到主机名,再判断主机名是否以googlebot.com或google.com结尾;随后还要把主机名做A记录解析,确认解析出的IP列表中包含客户端原IP。这个双向验证可以防止攻击者自建DNS服务器返回伪造的googlebot.com主机名。
下面的Python函数演示了Googlebot验证的简化流程。其中socket.gethostbyaddr用于PTR反查,socket.gethostbyname_ex用于正向解析并返回全部IP。
import socket
def fetch_forward_ips(hostname):
try:
return set(socket.gethostbyname_ex(hostname)[2])
except socket.gaierror:
return set()
def verify_googlebot(ip, user_agent):
if "Googlebot" not in user_agent:
return False
try:
hostname = socket.gethostbyaddr(ip)[0]
except socket.herror:
return False
if not hostname.endswith("googlebot.com") and not hostname.endswith("google.com"):
return False
return ip in fetch_forward_ips(hostname)
需要注意的是,DNS查询有延迟,在线流量中不能对每个请求都做一次PTR解析。CDN平台通常会把验证结果缓存一段时间,比如一小时或数小时,相同IP的后续请求直接使用缓存结论。Bingbot的验证逻辑类似,主机名应包含search.msn.com。对于没有官方IP列表的小型搜索引擎,建议先观察其抓取行为,再决定是否加入白名单。
反向DNS并不适合所有自动化流量。很多企业爬虫、RSS阅读器和监控服务没有设置PTR记录,强制验证会导致它们被误拦。因此这个手段主要用在明确声称自己是搜索引擎的请求上,而不是对所有未知Bot无差别验证。
四、规则落地的平衡与误伤规避
在实际部署中,不建议把未知流量全部拦截。搜索引擎收录、广告监测、价格比价、内容聚合等流量都可能以自动化方式访问站点,其中部分对业务有正面价值。更稳妥的做法是分层处置:通过双向DNS验证的搜索引擎直接放行;UA为search但验证失败的标记为伪造,执行JS挑战;UA为恶意工具或行为评分过高的丢弃;UA为unknown的只放行公开静态资源,限制登录、搜索、下单等动态接口的访问频率。
监控模式是上线初期必须保留的环节。先让CDN Bot管理规则只记录不拦截,观察一到两周,统计误伤量和真实攻击拦截量。重点看403页面访问率、验证码触发率、搜索收录是否下降。如果某类正常爬虫被频繁挑战,可以把它的IP段加入白名单;如果某些攻击工具绕过规则,再补充路径特征和TLS指纹规则。
搜索引擎爬虫的IP段和特征会变化,恶意扫描器的UA和工具指纹也在更新。建议每月检查一次Google、Bing等平台的官方抓取IP列表,更新放行清单;同时从CDN日志中提取被拦截的恶意请求样本,分析其请求头和路径,把新出现的工具名、默认UA和敏感路径加入规则库。这样既能保护源站安全,也不会因为一个粗暴的UA封禁毁掉站点在搜索引擎中的收录表现。
CDN Bot管理的关键从来不是找到一种完美识别Bot的算法,而是用可验证、可调整的分层策略,在搜索引擎流量和恶意扫描流量之间划出尽量清晰的边界。用UA做初筛,用DNS做验证,用行为做兜底,再配合监控和迭代,才能让爬虫管理既安全又不伤收录。