場景描述:
訪問路徑: A機器 - > B機器的 ->C虛擬機 :
A機器為客戶端用戶,本地地址為 192.168.0.110
B機器為服務端反向代理服務器 本地地址為192.168.0.128 –>(192.168.56.1)
C機器為B主機安裝的linux虛擬機,并安裝了nginx ,本地ip為**(192.168.56.10)**
從側面反映了反向代理的好處,直接從A是無法訪問C的,但是在B中做了反向代理 ,就能訪問了,保護了服務端的地址。而無法將C的ip暴露給客戶端A
注意:在B和C直接由于使用了虛擬機,虛擬機的網(wǎng)關的ip為192.168.56.1 所以 在C端取到的上一層ip為192.168.56.1
目的: 在C機器取到 A的ip地址,并輸出日志客戶端的真實ip為192.168.0.110
B機器的nginx 配置:(首層代理)
location /bb/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://192.168.56.10/cc/;
}
在B中的nginx 中 給請求設置了 header 。 X-Real-IP 和 X-Forwarded-For
X-Real-IP 取得值是 r e m o t e a d d r ,而 remote_addr ,而 remotea?ddr,而remote_addr為與主機B直連客戶端A 的ip地址。
X-Forwarded-For 取得值是個用逗號分隔得多個值,主要包括客戶端X-Forwarded-For的值 與 $remote_addr 的值,兩部分用逗號分隔。
所以此時 X-Real-IP 為 192.168.0.110, X-Forwarded-For 為 ,192.168.0.110 此時客戶端并未主動傳 X-Forwarded-For 頭。
-
proxy_set_header X-Real-IP $remote_addr;
這句的作用是將客戶端的IP地址賦值給X-Real-IP請求頭,$remote_addr變量表示與nginx服務器直接連接的客戶端或代理服務器的IP地址。這句一般用于第一層代理服務器,以便后續(xù)的代理服務器能夠獲取到客戶端的IP地址。 -
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
這句的作用是將客戶端請求頭中的X-Forwarded-For和 r e m o t e a d d r 兩部分用逗號分隔后賦值給 X ? F o r w a r d e d ? F o r 請求頭, remote_addr兩部分用逗號分隔后賦值給X-Forwarded-For請求頭, remotea?ddr兩部分用逗號分隔后賦值給X?Forwarded?For請求頭,proxy_add_x_forwarded_for變量表示客戶端請求頭中的X-Forwarded-For和$remote_addr兩部分。這句一般用于非首層代理服務器,以便將客戶端和所有經過的代理服務器的IP地址都記錄下來。
C中nginx 輸出的log-format
log_format main '$http_x_forwarded_for|$realip_remote_addr|$http_x_real_ip|$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$upstream_addr $request_time $upstream_response_time ';
C中nginx的配置
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# real_ip_header X-Forwarded-For;
# set_real_ip_from 192.168.56.1;
# real_ip_recursive on;
}
在這一層中 X-Real-IP 取到的是上層代理的地址,也就是192.168.56.1
X-Forwarded-For 是上兩層的地址? : 192.168.0.110,192.168.56.1 (這一層其實就一個值還是192.168.0.110,在下一層才是這兩個值,這里有些歧義,原因是這一層接收到值之后 還沒有拼接本層獲取上一層的地址。這一層只是待發(fā)送狀態(tài)。proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for 這個是將頭拼接后發(fā)給下一層的。所以在下一層取到地址才是 192.168.0.110,192.168.56.1 )
所以在c中的輸出日志中打印的值為
192.168.0.110|192.168.56.1|192.168.0.110|192.168.56.1 - - [15/Sep/2023:02:32:43 +0000] "GET /cc/ HTTP/1.0" 200 15539 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36" "192.168.0.110" 123.121.155.167:16002 0.326 0.326
如果我使用nginx自帶的模塊 realip 再固定一層,重點觀察$remote_addr的值
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
real_ip_header X-Forwarded-For;
set_real_ip_from 192.168.56.1;
real_ip_recursive on;
}
如果我將配置改成這樣,我們再來觀察一下日志輸出
192.168.0.110|192.168.56.1|192.168.0.110|192.168.0.110 - - [15/Sep/2023:02:46:38 +0000] "GET /cc/ HTTP/1.0" 200 15539 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36" "192.168.0.110" 123.121.155.167:16002 0.796 0.796
上述描述只是兩層代理,為了測試出 X-Forwarded-For 的值,我們設置了3層代理。
A -》B-》c-》d
A:192.168.0.110 B:192.168.0.104 C:192.168.0.128(192.168.56.1) D:192.168.56.10
B nginx 配置:
location /testIp/ {
# set $current-X-Fowarded-for X-Forwarded-For
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://192.168.0.128:6666/testIp/;
}
C nginx配置:
location /testIp/ {
# set $current-X-Fowarded-for X-Forwarded-For
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.56.10/testIp/;
}
D nginx 配置:
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# real_ip_header X-Forwarded-For;
# set_real_ip_from 192.168.56.1;
# real_ip_recursive on;
.....
localtion /testIp/ {
porxy_pass http://666.com
}
}
D 中nginx的日志
192.168.0.110, 192.168.0.104|192.168.56.1|192.168.0.104|192.168.56.1 - - [15/Sep/2023:03:26:30 +0000] "GET /testIp/ HTTP/1.0" 200 15539 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36" "192.168.0.110, 192.168.0.104" 192.168.0.104:82 0.299 0.299
192.168.0.110, 192.168.0.104 是輸出的X-forwarded-for 的值。
real_ip_header X-Forwarded-For;
set_real_ip_from 192.168.56.1;
real_ip_recursive on;
這三個值一般是加到最后的D中,為了設置授信ip為上層的remot_addr的值,
- set_real_ip_from:用于設置信任的 IP,即請求頭中的 IP 中 nginx 認為可信的 IP。一般是前幾層代理的 IP。
- real_ip_header:用于告訴 nginx 從哪個請求頭字段中獲取客戶端真實的 IP。一般是 X-Forwarded-For 或 X-Real-IP。
- real_ip_recursive:用于控制 nginx 如何從請求頭字段中獲取多個 IP 中的一個。當值為 on 時,nginx 會從右往左排除信任的 IP,取最后一個非信任的 IP 作為客戶端真實的 IP。
例如,如果您想從 X-Forwarded-For 字段中獲取客戶端真實的 IP,并且信任 192.168.56.1 這個 IP,您可以在 location 中添加以下代碼:
location /test {
proxy_pass http://backend;
real_ip_header X-Forwarded-For;
set_real_ip_from 192.168.56.1;
real_ip_recursive on;
}
這樣,nginx 就會把 X-Forwarded-For 字段中最后一個非 192.168.56.1 的 IP 賦值給 $remote_addr 變量,作為客戶端真實的 IP。文章來源:http://www.zghlxwxcb.cn/news/detail-742640.html
對于nginx 獲取客戶端真實ip做個總結
- 對于首層代理服務器,使用
proxy_set_header X-Forwarded-For $remote_addr;
來將客戶端IP賦值給X-Forwarded-For請求頭 - 對于非首層代理服務器,使用
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
來將客戶端請求頭中的X-Forwarded-For和$remote_addr兩部分用逗號分隔后賦值給X-Forwarded-For請求頭
ursive on;
}
這樣,nginx 就會把 X-Forwarded-For 字段中最后一個非 192.168.56.1 的 IP 賦值給 $remote_addr 變量,作為客戶端真實的 IP。
對于nginx 獲取客戶端真實ip做個總結
對于首層代理服務器,使用proxy_set_header X-Forwarded-For $remote_addr;
來將客戶端IP賦值給X-Forwarded-For請求頭文章來源地址http://www.zghlxwxcb.cn/news/detail-742640.html
- 對于非首層代理服務器,使用
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
來將客戶端請求頭中的X-Forwarded-For和$remote_addr兩部分用逗號分隔后賦值給X-Forwarded-For請求頭 - 如果有多層代理服務器,可以使用nginx的realip模塊來從XFF中拋棄指定的可信IP,從而獲取用戶真實IP
到了這里,關于nginx配置獲取客戶端的真實ip的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!