Nginx中透?jìng)骺蛻舳苏鎸?shí)IP的技巧
概述
1. 為什么需要獲取客戶端的真實(shí) IP 地址?
在使用 Nginx 作為反向代理服務(wù)器時(shí),默認(rèn)情況下,后端服務(wù)器只能看到 Nginx 的IP地址。為了記錄日志、限制訪問(wèn)或進(jìn)行其他基于 IP 地址的操作,獲取客戶端的真實(shí) IP 地址非常重要。
2. Nginx 中用于獲取真實(shí) IP 地址的模塊
Nginx 提供了兩個(gè)主要模塊來(lái)處理這一需求:
- HttpRealipModule: 用于從請(qǐng)求頭中提取客戶端的真實(shí) IP 地址。
- HttpGeoipModule: 用于根據(jù) IP 地址定位地理位置(較少用于獲取真實(shí) IP)。
這里主要介紹 HttpRealipModule
。
3. 配置示例和步驟
3.1 安裝和啟用模塊
大多數(shù)情況下,Nginx 已經(jīng)包含了 HttpRealipModule
??梢酝ㄟ^(guò)以下命令檢查:
nginx -V 2>&1 | grep -o with-http_realip_module
如果沒(méi)有啟用該模塊,則需要重新編譯 Nginx 或安裝包含該模塊的 Nginx 版本。
3.2 配置 Nginx
編輯你的 Nginx 配置文件(通常位于 /etc/nginx/nginx.conf
或 /etc/nginx/conf.d/
中的某個(gè)文件),添加以下配置:
http { ... set_real_ip_from 0.0.0.0/0; # 允許所有 IP 地址的代理 real_ip_header X-Forwarded-For; real_ip_recursive on; ... server { ... location / { ... # 如果需要日志中記錄真實(shí) IP log_format custom '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log custom; ... } } }
3.3 配置說(shuō)明
set_real_ip_from
: 允許哪些 IP 地址可以作為可信代理。如果你的代理服務(wù)器在特定的 IP 范圍內(nèi),只允許那些 IP。real_ip_header
: 指定哪個(gè)頭部字段包含了真實(shí) IP 地址。常用的是X-Forwarded-For
。real_ip_recursive
: 遞歸地檢查X-Forwarded-For
頭部中的所有 IP 地址,直到找到第一個(gè)非可信代理的 IP。
4. 潛在的陷阱和調(diào)試方法
4.1 潛在的陷阱
- 代理鏈中的 IP 地址順序:
X-Forwarded-For
頭部可能包含多個(gè) IP 地址,代表了一系列代理服務(wù)器。確保配置的real_ip_recursive on
正確地獲取到第一個(gè)客戶端的 IP 地址。 - 安全問(wèn)題:配置
set_real_ip_from
時(shí),要小心不要信任不受控制的 IP 地址,否則可能會(huì)導(dǎo)致 IP 欺騙。
4.2 調(diào)試方法
- 檢查日志:通過(guò)查看 Nginx 日志,確認(rèn)是否成功獲取到真實(shí) IP 地址。
- 測(cè)試請(qǐng)求:使用工具如
curl
模擬請(qǐng)求,帶上X-Forwarded-For
頭部,觀察服務(wù)器的響應(yīng)和日志記錄。
curl -H "X-Forwarded-For: 203.0.113.195" http://your-nginx-server
實(shí)操
http 節(jié)點(diǎn) 添加$http_x_forwarded_for日志格式
配置文件中需要添加$http_x_forwarded_for日志格式, 核心內(nèi)容如下
http { include mime.types; default_type application/octet-stream; log_format main ' $remote_addr | $http_x_forwarded_for | $remote_user | $time_local | $request | $http_host |' ' $status | $upstream_status | $body_bytes_sent | $http_referer ' ' $http_user_agent | $upstream_addr | $request_time | $upstream_response_time';
http節(jié)點(diǎn) 日志格式中需要添加$http_x_forwarded_for
log_format
指令用于定義 Nginx 的日志格式。它指定了在日志文件中記錄哪些信息以及如何格式化這些信息。每個(gè)字段使用一個(gè)變量表示,變量之間可以用分隔符分開(kāi),如空格、豎線(|
)等。定義的日志格式可以應(yīng)用于 access_log
指令,以便記錄客戶端請(qǐng)求的詳細(xì)信息。
以下是 log_format
指令中各個(gè)變量的含義:
log_format main ' $remote_addr | $http_x_forwarded_for | $remote_user | $time_local | $request | $http_host |' ' $status | $upstream_status | $body_bytes_sent | $http_referer ' ' $http_user_agent | $upstream_addr | $request_time | $upstream_response_time';
$remote_addr
: 客戶端的 IP 地址。這是直接連接到 Nginx 的客戶端的 IP 地址。$http_x_forwarded_for
: 客戶端的真實(shí) IP 地址。通常用于記錄經(jīng)過(guò)代理服務(wù)器或負(fù)載均衡器的客戶端 IP 地址,X-Forwarded-For
頭部中包含了這些 IP。$remote_user
: 客戶端的用戶名,如果請(qǐng)求需要 HTTP 基本認(rèn)證時(shí)會(huì)記錄用戶名。如果沒(méi)有認(rèn)證信息則為-
。$time_local
: 本地時(shí)間和日期,格式為day/month/year:hour:minute:second
。$request
: 請(qǐng)求的完整 URI,包括參數(shù)。格式為METHOD URI PROTOCOL
,例如GET /index.html HTTP/1.1
。$http_host
: 請(qǐng)求中的Host
頭部?jī)?nèi)容,即訪問(wèn)的主機(jī)名。$status
: 響應(yīng)的 HTTP 狀態(tài)碼,例如200
表示成功,404
表示未找到,500
表示服務(wù)器內(nèi)部錯(cuò)誤等。$upstream_status
: 上游服務(wù)器返回的狀態(tài)碼。當(dāng) Nginx 作為反向代理時(shí),此變量記錄上游服務(wù)器的響應(yīng)狀態(tài)碼。$body_bytes_sent
: 傳送給客戶端的響應(yīng)主體內(nèi)容的字節(jié)數(shù),不包括響應(yīng)頭的大小。$http_referer
: 請(qǐng)求的引用頁(yè)面,即從哪個(gè)頁(yè)面鏈接過(guò)來(lái)的(Referer
頭部?jī)?nèi)容)。如果沒(méi)有引用頁(yè)面則為-
。$http_user_agent
: 客戶端使用的瀏覽器或其他客戶端的信息(User-Agent
頭部?jī)?nèi)容)。$upstream_addr
: 上游服務(wù)器的地址。當(dāng) Nginx 作為反向代理時(shí),此變量記錄上游服務(wù)器的 IP 地址和端口。$request_time
: 處理請(qǐng)求的總時(shí)間,從接收到客戶端請(qǐng)求到完整發(fā)送響應(yīng)的時(shí)間,單位為秒。$upstream_response_time
: 從上游服務(wù)器讀取響應(yīng)的時(shí)間,單位為秒。
server節(jié)點(diǎn) 配置
server { listen 80; server_name localhost; access_log logs/access.log main; #需要添加日志引用 proxy_set_header X-Real-IP $remote_addr; #添加透?jìng)髋渲? proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for location / { root html; } }
http://www.dbjr.com.cn/server/3262802e1.htm
使用 proxy_set_header 指令設(shè)置透?jìng)黝^部。確保代理服務(wù)器(如 Nginx)在轉(zhuǎn)發(fā)請(qǐng)求時(shí)保留原始客戶端的 IP 地址
驗(yàn)證
方式一
訪問(wèn)Nginx頁(yè)面
訪問(wèn)日志
192.168.0.6 | 168.138.171.206 | - | 19/May/2024:10:57:24 +0800 | GET / HTTP/1.1 | nginx.frps.fun | 200 | - | 615 | - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 | - | 0.000 | -
192.168.0.6
:
含義:直接連接到 Nginx 服務(wù)器的客戶端的 IP 地址。在這個(gè)例子中,這可能是一個(gè)內(nèi)網(wǎng)的 IP 地址。
168.138.171.206
:
含義:通過(guò) X-Forwarded-For
頭部獲取的客戶端的真實(shí) IP 地址。在經(jīng)過(guò)代理或負(fù)載均衡器時(shí),這個(gè)頭部會(huì)記錄原始客戶端的 IP 地址。
-
:
含義:客戶端的用戶名。在請(qǐng)求需要 HTTP 基本認(rèn)證時(shí)記錄用戶名。這里沒(méi)有進(jìn)行認(rèn)證,所以顯示為 -
。
19/May/2024:10:57:24 +0800
:
含義:請(qǐng)求到達(dá)服務(wù)器的本地時(shí)間,格式為 day/month/year:hour:minute:second timezone
。這個(gè)例子中表示 2024 年 5 月 19 日上午 10:57:24,時(shí)區(qū)為 +0800。
GET / HTTP/1.1
:
含義:客戶端的請(qǐng)求行,包含請(qǐng)求的方法(GET)、請(qǐng)求的資源路徑(/),以及使用的 HTTP 協(xié)議版本(HTTP/1.1)。
nginx.frps.fun
:
含義:請(qǐng)求中的 Host
頭部,表示客戶端請(qǐng)求訪問(wèn)的主機(jī)名。
200
:
含義:HTTP 響應(yīng)狀態(tài)碼,表示請(qǐng)求成功。200
代表成功。
-
:
含義:上游服務(wù)器的響應(yīng)狀態(tài)碼。在沒(méi)有上游服務(wù)器時(shí),這里顯示為 -
。
615
:
含義:傳送給客戶端的響應(yīng)主體內(nèi)容的字節(jié)數(shù),不包括響應(yīng)頭的大小。
-
:
含義:請(qǐng)求的引用頁(yè)面(Referer)。如果沒(méi)有引用頁(yè)面則顯示為 -
。
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
:
含義:客戶端使用的瀏覽器或其他客戶端的信息(User-Agent)。在這個(gè)例子中,表示客戶端使用的是 Chrome 瀏覽器,運(yùn)行在 macOS 上。
-
:
含義:上游服務(wù)器的地址。在沒(méi)有上游服務(wù)器時(shí),這里顯示為 -
。
0.000
:
含義:處理請(qǐng)求的總時(shí)間,從接收到客戶端請(qǐng)求到完整發(fā)送響應(yīng)的時(shí)間,單位為秒。
-
:
含義:從上游服務(wù)器讀取響應(yīng)的時(shí)間。在沒(méi)有上游服務(wù)器時(shí),這里顯示為 -
。
方式二
如果我們前面沒(méi)有apisix或者其它lb,也可以使用curl命令來(lái)模擬X-Forwarded-For日志
curl http://127.0.0.1/ -H 'X-Forwarded-For: 1.1.1.1' -v * About to connect() to 127.0.0.1 port 80 (#0) * Trying 127.0.0.1... * Connected to 127.0.0.1 (127.0.0.1) port 80 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.29.0 > Host: 127.0.0.1 > Accept: */* > X-Forwarded-For: 1.1.1.1 #-v參數(shù)可以看到這里參數(shù)已經(jīng)傳入 > < HTTP/1.1 200 OK < Server: nginx < Date: Sun, 19 May 2024 03:09:05 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 615 < Last-Modified: Mon, 09 Oct 2023 06:03:57 GMT < Connection: keep-alive < ETag: "652397cd-267" < Accept-Ranges: bytes < <!DOCTYPE html> #http:127.0.0.1 就是Nginx服務(wù)器
- http://127.0.0.1/: 請(qǐng)求的 URL,127.0.0.1 表示本地服務(wù)器。
- -H ‘X-Forwarded-For: 1.1.1.1’: 添加 HTTP 請(qǐng)求頭 X-Forwarded-For,其值為 1.1.1.1。這個(gè)頭部通常用于表示客戶端的真實(shí) IP 地址。
- -v: 顯示詳細(xì)的請(qǐng)求和響應(yīng)過(guò)程,包括頭部信息
日志
127.0.0.1 | 1.1.1.1 | - | 19/May/2024:10:57:24 +0800 | GET / HTTP/1.1 | 127.0.0.1 | 200 | - | 615 | - | curl/7.29.0 | - | 0.000 | -
從日志文件 logs/access.log 中,可以驗(yàn)證 X-Forwarded-For 頭部信息是否正確記錄, 此日志記錄顯示,X-Forwarded-For 頭部中傳遞的 1.1.1.1 已正確記錄。
到此這篇關(guān)于Nginx中透?jìng)骺蛻舳苏鎸?shí)IP的技巧的文章就介紹到這了,更多相關(guān)Nginx 透?jìng)鱅P內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入理解nginx如何實(shí)現(xiàn)高性能和可擴(kuò)展性
這篇文章主要介紹了深入理解nginx如何實(shí)現(xiàn)高性能和可擴(kuò)展性,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05nginx proxy_buffer_size解決后端服務(wù)傳輸數(shù)據(jù)過(guò)多,header過(guò)大問(wèn)題
這篇文章主要介紹了nginx proxy_buffer_size解決后端服務(wù)傳輸數(shù)據(jù)過(guò)多,header過(guò)大問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12由于Nginx配置文件問(wèn)題導(dǎo)致打不開(kāi)網(wǎng)站unknown directive的解決
這篇文章主要介紹了由于Nginx配置文件問(wèn)題導(dǎo)致打不開(kāi)網(wǎng)站unknown directive,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06nginx禁止dedecms目錄php執(zhí)行權(quán)限
nginx禁止dedecms目錄php執(zhí)行權(quán)限,找到配置fastcgi.conf文件,一般在/usr/local/nginx/conf/下面,修改如下2014-01-01使用nginx搭建點(diǎn)播和直播流媒體服務(wù)器的方法步驟
本篇文章主要介紹了使用nginx搭建點(diǎn)播和直播流媒體服務(wù)器的方法步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03Nginx 代理轉(zhuǎn)發(fā)阿里云OSS上傳的實(shí)現(xiàn)代碼
這篇文章主要介紹了Nginx 代理轉(zhuǎn)發(fā)阿里云OSS上傳的實(shí)現(xiàn)代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09Nginx Rewrite規(guī)則與使用介紹和技巧實(shí)例
這篇文章主要介紹了Nginx Rewrite規(guī)則與使用介紹和技巧實(shí)例,本文講解了正則表達(dá)式匹配、文件及目錄匹配、flag標(biāo)記、Nginx Rewrite相關(guān)指令等內(nèi)容,需要的朋友可以參考下2015-01-01