很多站点在服務器上打開訪問日誌,會發現某個 IP 請求量特別大,一查是 CDN 回源节点或者负载均衡的内網地址。這时候日誌里的“訪客”其實全是代理,真實的蜘蛛来源和用戶来源都被盖住了。日誌失真不會立刻让站点出問题,但會让後續的抓取分析、異常排查、限流策略全部建立在错誤的資料上。
後端看到的到底是谁
当請求鏈路是 用戶 → CDN → 反向代理 → 應用 时,應用层拿到的是最後一跳的连接地址。常见情况有:
- 應用日誌里整頁都是 127.0.0.1 或 10.x 内網段,因為 Nginx 就在本机轉發;
- CDN 回源时,後端记錄的是 CDN 节点 IP,用戶 IP 只存在于請求头里;
- 负载均衡後面挂了多台机器,日誌里只有 LB 的地址。
常见的来源 IP 請求头
- X-Forwarded-For:逗号分隔的列表,最左邊通常是原始客戶端,後面依次是各級代理;
- X-Real-IP:多數场景只放一跳的客戶端地址,简單但依赖上游是否設定;
- CF-Connecting-IP、True-Client-IP 等:特定服務商提供,语义更明确;
- Forwarded:标准头,實际使用率不算高。
需要留意的是,這些头客戶端自己也能寫。所以取值之前要先確認“這個請求是不是来自可信代理”,否則等于把判断權交给了任意訪客。
配置上的几個要点
- 只信任自己掌握的代理網段。Nginx 的 set_real_ip_from 應寫 CDN 回源段或内網段,而不是 0.0.0.0/0。
- 明确指定從哪個头取值,例如 real_ip_header X-Forwarded-For,並配合 real_ip_recursive 决定是否逐跳回溯。
- 代理层在轉發时主動重寫或追加头,避免把用戶传来的同名头原样带到後端。
- 應用侧不要各處直接讀 socket 地址做业務判断,统一走一個封装好的取 IP 函數。
日誌格式建议
日誌里至少保留客戶端 IP、請求時間、方法、URL、狀態碼、响應時間、UA 和 Referer。UA 是识別蜘蛛的直接线索,但同样可以被伪造,所以它更适合用来做分類統計,而不是單獨的准入依據。若站点有多层代理,可以額外记下命中的代理节点,出問题时能快速判断是哪一段丢失了信息。
怎么驗證是否生效
- 從外部網絡訪問一個會回顯 IP 的測試頁面,對比日誌里的值與頁面顯示的值是否一致;
- 用命令行工具指定 UA 和来源头請求一次,看日誌是否按预期记錄;
- 抽查几段歷史日誌,看同一時間段内 IP 分布是否突然集中到少數几個地址。
日誌字段的價值在于可信。如果来源 IP 不可信,基于它做的限流、封禁、抓取統計都會连带失真。
把這些理顺之後,再回头看抓取频次、異常請求、回源比例這些指标,判断才有基础。代理配置本身不难,难的是長期保持一致——換 CDN、加节点、調整回源規則时,记得同步检查一遍取 IP 的逻辑。