Nginx 传递客户端真实 IP 需同时配置 proxy_set_header 设置 X-Real-IP、X-Forwarded-For 等头字段,并配合 set_real_ip_from 和 real_ip_header 指令限定可信代理范围,后端还需正确解析,日志验证不可省略。

要在 Nginx 的 Virtual Host(即 server 块)中正确传递客户端真实 IP,关键不是“防止被代理掩盖”,而是主动、可信地把原始 IP 通过标准 HTTP 头传给后端,并让后端能安全识别它。Nginx 本身不隐藏 IP,但若配置不当,后端看到的就只是 Nginx 自己的 IP。
确保 proxy_set_header 正确设置
在 location 块内必须显式设置以下头字段,不能依赖默认值:
-
X-Real-IP:直接设为
$remote_addr,适用于单层代理场景 -
X-Forwarded-For:用
$proxy_add_x_forwarded_for,它会在原有值后追加当前 Nginx 的 IP,保留完整链路 -
Host:设为
$host或$http_host,保证后端收到原始请求域名 -
X-Forwarded-Proto:设为
$scheme,让后端知道用户访问的是 http 还是 https
限制可信代理范围(防伪造)
仅靠传递头是不够的——攻击者可手动构造 X-Forwarded-For。必须配合 set_real_ip_from 和 real_ip_header 指令,告诉 Nginx 哪些来源的请求头可信:
- 在
http或server块顶部添加:set_real_ip_from 10.0.0.0/8;(替换成你实际的上游代理或负载均衡器网段) - 指定信任的头:
real_ip_header X-Forwarded-For; - 开启递归解析:
real_ip_recursive on;,这样 Nginx 会从右往左找第一个非可信 IP 作为真实客户端 IP
注意:set_real_ip_from 必须精确——写成 0.0.0.0/0 等同于完全信任任意伪造头,存在严重风险。
后端需配合解析,不能只看原始 remote_addr
Nginx 传了头,后端不读等于白传。常见框架需额外配置:
-
Spring Boot:在
application.properties中启用 RemoteIpValve:server.tomcat.remote-ip-header=x-forwarded-for,并设置server.tomcat.protocol-header=x-forwarded-proto -
Tomcat(独立部署):在
server.xml的<host></host>内添加:<valve classname="org.apache.catalina.valves.RemoteIpValve"></valve> -
Node.js / Python 等自研服务:代码中优先读取
X-Real-IP,若为空则取X-Forwarded-For最右边非私有地址的 IP(如192.168.x.x、10.x.x.x应跳过)
日志与验证环节不能省
光配不验证,容易出问题。建议:
- 定义含真实 IP 的日志格式:
log_format main '$http_x_forwarded_for - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'; - 将该格式应用到
access_log,观察日志中$http_x_forwarded_for是否稳定输出客户端公网 IP - 用
curl -H "X-Forwarded-For: 1.2.3.4" http://your-domain/测试——如果日志里真出现1.2.3.4,说明未启用set_real_ip_from或配置错误,需立即修正


















