一、使用場景
- 日志記錄
記錄真實客戶端 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_protocolreal_ip_header X-Forwarded-For;# 開啟遞歸模式時,將跳過鏈中信任的上游,選取第一個非信任地址real_ip_recursive on;server {listen 80;location / {# 此時 $remote_addr 是真實客戶端 IPproxy_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 和端口,為日志、限流、安全防護等功能提供可靠的基礎。