X-Forwarded-For 是什么
这个字段用来在代理链路上传递客户端地址:它是一串以逗号分隔的地址,最左边是最初发起请求的客户端,最右边是最近一跳代理。它并非正式规范定义的字段,而是事实标准,后来另有正式的转发字段作为替代。应用要拿到真实客户端地址,正确做法是固定可信代理层并让网关做递归剥离,而不是直接读第一个值——客户端可以随意伪造前面几段。
基本信息
| 名称 | 转发客户端地址字段,属于事实标准 |
|---|---|
| 结构 | 逗号分隔的地址链,最左为最初客户端 |
| 正式替代 | 另有标准化的转发字段,语义更清晰 |
| 安全前提 | 必须结合可信代理范围使用 |
| 风险 | 客户端可伪造链条前段 |
典型使用场景
- 访问日志:记录真实客户端地址而不是代理地址
- 限流与风控:按真实客户端做频率控制与封禁
- 地域分析:判断访问来源分布
- 审计合规:满足记录真实来源的要求
- 排障:确认请求经过了几层代理
让网关计算真实客户端地址
让网关计算真实客户端地址
# 只信任内部代理网段,其余来源的同名字段一律忽略
# 开启递归剥离后,网关会把可信层剥离,留下真实客户端地址
# 再把结果通过单独的头部传给后端,后端只读这个值
# 后端不要直接读原始链条的第一个地址,那是可以被伪造的两个字段的差别
| 对比项 | 事实标准字段 | 标准化转发字段 |
|---|---|---|
| 规范性 | 无正式规范,各家实现有差异 | 有正式规范,语义明确 |
| 结构 | 纯地址链 | 带参数的结构化表达 |
| 支持度 | 几乎所有代理都支持 | 支持度在逐步提升 |
排查要点
- 日志里出现代理地址,说明网关没有写回真实客户端地址
- 出现多个地址时,数一下层数,确认与自己的代理架构是否吻合
- 边缘节点改写后自家代理又追加一层,链中位置与预期不符是常见现象
直接取链条里第一个地址做限流或封禁,等于把控制权交给攻击者:伪造一个别人的地址就能让你封掉正常用户,或者让自己绕过限制。必须先固定可信代理并做递归剥离。
用日志分析时不要把真实客户端字段与连接来源地址两列混用:前者可能被伪造,后者是链路上实际与本机建连的地址。混用会导致风控规则误封代理节点。