
最近不少運維和安全群在討論一種現象服務器訪問日志里突然出現大量 User-Agent 寫為 ClaudeBot、GPTBot 之類的請求但實際訪問路徑并不是頁面采集而是/.env、/.git/config、wp-login.php這類敏感文件探測。這不是官方 AI 爬蟲的正常行為而是有人故意偽造 AI Bot 的 User-Agent進行大規模漏洞掃描。偽造者利用 AI 爬蟲名稱看起來合法、近兩年又頻繁出現在日志里的特點把掃描流量混在正常 Bot 流量中。對運維和開發來說真正重要的是學會從 User-Agent 之外的信息確認請求身份并在日志、WAF、封禁策略三層完成識別、驗證和處置。如果你也在自己的 Nginx 或云安全產品里看到類似日志不要急著把所有 ClaudeBot 請求封掉也不要簡單放行。這篇文章會從攻擊者為什么這樣做開始再給出一套從日志到封禁的最小落地流程。1. 為什么有人要偽造 ClaudeBot 這類 AI Bot 的 User-Agent1.1 偽裝掃描日志到底長什么樣先看一段常見但很可疑的訪問日志203.0.113.7 - - [06/Feb/2025:03:11:22 0800] GET /.env HTTP/1.1 404 153 - ClaudeBot/1.0 198.51.100.23 - - [06/Feb/2025:03:11:24 0800] GET /.git/config HTTP/1.1 404 153 - ClaudeBot/1.0 198.51.100.24 - - [06/Feb/2025:03:11:27 0800] GET /wp-login.php HTTP/1.1 404 153 - Mozilla/5.0 (compatible; ClaudeBot/1.0)如果只看 User-Agent前幾行確實像某個 AI 爬蟲在正常抓取。但請求路徑暴露了問題/.env環境變量文件、/.git/config源碼倉庫配置、wp-login.phpWordPress 登錄入口這些都是漏洞掃描器最常探測的敏感路徑。攻擊者不在意返回 200 還是 404他們關心的是哪些路徑存在、哪些服務會響應以及能否從響應內容中提取到價值信息。這類日志的特點是一條請求一個路徑來源 IP 可能分散UA 只在字面上“看起來像官方”但訪問規律和正常 AI 爬蟲完全不同。1.2 偽造 AI Bot 身份能帶來哪些好處攻擊者偽造 ClaudeBot 這類 AI 爬蟲名稱不是隨手寫的主要有幾個現實原因。第一個原因是繞過依賴 UA 的訪問控制。有些站點為了配合 AI 搜索收錄會在 Nginx 或 CDN 上專門放行ClaudeBot、GPTBot這類 UA有些團隊還會把它們加入白名單認為它們不會帶來威脅。攻擊者偽造這個 UA相當于直接借用了白名單身份。第二個原因是規避基于惡意 UA 的基礎封禁。像 sqlmap、Nikto、wpscan 這些掃描工具的 UA 特征非常明顯很多 IPS、WAF 有現成規則可以直接攔截。把 UA 改成 ClaudeBot 之后傳統規則失效流量更容易到達業務服務器。第三個原因是降低人工分析時的警惕性。安全告警每天會產生大量日志看到 ClaudeBot、GPTBot 這類名稱很多分析師第一反應是“正常 AI 爬蟲”不會第一時間深入排查。攻擊者利用的正是這種思維慣性。1.3 User-Agent 是自述身份不能作為唯一依據需要注意HTTP 協議中的 User-Agent 是請求方自己聲明的“身份”客戶端可以隨意修改。用一行命令就能演示curl -A ClaudeBot/1.0 https://example.com/robots.txt服務器端收到這個請求后只能看到User-Agent: ClaudeBot/1.0無法判斷發請求的到底是 ClaudeBot 官方爬蟲還是某個掃描器。基于同樣的原理攻擊者完全可以在掃描腳本里偽造任意 UA。所以對 User-Agent 的正確態度是它只能作為第一層分流標識不能作為信任依據。真正要判斷一個流量是否可信必須組合來源 IP、請求行為、訪問頻率和路徑特征來判斷。2. 三層識別法從身份、來源、行為判斷真假2.1 第一層身份核對 UA 字符串本身雖然 UA 可以偽造但它仍然是第一道過濾條件。這里要做的是“精確匹配”而不是“模糊包含”。以 ClaudeBot 為例官方爬蟲的 UA 命名通常有固定格式一般形如ClaudeBot/1.0或Mozilla/5.0 (compatible; ClaudeBot/1.0; 官方說明頁)。如果日志里出現ClaudeBot/1.0后面還拼接了.net、.php、scanner、test等字符或者大小寫、空格明顯異常就需要懷疑是偽造樣本。更嚴謹的做法是維護一個“已知 AI Bot UA 樣本庫”。這個樣本庫包括三部分官方公開文檔中聲明的 UA 格式。線上訪問日志中確認為官方爬蟲的 UA。社區報告確認過存在偽造的 UA 變體。判斷原則很簡單字符串完全匹配可能有風險需要繼續看下一層字符串不匹配但行為像抓取器可能是普通爬蟲也可能是掃描器同樣要繼續看來源和行為。2.2 第二層來源IP 段、ASN 與反向 DNS來源驗證是識別偽造 AI Bot 最重要的手段。User-Agent 可以隨便改但正常情況下一個 TCP 連接必須有真實的源 IP攻擊者可以使用大量 IP 發起掃描但很難讓自己的一臺掃描機同時出現在正確的云廠商網段里。先看 IP 歸屬whois 203.0.113.7查詢結果會顯示 IP 所在網段、運營商和組織名稱。比如查詢到Organization: Example Cloud、CIDR: 203.0.113.0/24這時再看這個組織是否與官方 AI 爬蟲公開的網段一致。再看反向 DNSdig -x 203.0.113.7官方爬蟲的 IP 通常會配置反解反解域名會包含明顯標識比如某個爬蟲名稱或官方域名后綴。如果源 IP 反解結果為空或者反解域名是一串隨機數字甚至指向一個與 AI 爬蟲完全無關的 IDC 機房那么即使 UA 寫得再像官方也要提高警惕。這里的難點是官方 AI 爬蟲不一定會公開完整的 IP 清單部分云廠商 IP 還會動態變化。所以來源信息不能作為絕對判斷要結合行為一起看。2.3 第三層行為請求路徑、頻率和抓取順序正常 AI 爬蟲的工作方式通常有清晰的抓取順序先請求robots.txt再根據 sitemap 或頁面里的鏈接去抓取頁面內容請求的路徑大多是可訪問的業務 URL頻率相對可控。漏洞掃描器不是這樣工作的。掃描器通常攜帶一份路徑字典按字典順序挨個發起請求比如/.env /.git/HEAD /.git/config /wp-login.php /wp-admin/ /api/v1/ /actuator/env /backup.sql它們不會先看 robots.txt也不會在意頁面結構和鏈接關系只關心路徑是否存在、響應狀態碼是什么、返回內容里有沒有敏感信息。如果一個“ClaudeBot”在同一個 IP 下十秒內連續請求這些路徑那基本可以確定不是官方 AI Bot而是偽造 UA 的掃描行為。還可以觀察請求頻率是否規律。正常抓取會有一定間隔掃描器為了趕時間常常高并發。如果同一個 UA 在凌晨兩三點對同一臺服務器發起幾百個不同路徑的請求而且大部分是 404攻擊的可能性很高。2.4 三層組合判斷不要只看單一條件維度正常 AI Bot 常見表現偽造 AI Bot 常見表現UA 匹配UA 與官方公開字符串一致格式穩定UA 相似但夾雜異常字符或版本不一致來源 IP來自官方或合作云廠商網段可能有固定 ASN來源分散在多個 IDCASN 與官方聲明不一致反查 DNS反解域名包含可識別標識無反解或反解指向無關域名訪問路徑先請求 robots.txt再抓取業務鏈接直接路徑枚舉/.env、/.git/config等抓取頻率有間隔并發受控短時間高頻請求規律不明顯參考鏈接一般帶正常 Referer請求頭完整缺少 RefererHeader 不自然單條請求命中某一項不能說明什么比如正常業務方也可能偶爾訪問/.env路徑。但如果“UA 匹配 來源可疑 敏感路徑 高頻”這四件事同時出現基本可以進入攔截流程。3. 落地檢測從 Nginx 訪問日志找出可疑 Bot 流量3.1 先統一日志格式保證能取到關鍵字段在排查之前要確保 Nginx 訪問日志記錄了足夠信息。推薦使用包含客戶端 IP、時間、請求、狀態碼和 UA 的格式log_format main $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent; access_log /var/log/nginx/access.log main;如果業務部署在 CDN 或七層負載均衡后面$remote_addr可能是 CDN 節點 IP而不是真實客戶端 IP。這種情況要使用X-Forwarded-For或 CDN 平臺提供的真實客戶端 IP 變量但同時要注意這些 Header 可以被偽造。生產環境必須先驗證源站是否只信任來自 CDN 的請求避免攻擊者直接偽造 Header 繞過記錄。3.2 用 Python 腳本按特征聚合可疑請求先統計 UA 里出現 ClaudeBot、GPTBot、Bytespider 等關鍵詞的 IP找出最活躍的來源from collections import Counter from pathlib import Path log_file Path(/var/log/nginx/access.log) fake_ua_keywords (ClaudeBot, GPTBot, Bytespider) sensitive_path (/.env, .git/config, wp-login.php, actuator, .bak, .sql) ip_counter Counter() sensitive_counter Counter() lines log_file.read_text(encodingutf-8, errorsignore).splitlines() for line in lines: if not any(keyword in line for keyword in fake_ua_keywords): continue fields line.split() if not fields: continue ip fields[0] ip_counter[ip] 1 if any(path in line for path in sensitive_path): sensitive_counter[ip] 1 print(出現偽造 AI UA 關鍵詞的 Top 20 IP) for ip, count in ip_counter.most_common(20): print(f{count:8d} {ip}) print(命中敏感路徑的 Top 20 IP) for ip, count in sensitive_counter.most_common(20): print(f{count:8d} {ip})這個腳本的思路是先篩選 UA再篩選路徑最后按 IP 聚合。實際生產環境不需要硬編碼在腳本里可以把日志接入 ELK、ClickHouse 或云原生日志服務用同樣的邏輯做可視化統計。這里要注意一個坑不要直接在整個日志文件上一次性過濾。生產環境日志量很大建議先tail -100000或按時間窗口切分日志再進行分析。3.3 時間維度瞬時突增是更可靠的信號IP 數量和路徑命中只是其中一個維度。偽造 UA 的掃描器往往會在短時間內集中爆發所以把時間維度加進來判斷更準確。統計指定時間內每分鐘請求量tail -100000 /var/log/nginx/access.log \ | grep ClaudeBot \ | cut -d[ -f2 | cut -d] -f1 | cut -d: -f1-3 \ | sort | uniq -c | sort -rn | head -20輸出結果類似147 06/Feb/2025:03:11 98 06/Feb/2025:03:12 12 06/Feb/2025:03:13如果同一個來源 IP 在某一分鐘內連續產生幾十條到上百條請求而且請求路徑全是/.env、/.git/config、wp-login.php這類路徑說明這不是正常 AI Bot 的抓取節奏而是掃描器正在跑字典。時間窗口聚合的價值在于它能把“少量誤報”和“批量掃描”區分開。正常抓取也會請求多個路徑但不會在幾秒內密集命中大量敏感路徑。建議把“單位時間內同一個 IP 命中敏感路徑次數”作為告警條件而不是單純看 UA。這樣即使對方換個 UA 名稱只要行為仍然是掃描一樣能觸發。4. 自動處置從 Fail2ban 到 WAF 策略4.1 Fail2ban 攔截“敏感路徑 偽 AI UA”在單臺 Linux 服務器上快速落地時Fail2ban 是成本最低的方案。思路是在 Nginx 訪問日志中匹配特定 UA 和敏感路徑超過閾值后自動封禁源 IP。先創建過濾器比如/etc/fail2ban/filter.d/fake-ai-bot.conf[Definition] failregex ^HOST .*(?:GET|POST|HEAD) \/(?:\.env|\.git\/config|wp-login\.php|\.\.\/\.\.\/).* 404 .*ClaudeBot/1\.0$ ignoreregex 再在/etc/fail2ban/jail.local中啟用[fake-ai-bot] enabled true port http,https filter fake-ai-bot logpath /var/log/nginx/access.log findtime 60 maxretry 5 bantime 3600參數含義參數說明示例值findtime統計時間窗口單位秒60maxretry時間窗口內匹配的最大次數5bantime封禁時長單位秒3600logpath日志文件路徑/var/log/nginx/access.log配置完成后先測試正則是否匹配真實日志fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/fake-ai-bot.conf這個工具會顯示匹配次數。如果正則不匹配需要檢查日志格式與正則中的字段順序。4.2 WAF 的挑戰與限流思路Fail2ban 適合單機和簡單場景但對于多節點、分布式掃描和 CDN 場景更推薦在 WAF 層處理。WAF 通常提供三種能力Bot 管理識別常見爬蟲和工具 UA并支持自定義 Bot 特征。JS Challenge對可疑請求下發一段 JavaScript 挑戰正常瀏覽器能通過大多數命令行掃描工具無法完成。速率限制按 IP、Session、UA 組合限流。實際策略不要直接對 ClaudeBot 返回 403而是先分級正常且可驗證的官方 AI Bot - 放行并限速 可疑 UA 但來源未知 - JS Challenge 或 429 疑似掃描 命中敏感路徑 - 403 或封禁這樣的好處是減少誤傷。有些站點希望被 AI 搜索索引如果把所有 ClaudeBot 都封掉可能會造成收錄異常。進入挑戰流程后官方 Bot 即使無法完成 JS 挑戰也有機會通過后續 IP 驗證流程放行。4.3 封禁、觀察、復核的完整處理流程任何自動封禁都可能誤傷尤其涉及到 AI Bot 名稱時。建議按下面順序執行自動發現日志或 WAF 識別到“UA 疑似 AI Bot 敏感路徑 高頻”。臨時限速先對該 IP 啟用較慢的限速策略而不是直接 403。人工復核查看 IP 歸屬、ASN、反向 DNS 和該 IP 的完整請求序列。確認封禁如果確認為掃描再封禁 IP 或 IP 段并設置合理時長。定期復查每天檢查被誤殺的請求調整規則。保留證據把原始日志、請求頭和響應狀態保存下來便于后續調整規則。這里重點強調第六步。很多團隊封完就不管了后來才發現某個正常爬蟲 IP 被規則誤傷。保留日志和規則快照可以讓誤傷恢復變得可操作而不是只能靠“感覺”。5. 避免誤傷官方 AI Bot 和偽造掃描器怎么區分處理5.1 官方 AI Bot 通常會有哪些可驗證特征雖然不同 AI 爬蟲的實現細節不同但公開服務通常有相對穩定的特征會遵守robots.txt并且很多官方文檔會說明爬蟲用途和聯系頁面。會使用固定 UA并且 UA 中可能包含官方說明頁地址。來源 IP 有較明確的云廠商或自有網段部分會公布 IP 范圍。抓取行為以采集頁面內容為主不會高頻請求/.git、/.env這類路徑。官方 AI Bot 也不一定永遠表現完美比如某些海外云廠商的爬蟲會訪問不支持的地域、頻繁請求動態接口但這不能作為直接封禁理由。更好的做法是建立“正常樣本”和“可疑樣本”兩個隊列持續觀察。5.2 參考分級處理策略情況建議處理UA 匹配IP 歸屬正常訪問路徑正常放行并設置每秒請求數上限UA 匹配IP 歸屬未知但路徑正常臨時放行記錄日志并持續觀察UA 匹配IP 歸屬未知命中敏感路徑限速觀察后續行為UA 匹配IP 歸屬可疑高頻命中敏感路徑直接封禁至少封禁 24 小時UA 不匹配但行為與官方 AI Bot 一致按普通爬蟲處理不做特殊放行在生產環境里建議把“UA 匹配”和“行為匹配”分開記分而不是用布爾判斷。例如UA 匹配官方格式1 IP 歸屬在官方網段3 先請求 robots.txt2 命中敏感路徑-3 短時間高頻請求-2 缺少 Referer-1最終分越高越可信越低越可疑。這樣即使攻擊者不斷更換 UA只要行為特征不變分數依然會偏低。提醒最好不要在規則里寫死“只要 UA 等于 ClaudeBot 就放行”。AI 爬蟲名稱會不斷增加和變化要把判斷重點放在“來源和行為”上。6. 生產環境排錯與預防清單6.1 接到告警后的排查順序如果線上已經出現大量偽造 AI Bot 掃描建議按下面的順序排查而不是先找封禁命令。第一步看告警信息和時間窗口確認是哪臺服務器、哪個域名、什么時間段開始異常。第二步提取原始日志不要只看聚合結果。先從日志里復制幾條最可疑的完整請求行看 UA、路徑、狀態碼、Referer 和來源 IP。第三步驗證來源 IP。使用 whois、ASN 查詢和反向 DNS 解析判斷該 IP 是否在 AI Bot 官方網段范圍內。這里要注意很多攻擊者會使用云主機IP 歸屬看起來也是正常云廠商所以不能只看“是不是云廠商”要看“是不是官方公告中使用的云廠商和網段”。第四步確認 CDN 場景下是否拿到真實 IP。如果源站只信任 CDN 轉發請求日志里出現的客戶端 IP 才可信如果攻擊者直接訪問源站入口日志里記錄的 IP 可能不是真實攻擊源。第五步再決定處置動作。如果是少量誤報先限速后觀察如果是大規模掃描就加入 WAF 規則或臨時封禁。6.2 上線前和日常防護檢查清單很多服務器既沒有統一的訪問日志格式也沒有 WAF 規則出了問題只能臨時翻日志。下面這份清單可以用于新服務上線前檢查也適合作為日常巡檢項訪問日志是否記錄了完整 UA、Referer、狀態碼和響應時間。是否有/.env、/.git、/wp-login.php、/actuator等敏感路徑的訪問告警。是否對源站入口做了訪問控制避免 CDN 后的真實 IP 泄露。是否配置了限速策略尤其是 UA 為常見 AI Bot 的請求。是否維護了已知 AI Bot IP 段和 UA 樣本庫并定期更新。是否有誤報回滾機制封禁后如何快速放行正常爬蟲。是否對封禁規則做每日或每周復盤。其中“源站真實 IP 泄露”經常被忽略。攻擊者可以直接掃描源站 IP繞過云 WAF即使你把 WAF 規則寫得再好也會失去意義。所以生產環境要確保源站只允許 CDN 節點、負載均衡器或白名單網段訪問。6.3 從“封 UA”升級到“行為基線”長期來看只靠 UA 關鍵詞做防御是不夠的。攻擊者會不斷學習新的 UA 名稱今天偽裝 ClaudeBot明天就可能偽裝其它 AI 爬蟲。真正有效的方式是建立流量行為基線正常業務接口的