网站前面挂了代理,日志里记到的客户端地址为什么全是代理
挂上反向代理之后,访问日志和统计里看到的客户端地址全是同一个内网或代理地址,这不是日志写错了:从程序的视角看,这条 TCP 连接确实来自代理。真实来源只能从转发头里取,而这个头的可信度需要专门处理,取错会比不取更麻烦。
地址列表的左右顺序意味着什么
转发头里是一个逗号分隔的地址列表。按文档的定义,最右边那一个是最近的代理,最左边那一个声称是原始客户端。每经过一层代理,就会在末尾追加一层,因此列表从左到右读的是「声称的来源到最近的转发者」,可信度是从左到右递增的。
这意味着两种取法要分开:想还原访客地址,取的是列表中最左侧那一个;想知道这一跳是谁连上来的,取的是直连地址而不是头里的内容。
为什么不能整串照收
因为客户端自己也能写这个头。如果程序直接信任整个列表,攻击者可以预先塞进任意地址,让后面的判定全部失真。文档给出的边界很直接:只要服务器可以被公网直连,那么列表里没有哪一部分可以被认为是可信的、可用于安全相关用途。
| 用途 | 能不能用转发头 | 取值口径 |
|---|---|---|
| 访问量与地域统计 | 可以用,容忍误差 | 取最左,允许为空 |
| 接口限速 | 只信可信代理追加的地址 | 从右往左剥到已知代理 |
| 按地址封禁与访问控制 | 同上,必须严格 | 同上 |
| 审计与追溯 | 需要与网关日志对齐 | 两层记录交叉核对 |
哪些用途能信哪些不能
统计类用途出错影响的是报表,可以接受一定噪声。限速、封禁、防采集这类按地址做的判断一旦取错就会反过来:把代理地址当成访客,等于让整站访客共用一个配额;把伪造地址当成访客,等于让攻击者替自己决定封禁谁。所以这一层的规则是同一条——只使用由可信代理追加的那部分。做法是从右往左依次剥掉已知的代理与负载均衡地址,第一个不在可信名单里的位置才是真正连上来的来源。
部署侧的三步对齐
第一步是固定链路:确认站点只能经代理访问,源站不直接暴露公网,否则上面的可信前提不成立。第二步是在部署层配置可信代理范围,宝塔面板或自建 Nginx 都要把代理段地址写进去,让程序知道该从哪一层开始取值;用 Docker 镜像部署时同样要把这一层配置带进去,不能只改网关。第三步是让日志与统计的口径一致:写入时用的字段和读取时用的字段必须是同一个,否则历史数据无法对比。
数据迁移与备份恢复时也要连这一层一起核对。备份里包含静态文件与配置,恢复后如果可信代理配置没有跟着回来,日志会重新退化成满屏代理地址,访问统计与按地址的防护都会同时失真。
常见问题
问:为什么不直接用真实 IP 扩展头? 自定义头只有在代理与源站之间的链路完全可控时才有意义,通用做法仍然是按可信代理列表处理标准转发头。
问:访客用代理或浏览器插件会不会让地址变错? 会。列表最左侧那一个是声称的来源,可能被客户端改写,统计可以接受,安全判定不能接受。
问:IPv6 地址要不要特殊处理? 需要。可信名单与剥离逻辑都要同时覆盖两个协议族,只写其中一段会让另一段全部落到不可信分支。