配置 X-Forwarded-For 的核心目标是每级代理正确追加客户端真实IP而非覆盖,需统一使用 $proxy_add_x_forwarded_for 并配合 set_real_ip_from 与 real_ip_recursive on 实现可信链路溯源。

配置 proxy_set_header X-Forwarded-For 的核心目标是:在每级代理中**正确追加**客户端真实 IP,而不是覆盖或丢失。关键不在于“设一次”,而在于“链路中每一跳都按规则处理”。否则容易出现 IP 被覆盖、伪造、或取到中间代理地址。
明确 X-Forwarded-For 的传递逻辑
X-Forwarded-For 是一个逗号分隔的 IP 列表,格式为:X-Forwarded-For: 客户端真实IP, 代理1, 代理2, ...
最左边(第一个)IP 才是原始客户端 IP。后续每经过一级可信代理,应在原有值末尾追加当前请求的 remote_addr(即上一跳的真实出口 IP),而非重写整条字段。
Nginx 中安全可靠的配置方式
使用 proxy_set_header X-Forwarded-For 时,必须结合 real_ip_recursive on 和可信源范围(set_real_ip_from),否则可能被恶意伪造:
- 在 upstream 前的 proxy 配置块中写:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
该变量会自动判断:若上游已有 XFF,则追加$remote_addr;若无,则用$remote_addr初始化。 - 在 server 或 http 块中声明可信代理网段(如 CLB、Nginx LB、CDN 回源 IP 段):
set_real_ip_from 10.0.0.0/8;<br>set_real_ip_from 192.168.0.0/16;<br>real_ip_recursive on;
- 启用后,
$remote_addr将自动替换为解析出的客户端真实 IP,日志和应用层可直接使用。
多级代理场景下的协同要点
当存在「CDN → CLB → Nginx LB → 应用」等多层时,每层都需遵守同一原则:
- 只信任来自已知代理网段的请求,并仅从这些请求中提取并追加 XFF;
- 禁止对公网直连请求设置或修改 XFF(防止伪造);
- CLB 七层监听默认开启 XFF 透传,无需额外开关;但四层监听不带 HTTP 头,此时应改用 Proxy Protocol;
- 后端应用读取时,应取
X-Forwarded-For字段中第一个非私有、合法格式的 IPv4/IPv6 地址(建议做基础校验,如正则匹配^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$)。
验证是否生效的实操方法
快速确认链路是否完整:
- 用 curl 模拟请求:
curl -H "X-Forwarded-For: 1.2.3.4" http://your-domain.com/test-ip.php
观察响应或日志中最终记录的 XFF 值是否变成1.2.3.4, [CLB_IP], [Nginx_IP]; - 检查 Nginx access_log 中
$http_x_forwarded_for和$remote_addr是否一致且合理; - 在应用代码中打印原始 header,确认未被中间层意外清除或覆盖。


















