如何通过Nginx的Proxy-Set-Header功能将客户端IP透传给后端服务器?
- 内容介绍
- 文章标签
- 相关推荐
本文共计779个文字,预计阅读时间需要4分钟。
在Nginx作为反向代理时,配置示例如下:
确保 Nginx 正确透传真实 IP 头字段
Nginx 本身不自动识别“真实 IP”,需根据上游来源显式设置 HTTP 头。常见组合如下:
-
X-Real-IP:最简方式,只传一个 IP(推荐用于单层代理)
proxy_set_header X-Real-IP $remote_addr; -
X-Forwarded-For:标准字段,支持追加(多层代理时保留原始链路)
proxy_set_header X-Forwarded-For $remote_addr;
若已有值(如上一级代理已设),可用$proxy_add_x_forwarded_for自动追加:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - X-Forwarded-Proto 和 X-Forwarded-Host:辅助传递协议与域名,避免后端误判 HTTPS 或生成错误链接
限定可信代理范围,防止 IP 伪造
仅设 header 不够——攻击者可手动发送 X-Forwarded-For: 1.2.3.4 伪造 IP。Nginx 必须明确知道哪些客户端是“可信代理”,才信任其携带的转发头。
- 使用
set_real_ip_from声明可信代理 IP 段(如负载均衡器、CDN 回源 IP、内网网关)
例如:set_real_ip_from 10.0.0.0/8;或set_real_ip_from 203.208.60.1; - 指定真实 IP 来源字段:
real_ip_header X-Forwarded-For;(若 CDN 用该头)或real_ip_header X-Real-IP; - 启用后,
$remote_addr将自动替换为解析出的真实客户端 IP,后续proxy_set_header X-Real-IP $remote_addr;才真正有效
后端服务必须主动读取对应 Header
Nginx 设置只是“发出去”,后端框架默认仍读 REMOTE_ADDR(即连接发起方 IP)。必须显式从 header 中提取:
-
PHP:用
$_SERVER['HTTP_X_REAL_IP']或$_SERVER['HTTP_X_FORWARDED_FOR'](注意后者可能是逗号分隔列表,取第一个) -
Spring Boot:配置
server.forward-headers-strategy=framework,并使用HttpServletRequest.getRemoteAddr()(自动适配);或手动读request.getHeader("X-Real-IP") -
Node.js(Express):启用
app.set('trust proxy', true),再用req.ip或req.headers['x-real-ip'] - 务必校验 header 是否来自可信源(如检查是否仅在内网请求中存在),避免开放代理被滥用
验证与排错要点
透传失败常见于配置遗漏或顺序错误:
-
set_real_ip_from和real_ip_header必须放在server或http块,且在location之前生效 - 检查 Nginx 配置语法:
nginx -t;重载:nginx -s reload - 用
curl -H "X-Forwarded-For: 1.1.1.1" http://your-domain/测试伪造是否被忽略(应返回真实 IP) - 在后端打印所有 headers,确认
X-Real-IP或X-Forwarded-For是否到达、内容是否正确
本文共计779个文字,预计阅读时间需要4分钟。
在Nginx作为反向代理时,配置示例如下:
确保 Nginx 正确透传真实 IP 头字段
Nginx 本身不自动识别“真实 IP”,需根据上游来源显式设置 HTTP 头。常见组合如下:
-
X-Real-IP:最简方式,只传一个 IP(推荐用于单层代理)
proxy_set_header X-Real-IP $remote_addr; -
X-Forwarded-For:标准字段,支持追加(多层代理时保留原始链路)
proxy_set_header X-Forwarded-For $remote_addr;
若已有值(如上一级代理已设),可用$proxy_add_x_forwarded_for自动追加:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - X-Forwarded-Proto 和 X-Forwarded-Host:辅助传递协议与域名,避免后端误判 HTTPS 或生成错误链接
限定可信代理范围,防止 IP 伪造
仅设 header 不够——攻击者可手动发送 X-Forwarded-For: 1.2.3.4 伪造 IP。Nginx 必须明确知道哪些客户端是“可信代理”,才信任其携带的转发头。
- 使用
set_real_ip_from声明可信代理 IP 段(如负载均衡器、CDN 回源 IP、内网网关)
例如:set_real_ip_from 10.0.0.0/8;或set_real_ip_from 203.208.60.1; - 指定真实 IP 来源字段:
real_ip_header X-Forwarded-For;(若 CDN 用该头)或real_ip_header X-Real-IP; - 启用后,
$remote_addr将自动替换为解析出的真实客户端 IP,后续proxy_set_header X-Real-IP $remote_addr;才真正有效
后端服务必须主动读取对应 Header
Nginx 设置只是“发出去”,后端框架默认仍读 REMOTE_ADDR(即连接发起方 IP)。必须显式从 header 中提取:
-
PHP:用
$_SERVER['HTTP_X_REAL_IP']或$_SERVER['HTTP_X_FORWARDED_FOR'](注意后者可能是逗号分隔列表,取第一个) -
Spring Boot:配置
server.forward-headers-strategy=framework,并使用HttpServletRequest.getRemoteAddr()(自动适配);或手动读request.getHeader("X-Real-IP") -
Node.js(Express):启用
app.set('trust proxy', true),再用req.ip或req.headers['x-real-ip'] - 务必校验 header 是否来自可信源(如检查是否仅在内网请求中存在),避免开放代理被滥用
验证与排错要点
透传失败常见于配置遗漏或顺序错误:
-
set_real_ip_from和real_ip_header必须放在server或http块,且在location之前生效 - 检查 Nginx 配置语法:
nginx -t;重载:nginx -s reload - 用
curl -H "X-Forwarded-For: 1.1.1.1" http://your-domain/测试伪造是否被忽略(应返回真实 IP) - 在后端打印所有 headers,确认
X-Real-IP或X-Forwarded-For是否到达、内容是否正确

