很多站点在服务器上打开访问日志,会发现某个 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 的逻辑。