要准确透传真实客户端IP需前后端协同:前端每级Nginx用$proxy_add_x_forwarded_for追加X-Forwarded-For、设X-Real-IP为$remote_addr;后端Nginx启用http_realip_module,配置set_real_ip_from限定可信代理IP段,real_ip_header X-Real-IP,real_ip_recursive on;应用层优先读HTTP_X_REAL_IP,其次解析X-Forwarded-For首IP,并校验有效性。

要让真实客户端IP在多级Nginx反向代理链中准确透传,关键不是简单加几个header,而是前后端配合、信任链明确、解析逻辑可靠。一级代理能传对,不等于多级就自动正确——中间每跳都可能篡改或混淆IP字段。
前端代理必须设置正确的X-Forwarded-For和X-Real-IP
每一级Nginx都需要主动把上一跳看到的客户端IP写入请求头,不能依赖后端自己“猜”。标准做法是:
-
X-Real-IP:始终设为当前收到请求的
$remote_addr,代表这一跳直接连接的上游地址(对首层代理来说就是真实用户) -
X-Forwarded-For:用
$proxy_add_x_forwarded_for追加,它会自动在原有值后拼上$remote_addr,保留完整路径 - 避免手动拼接
X-Forwarded-For,否则容易覆盖原始链路或引入空值
后端服务需启用realip模块并限定可信源
仅靠header传递还不够。后端Nginx必须加载http_realip_module(编译时加--with-http_realip_module),并在配置中明确指定哪些IP是可信代理:
-
set_real_ip_from 192.168.1.10;—— 每一级代理的出口IP都要单独写一行 -
real_ip_header X-Real-IP;—— 告诉Nginx从哪个header取真实IP -
real_ip_recursive on;—— 开启递归解析,当X-Forwarded-For含多个IP时,从右往左找第一个非可信IP
不设set_real_ip_from,Nginx默认只信127.0.0.1;设错范围,会导致IP被伪造或丢失。
多级场景下X-Forwarded-For的格式与风险
假设链路是:用户 → Nginx-A → Nginx-B → 应用,那么X-Forwarded-For最终形如:
用户IP, Nginx-A的出口IP, Nginx-B的出口IP
- 最左边是原始客户端IP,最右边是最后一跳代理IP
- 如果某一级未设
X-Forwarded-For,链路就会中断,后续无法还原全路径 - 该字段可被客户端伪造,所以绝不能直接用于权限判断——必须结合
set_real_ip_from做可信校验
应用层读取建议:优先用HTTP_X_REAL_IP,备选X-Forwarded-For
后端代码(如PHP/Java/Node.js)应按如下顺序安全获取:
- 先尝试读
HTTP_X_REAL_IP(由realip模块注入,已校验可信) - 若为空,再取
HTTP_X_FORWARDED_FOR的第一个IP(需自行split并trim) - 最后 fallback 到
REMOTE_ADDR(仅作兜底,通常只是最后一跳代理IP) - 对所有来源IP做基础校验(如排除
127.0.0.1、::1、私有网段等无效值)


















