在 Nginx 中,$remote_addr
是一个内置变量,用于记录 直接与 Nginx 建立 TCP 连接的客户端 IP 地址。它的值取决于客户端的连接方式以及是否存在中间代理(如 CDN、负载均衡器等)。
关键细节
直接访问时
- 如果客户端直接连接 Nginx(无代理),
$remote_addr
记录的是客户端的真实 IP(例如123.45.67.89
)。
- 如果客户端直接连接 Nginx(无代理),
通过代理访问时
- 如果请求经过反向代理(如 CDN、负载均衡器、Cloudflare),
$remote_addr
会记录最后一个代理服务器的 IP,而非原始客户端 IP。
- 此时需依赖代理传递的额外头(如
X-Forwarded-For
)获取真实 IP。
- 如果请求经过反向代理(如 CDN、负载均衡器、Cloudflare),
IPv4/IPv6
- 自动适配客户端的协议类型(如
192.168.1.1
或2001:db8::1
)。
- 自动适配客户端的协议类型(如
常见问题场景
如何获取真实客户端 IP?
当请求经过多层代理时,需结合以下配置:
location / {
proxy_pass http://backend;
# 从 X-Forwarded-For 中提取第一个 IP(原始客户端 IP)
set $real_ip $remote_addr;
if ($http_x_forwarded_for) {
set $real_ip $http_x_forwarded_for;
# 如果有多层代理,X-Forwarded-For 是逗号分隔的 IP 链
# set $real_ip $proxy_add_x_forwarded_for; # 等价于上一条
}
proxy_set_header X-Real-IP $real_ip;
}
为什么 $remote_addr
是本地 IP?
如果 Nginx 前面有本地反向代理(如 Docker、Kubernetes Ingress),$remote_addr
可能是内部网络 IP(如 172.17.0.2
)。此时仍需依赖 X-Forwarded-For
。
安全注意事项
信任边界
X-Forwarded-For
头可以被伪造,需确保只有可信代理能修改它(通过set_real_ip_from
+real_ip_header
)。
配置可信代理
real_ip_header X-Forwarded-For; set_real_ip_from trusted_proxy_ip; # 允许哪些代理修改 IP
总结
场景 | $remote_addr 值 |
---|---|
客户端直连 Nginx | 客户端真实 IP |
经过代理/CDN | 最后一个代理服务器的 IP |
如果需要可靠获取客户端真实 IP,必须正确配置代理链和 HTTP 头处理。
内容由零声教学AI助手提供,问题来源于学员提问