一、使用场景
- 日志记录
记录真实客户端 IP 而非反向代理的 IP,有助于流量分析和安全审计。 - 访问控制
基于真实 IP 实现防火墙规则(allow
/deny
)或限流,而非误将上游 IP 视为客户端。 - GeoIP、WAF、限速等功能
模块化的上游真实 IP 支持与诸如ngx_http_geoip_module
、limit_req
、WAF 插件等配合使用。
二、示例配置
http {
# 信任的上游地址列表(CIDR、单 IP 或 unix 域 socket)
set_real_ip_from 192.168.1.0/24;
set_real_ip_from 10.0.0.0/8;
set_real_ip_from unix:;
# 指定从哪个请求头获取真实地址
# 常见的有:X-Real-IP、X-Forwarded-For、proxy_protocol
real_ip_header X-Forwarded-For;
# 开启递归模式时,将跳过链中信任的上游,选取第一个非信任地址
real_ip_recursive on;
server {
listen 80;
location / {
# 此时 $remote_addr 是真实客户端 IP
proxy_pass http://backend;
}
}
}
三、指令详解
1. set_real_ip_from
Syntax: set_real_ip_from address | CIDR | unix:;
Default: —;
Context: http, server, location
- address | CIDR:IPv4/IPv6 网络或单地址,如
192.168.2.1
、2001:db8::/32
。 - unix::信任所有 UNIX 域套接字连接。
- 用途:指定哪些上游代理地址可信,只有来自这些源的请求头中携带的 IP 才会被视为真实客户端。
注意
- 支持主机名(1.13.1 起),解析后再进行匹配。
- IPv6 支持自 1.2.1/1.3.0 起。
2. real_ip_header
Syntax: real_ip_header field | X-Real-IP | X-Forwarded-For | proxy_protocol;
Default: real_ip_header X-Real-IP;
Context: http, server, location
- field:HTTP 请求头名,常见有
X-Real-IP
或X-Forwarded-For
。 - proxy_protocol:从 PROXY 协议头部获取地址,需先在
listen
中启用proxy_protocol
。 - 端口替换:若头部中同时包含 IP:PORT,则还可替换
$remote_port
。
3. real_ip_recursive
Syntax: real_ip_recursive on | off;
Default: real_ip_recursive off;
Context: http, server, location
- off(默认):取请求头最末尾(最后一个)IP,只要发现第一个可信代理,即替换为该代理后面的 IP。
- on:递归查找,跳过所有可信代理,取第一个非信任地址,适用于多级反代场景。
四、内置变量
变量 | 含义 |
---|---|
$realip_remote_addr |
原始客户端 IP(被替换前的 $remote_addr ) |
$realip_remote_port |
原始客户端端口(被替换前的 $remote_port ) |
这些变量可用于日志或者后续条件判断,方便同时保留“原始代理IP”与“替换后真实IP”。
五、处理流程
接收请求
Nginx 监听到请求,初始$remote_addr
为 TCP 连接的对端地址。匹配可信源
检查该地址是否在任一set_real_ip_from
列表中。提取头部值
读取real_ip_header
指定的头部字段,按逗号拆分(若是X-Forwarded-For
,可能包含多级 IP)。选取 IP
real_ip_recursive off
:取列表末尾(最后一个)IP;real_ip_recursive on
:倒序遍历,跳过可信源,取第一个非信任 IP。
替换地址
更新$remote_addr
(及可选$remote_port
),并记录旧值至$realip_remote_addr
。继续其它模块处理
后续日志、WAF、限速等模块均以新的$remote_addr
为准。
六、常见注意事项
- 安全性
仅信任可信网络或反向代理,避免客户端伪造X-Forwarded-For
欺骗源 IP。 - 多级代理
开启real_ip_recursive on
以正确获取最初客户端 IP;否则仅能获取到第一级代理前的 IP。 - PROXY 协议
使用proxy_protocol
时,需要在listen ... proxy_protocol;
中启用,并由上游(如 LVS、HAProxy)发送 PROXY 首部。 - 端口保留
若需要真实端口信息,可在头部中附加<ip>:<port>
格式,并确保 Nginx 版本 ≥1.11.0。
通过 ngx_http_realip_module
,可以在 Nginx 层面安全、灵活地恢复原始客户端 IP 和端口,为日志、限流、安全防护等功能提供可靠的基础。