要让 real_ip_header 在多级 CDN + 反向代理环境下真正生效,关键不是简单写一行指令,而是把它嵌入一套完整的可信链校验机制中——它只在上游 IP 被确认可信后才开始解析头字段,否则直接忽略。

要让 real_ip_header 在多级 CDN + 反向代理环境下真正生效,关键不是简单写一行指令,而是把它嵌入一套完整的可信链校验机制中——它只在上游 IP 被确认可信后才开始解析头字段,否则直接忽略。
必须先声明可信代理来源(set_real_ip_from)
real_ip_header 不会无条件读取 X-Forwarded-For,它只对来自可信网段的请求起作用。如果没配 set_real_ip_from,或配错范围,Nginx 会直接跳过解析,$remote_addr 始终是上一跳代理 IP。
- 列出所有实际参与转发的可信出口网段:CDN 回源 IP 段(如 Cloudflare 的
173.245.48.0/20、阿里云全站加速的121.194.0.0/16)、负载均衡器内网段(如10.100.0.0/16)、前置 Nginx 集群段(如192.168.50.0/24) - 禁止使用
0.0.0.0/0或模糊网段,否则伪造 X-Forwarded-For 可绕过校验 - 每行一个
set_real_ip_from,支持 IPv4 和 IPv6,顺序无关
明确指定解析目标头(real_ip_header)
推荐统一用 X-Forwarded-For 作为解析源,而不是 X-Real-IP。因为多级代理中,只有 X-Forwarded-For 保证逐跳追加,而 X-Real-IP 在每一层都被覆盖为当前 $remote_addr,链路信息不可回溯。
- 写法:
real_ip_header X-Forwarded-For; - 确保前端所有代理(CDN、WAF、LB、Nginx-A、Nginx-B)都配置了
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - 若某 CDN 提供专用头(如 Cloudflare 的
CF-Connecting-IP),可改用real_ip_header CF-Connecting-IP;,但需确认该头仅由 CDN 注入且不可被客户端篡改
启用递归剥离(real_ip_recursive on)
多级代理下,X-Forwarded-For 值形如 203.0.113.45, 198.51.100.1, 203.0.113.10。real_ip_recursive 控制 Nginx 从右往左剔除已知可信 IP,最终留下最左边那个“不可信”的 IP —— 它才是真实客户端 IP。
- 必须开启:
real_ip_recursive on; - 关闭时(默认 off),Nginx 只取 X-Forwarded-For 最左 IP,不校验中间跳是否可信,极易被伪造
- 开启后,Nginx 会依次比对
203.0.113.10 → 198.51.100.1 → 203.0.113.45,跳过前两个(若它们落在 set_real_ip_from 中),最终将203.0.113.45赋给 $remote_addr 和 $realip_remote_addr
验证与日志落地
配置生效后,真实 IP 才会进入业务逻辑和日志系统,不能只看 header 是否存在。
- 检查模块是否启用:
nginx -V 2>&1 | grep -o http_realip_module,无输出说明未编译该模块 - 在 log_format 中使用
$realip_remote_addr(不是$remote_addr)记录 IP,例如:log_format main '$realip_remote_addr ...'; - 访问时抓包或查看 access_log,确认字段值符合预期;若仍为 CDN IP,优先排查 set_real_ip_from 是否遗漏某一级代理网段

















