Nginx 的 real_ip_header 与 X-Forwarded-For 看起来不对,怎么配?

Nginx real_ip_header 正确姿势:real_ip_header X-Forwarded-For + set_real_ip_from 限定可信代理网段;多层代理用 real_ip_recursive;防伪造原理与 FAQ。

最佳实践
Nginx 的 real_ip_header 与 X-Forwarded-For 看起来不对,怎么配?封面

正确姿势是三个指令配合:set_real_ip_from 声明可信代理网段 → real_ip_header X-Forwarded-For 指定从哪个头取真实 IP → 多层代理链加 real_ip_recursive on 缺了 set_real_ip_from,X-Forwarded-For 谁都能伪造,等于没配。

标准配置

http {
    # 可信的代理/负载均衡网段(你的 CDN、SLB、前置 Nginx)
    set_real_ip_from 10.0.0.0/8;
    set_real_ip_from 172.16.0.0/12;
    # CDN 厂商的官方 IP 段逐条列上

    real_ip_header X-Forwarded-For;
    real_ip_recursive on;      # 多层代理时从右往左跳过可信 IP

    ...
}

工作原理(理解了就配不错)

请求经过"客户端 → CDN → SLB → Nginx"时,X-Forwarded-For 可能是:

X-Forwarded-For: 客户端IP, CDN节点IP

remote_addr 是直连 Nginx 的 SLB 地址。real_ip 模块的算法:

  1. 直连 IP 在 set_real_ip_from 里 → 可信,开始从 XFF 右侧往左检查;
  2. real_ip_recursive on:跳过所有落在可信网段里的 IP,第一个不可信的 IP 就是真实客户端;
  3. remote_addr 被改写为那个 IP,应用层拿到的就是真实来源。

常见翻车点

  • 没设 set_real_ip_from:模块不生效,remote_addr 还是代理 IP——"配了没用"。
  • 网段写窄了:代理换了出口 IP,Nginx 认为它不可信 → 取到的是代理自己的 IP 或 XFF 里错误的一格。
  • 递归没开:多层代理下只回退一格,拿到的还是中间代理地址。
  • 信任了客户端伪造:网段设得太宽(如 0.0.0.0/0),访客随手发个 X-Forwarded-For: 8.8.8.8 就伪装成功——基于 IP 的限流、审计全部失效。

验证

curl -H "X-Forwarded-For: 1.2.3.4" http://yoursite/debug-ip
# debug 接口回显 remote_addr,对照是否变为 1.2.3.4(仅当 curl 来源在可信段内)

再抓一条真实访问看 access log 里的 $remote_addr 是否已是真实客户端。

观测云对照

真实 IP 是访问日志里最重要的维度之一——风控、地域分析、异常排查全依赖它。日志接入观测云后,在日志查看器里按 $remote_addr 做地域分布、TOP 来源分析;IP 维度的突增告警还能帮你发现"限流规则因为拿到的是代理 IP 而形同虚设"这类配置事故。

常见问题(FAQ)

Q:CDN 厂商的 IP 段去哪找?
A:各厂商官网都公布回源 IP 段(通常提供 JSON/文本接口)。段会变,建议定期同步进配置,或用自动化工具生成。

Q:应用框架(如 Laravel/Express)还要再配信任代理吗?
A:要。Nginx 改的是自己的 $remote_addr;应用若从 X-Forwarded-For 取 IP,也得声明可信代理,否则同样会被伪造值欺骗。两层各管各的。

Q:CF-Connecting-IP 这类自定义头能用吗?
A:可以,real_ip_header CF-Connecting-IP;。但同样必须配合 set_real_ip_from 限定 Cloudflare 官方 IP 段,否则伪造更容易。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台