☰
当ClaudeBot成为攻击面具:识别与拦截伪装爬虫扫描
2026/10/30 0:20:50 网站建设 项目流程

凌晨一点,我本想看一眼服务器今天的访问情况,tail 出来的日志却让人睡意全消。过去十分钟,Nginx 的 access log 里刷进来上千条请求,User-Agent 整整齐齐写着 ClaudeBot。第一反应是 Anthropic 的爬虫又来抓内容了。可下一秒就不对劲——URL 路径全是 wp-login.php、.env、config.php.bak、.git/config 这类组合,这哪是抓网页内容,这是在试探站点有没有可被利用的入口。

“ClaudeBot”跑来做批量漏洞扫描,已经不是孤例。在不少站长的日志里,同样的戏码正在反复上演:攻击者不用自己的 User-Agent,而是把身份伪装成正牌的 AI 爬虫,比如 ClaudeBot、GPTBot、Bytespider。日志上看是 AI 机器人密集访问,实际是一轮早期的批量漏洞探测。

这篇文章不打算讲攻击手法,而是想从运维和站长的视角聊清楚一件事:当“AI 爬虫”出现在不该出现的路径上,你怎么识别、怎么拦截、又该怎么避免误伤真正有价值的抓取流量。

1. 别急着骂 AI 爬虫,先看清日志里的行为差异

真实情况是:ClaudeBot 这类正规爬虫确实会持续、大量地访问公开网页,这也是很多站长在日志里看到大量 AI bot 请求的原因。它本身不是问题。问题在于,这些请求的路径完全超出了爬虫的正常行为范围。

1.1 现象:ClaudeBot 为什么不该出现在这些路径上

从官方说明看,ClaudeBot 是 Anthropic 用于抓取公开网页内容的机器人,主要服务于模型训练和内容处理这类任务。它的行为模式通常更接近一个常规网络爬虫:会先请求 robots.txt,抓取路径以内容页、列表页、静态资源为主,请求以 GET 为主,速率保持在相对可控的范围内。

而日志里那些伪装请求完全不是这个画风:

  • 一分钟内连续请求大量已删除、不存在或明显不该公开访问的路径;
  • 路径组合像字典枚举:.env、.bak、.sql、.git/config、phpMyAdmin、adminer.php、wp-login.php,以及带日期后缀的备份文件名;
  • 某些请求带 POST 方法,打在登录接口、上传接口或 API 接口上;
  • 不请求 robots.txt,不按网站目录结构走,一上来就直奔高价值目标。

这时候 UA 写什么已经不重要了。行为已经构成“批量漏洞扫描”的特征。真正值得关注的是:为什么它敢大摇大摆地顶着 ClaudeBot 的名字进来?

1.2 一个关键判断:单看 UA 已经说明不了任何问题

很多站点在接入 WAF 或写访问控制策略时,习惯用 UA 判断“这是不是好机器人”。这个习惯在早期还能用,但现在基本失效了。

原因很直接:User-Agent 是一段由客户端自行声明的文本,没有任何协议层面的强制校验。同样一个 HTTP 请求,可以标成浏览器,可以标成搜索引擎爬虫,也可以标成 Anthropic 的 ClaudeBot,服务端光看这一行字,无法区分谁真谁假。

所以这里先给出全文的主判断:不要把“识别爬虫”当成一次 UA 过滤,而要当成一次行为审计。UA 只能作为辅助线索,真正能说明问题的是请求路径、请求方法、来源 IP、请求节奏,以及访问后的状态码分布。

注意:看到“ClaudeBot”访问 .env 这类路径时,不要直接给 Anthropic 发邮件质询,先确认日志里的行为是否真的来自官方爬虫。多数情况下,这只是一个借了壳的扫描器。

2. 为什么攻击者要伪装成 ClaudeBot 这类爬虫

伪装成 AI 爬虫不是新鲜事,但这两年明显变多。背后不是某个单一原因,而是三件事凑到了一起。

2.1 伪装成本几乎为零

一个 curl 请求就能把 UA 改成任何值:

curl -A "ClaudeBot/1.0" https://example.com/wp-login.php

这不是什么复杂攻击技巧,它只是利用了 HTTP 头“自报家门”这一基础事实。问题在于,一旦这种零成本伪装开始流行,传统基于 UA 的放行策略就成了默认突破口。

有的站点配置了“对 AI 爬虫放行”,有的站点为了观测流量来源,保留了各大搜索引擎和 AI 爬虫的访问权限,甚至还有一些站点专门给这类爬虫开了较高优先级。伪造成 ClaudeBot 或 GPTBot,等于直接进入了这些“受信任名单”。

2.2 信任 AI 爬虫的惯性,成了最好的掩护

这里还有一个容易被忽略的心理因素。当一个 UA 写着大厂 AI 爬虫的名字时,运维第一反应通常不是拦截,而是“这是别人家的正规机器人,尽量别误伤”。尤其像 ClaudeBot 这类爬虫,抓取量大、官方有文档说明、IP 段也可能横跨多个云厂商,站长更不愿意轻易动它。

攻击者很清楚这一点。他们顶着 ClaudeBot 的名字进入,一是在扫描阶段降低被管理员注意的概率,二是万一被拦截,也可以随时切换 UA,换一个身份继续探测。对防御方来说,单纯拉黑一个 UA,基本等于什么都没做。

所以伪装的根本原因不是某个爬虫品牌被盯上,而是“UA 身份 + 大厂品牌”组合成了当代日志过滤体系里的盲区。

3. 一张表讲清楚:真爬虫和伪装扫描怎么区分

判断一个请求是不是真的 AI 爬虫,永远不要只看 UA。下面这张表是我处理这类日志时常用的判断维度,每个维度都只能算一个信号,不能单独定罪。

3.1 判断维度表

判断维度真爬虫常见特征伪装扫描常见特征
User-Agent与官方公布的 UA 一致,版本号稳定UA 固定不变,但请求内容和官方行为不匹配
请求路径内容页、列表页、静态资源,路径符合站点结构.env、.bak、.sql、.git/config、admin、备份文件
请求方法绝大多数是 GET可能出现 POST 打向登录、上传或 API 接口
来源 IP / ASN与官方公布的 IP 段或对应 ASN 匹配来自小型 VPS、IDC 随机段、住宅代理等
反解 PTR有较规范 PTR 记录,或解析到官方域名PTR 缺失,或解析到普通 VPS 域名
robots.txt首次抓取前通常先请求 robots.txt完全不理会 robots.txt,直接打敏感路径
请求节奏速率相对均匀,时间分散分钟级上千条,时间集中,可能 24 小时不停
404 占比正常爬虫 404 率通常不高大量请求不存在路径,404 占比明显偏高
TLS / HTTP 指纹官方爬虫客户端特征相对固定常见 curl、Python requests、Go 等工具指纹

这张表的价值不在于让你对着日志逐项打勾,而在于建立一种“组合判断”的直觉。单个信号出现,可能是巧合;多个信号同时出现,就需要认真对待了。

3.2 组合判断:不要用单一信号定罪

IP 是不是绝对可信?也不是。攻击者可以用大量机器轮换来源,甚至用代理池,所以不能因为“这个 IP 不在官方列表里”就立刻断定它在扫描,也不能因为“这个 IP 看起来像官方段”就完全放心。

更稳妥的做法是打分式判断。我一般会先看最近一小时 access log 里出现次数最多的 UA,再按路径复杂度排序。路径越像字典枚举、404 占比越高、POST 比例越高,就越值得怀疑。一个正经爬虫的 404 率通常不会高到哪里去,更不会盯着 .env 和 wp-login.php 反复试探。

另外,官方信息要查,但要用保守的方式参考。比如 Anthropic 是否公开了 ClaudeBot 的完整 IP 段,公开到什么粒度,更新频率如何,都要以官方最新文档为准。如果你在某个技术博客里看到一个“ClaudeBot 完整 IP 列表”,它可能已经过时,甚至本身就是别人编的。

实操建议:把判断维度做成一个脚本,每天扫描一遍 access log,输出“高嫌疑访问”清单。刚开始可以只输出不拦截,先跑一周,看看误报率再决定要不要自动处理。

4. 确认异常后,按这个顺序处理更稳

确认日志里的“ClaudeBot”是伪装扫描后,正确的反应不是骂两句然后封掉 Anthropic 的整个网段,而是按顺序做几件事。

4.1 留证:先拷贝日志,再谈封禁

第一条原则:先留证据,再动手。因为后续如果要排查影响范围、要看请求是否已经打到真实漏洞上,都要回到原始日志。

具体做法:

  • 把 access log 里包含可疑 UA 或可疑 IP 的行,单独导出成文件,保留足够长的时间窗口,比如至少 72 小时;
  • 记录重要时间点、请求路径、方法、状态码、响应字节数;
  • 确认日志已经包含完整 UA 字段,如果网站前面还有一层代理,X-Forwarded-For 也要留,否则看到的全是代理 IP,没法溯源。

先用一条 shell 命令做初筛,从已保留的日志里筛选“爬虫 UA + 敏感路径”的请求,并按来源 IP 统计:

zgrep -h "ClaudeBot" /var/log/nginx/access.log* \ | grep -E "wp-login\.php|\.env|\.git/config|adminer\.php|\.sql|\.bak" \ | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

这只是最粗糙的初筛,但它能快速告诉你:真正异常的来源是几个 IP,还是散成一大片。如果来源集中在少数几个 IP,处理起来很简单;如果来源分散,说明对方可能有代理池,这时候单纯封 IP 意义不大,要转向路径层面的统一防护。

4.2 封禁与限速:从 IP 和路径两个维度一起下手

处理扫描流量,我建议遵循一个顺序:先拦明显恶意的高频 IP,再对敏感路径做统一访问控制,最后再决定要不要限速。

第一层,系统层或防火墙层直接拒绝确认恶意的高频 IP。这一步最好用 fail2ban 或防火墙规则自动化,而不是手动一条条加。

第二层,无论什么 UA,敏感路径都不能直接裸奔。.env、.git/config、备份文件、数据库导出文件这类路径,本来就不该允许匿名访问。即使没有爬虫捣乱,也建议在 Web 服务层面统一挡住。

Nginx 里可以这样处理这类路径:

# 对明显敏感路径做统一访问控制,不管 UA 是什么 location ~* \.(env|sql|bak|zip|tar)(\?.*)?$ { deny all; return 403; } # 对声明为爬虫的请求做限速,避免异常流量拖垮站点 limit_req_zone $binary_remote_addr zone=bot_limit:10m rate=5r/s; server { location / { limit_req zone=bot_limit burst=20 nodelay; } }

这里要特别提醒:不要把限速和封禁混为一谈。限速是为了控制影响,封禁是为了消除持续探测。对于伪装扫描,如果对方只有几个固定 IP,封禁更直接;如果对方有轮换 IP,限速加敏感路径阻断比单纯封禁更有效。

4.3 用 fail2ban 做自动化拦截示例

如果日志格式比较规整,可以用 fail2ban 自动完成“识别异常行为 → 封禁来源 IP”的流程。下面是一个常见写法,用来匹配“爬虫 UA 命中敏感路径”的请求:

# /etc/fail2ban/filter.d/nginx-scan-spoof.conf [Definition] failregex = ^<HOST> .*" (?:GET|POST) .*(?:\.env|\.git/config|wp-login\.php|adminer\.php).*"(?:ClaudeBot|GPTBot) ignoreregex =
# /etc/fail2ban/jail.d/nginx-scan-spoof.local [nginx-scan-spoof] enabled = true port = http,https filter = nginx-scan-spoof logpath = /var/log/nginx/access.log maxretry = 5 findtime = 60 bantime = 3600

含义是:在 60 秒窗口内,如果某个 IP 出现 5 条匹配“爬虫 UA 命中敏感路径”的日志,就把这个 IP 封禁 1 小时。

注意,fail2ban 的正则高度依赖 Nginx 日志格式,不能拿这套配置直接套生产环境。正确做法是先下载匹配的日志样本,用 fail2ban-regex 工具测一遍,确认能命中再启用。启动后也要观察一两天,防止误伤。

5. 比拦截更重要的,是把日志和监控补起来

很多站点在处理完这一波扫描之后就当事情结束了。但从长期看,真正值得投入的不是这一次封禁,而是“下次再出现时,能不能第一时间发现”。

5.1 日志至少保留哪些字段

如果要识别“伪装成 AI 爬虫”的扫描,日志只记录 IP、时间、方法和 URL 是不够的。建议至少保留以下字段:

  • 来源 IP:最好同时记录直连 IP 和 X-Forwarded-For;
  • 完整 User-Agent:不要截断,因为你要判断它是不是被伪装过的;
  • 请求方法和完整路径:包含查询参数,否则漏掉很多有效信息;
  • 状态码和响应字节数:用来计算 404 占比;
  • 请求耗时:用于识别异常的高负载请求;
  • 尽可能记录 TLS 版本和加密套件:在 UA 完全不可信时,TLS 指纹能提供额外判断线索;
  • 如果日志里能记录 Header Referer 和 Content-Type,对分析 POST 类扫描也很有帮助。

这些字段不是每一条都有用,但等到需要的时候,缺一个都会让排查变得很难受。

5.2 告警规则从这三条开始

不用一上来就上复杂 SIEM,先用简单规则跑起来。最容易见效的告警规则有三条:

  1. 高 404 占比加爬虫 UA:某个 UA 在 10 分钟内产生大量请求,且 404 占比超过 60%,先标记为嫌疑对象;
  2. 敏感路径命中:任何 UA 访问 .env、.git/config、备份文件、数据库导出文件,直接告警,不做二次判断;
  3. 同 IP 频繁切换 UA:一个来源 IP 在短时间内出现多种不同 UA,且其中包含主流浏览器或爬虫标识,说明自动化工具在反复变更身份,需要观察。

如果你已经有了 CDN 或云 WAF,这些规则通常都能在控制台里配置,不一定非要自己写脚本。真正要保证的是:告警发出后有人看,有明确的处理流程,而不是告警邮件躺在邮箱里没人管。

落地建议:先用一个固定目录存放告警快照,比如/var/log/security/bot-scan/,每次触发规则就把相关日志行复制过去。这样不仅方便复盘,也能为后续写更精准的规则积累样本。

6. 这件小事背后,是一个长期要适应的安全变化

处理完“ClaudeBot 伪装扫描”这件事,最值得记住的其实不是某条封禁命令,而是一个正在发生的安全习惯转移。

6.1 从信任 UA 转向信任行为

过去运维判断“好机器人”和“坏机器人”,很大程度上依赖身份标识:UA 对不对、IP 在不在白名单、ASN 是不是官方网段。这套模式的问题在于,身份是可声明的,攻击者可以伪造 UA,可以租用不同地区的服务器,甚至可以伪造反解记录。

更可靠的路径是转向行为判断:请求什么路径,用什么方法,访问节奏如何,失败率多高,是否触发了业务核心资源。把这些行为特征组合起来,形成基线。基线之外的流量,先怀疑,再确认,而不是先放行。

这个转变对普通站点来说并不容易,因为行为分析往往需要历史日志和数据积累。但你可以从一个很小的起点开始:每天花十分钟看一眼 access log 的异常请求,每周分析一次高嫌疑流量,每月更新一次防护规则。

6.2 对僵尸扫描的实用边界

也要承认,伪装扫描只是 Web 攻击里最基础的一种形态。它不是一次就能彻底防住的威胁,而是一种持续存在的背景噪声。

  • 如果你运营的是个人博客或小站点,做到“敏感路径防护 + 异常 UA 告警 + 定期看日志”就足够了,没有必要为一次扫描上全套商业安全产品;
  • 如果你运营的是业务系统或中大型站点,建议把这类请求交给 CDN/WAF 统一处理,同时保证源站日志完整、权限收敛、敏感接口有独立鉴权;
  • 无论站点大小,都不要因为一次伪装扫描就去封杀所有 AI 爬虫。真正需要长期维护的能力,是“能快速区分异常访问和正常抓取”的监控体系。

这类扫描流量还有一个特点:它会不断换皮。今天顶的是 ClaudeBot,明天可能就是另一个新出现的 AI 爬虫品牌。如果你的防护只认几个固定 UA,那这场猫鼠游戏你永远慢半拍。

回到最初那个场景。看到 ClaudeBot 在你的日志里访问 wp-login.php,真正该做的不是第一时间把 Anthropic 拉黑,而是把这条日志当成一个信号:你的访问日志和监控体系,是否已经足以让你分辨“好爬虫”和“借壳扫描”?

如果答案是模糊的,那么这次异常反而是一个机会。趁这个信号还热着,把该补的日志字段补上,把该拦的敏感路径拦住,把三两条告警规则跑起来。下一次再有机器人顶着大厂名字进来时,你就能少一点深夜的紧张,多一点明确的判断。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询