客戶端IP指的是訪問者(用戶設備)的IP地址。在Web應用開發中,通常需要獲取客戶端真實的IP地址。例如,投票系統為了防止刷票,需要通過獲取客戶端真實IP地址,限制每個客戶端IP地址只能投票一次。
當您的網站已接入Web應用防火墻(Web Application Firewall,簡稱WAF)進行安全防護后,WAF作為一個反向代理存在于客戶端和服務器之間,服務器的真實IP被隱藏起來,Web訪問者只能看到WAF的IP地址。此時,您可直接通過WAF獲取客戶端的真實IP,也可以通過配置網站服務器獲取客戶端的真實IP。
本章節介紹了通過WAF直接獲取真實IP的方法,以及不同類型的Web應用服務器(包括Tomcat、Apache、Nginx、IIS 6和IIS 7)如何進行相關設置,以獲取客戶端的真實IP。
背景信息
通常情況下,網站訪問并不是簡單地從用戶的瀏覽器直達服務器,中間可能部署有CDN、WAF、高防等代理服務器(架構為)。以WAF為例,部署示意圖如圖1所示。
圖1 部署WAF原理圖
說明:
- 當網站沒有接入到WAF前,DNS直接解析到源站的IP,用戶直接訪問服務器。
- 當網站接入WAF后,需要把DNS解析到WAF的CNAME,這樣流量才會先經過WAF,WAF再將流量轉到源站,實現網站流量檢測和攻擊攔截。
在這種情況下,訪問請求到達源站服務器之前可能經過了多層安全代理轉發或加速代理轉發,服務器如何獲取發起請求的真實客戶端IP呢?
一個透明的代理服務器在把用戶的HTTP請求轉到下一環節的服務器時,會在HTTP的頭部中加入一條“X-Forwarded-For”記錄,用來記錄用戶的真實IP,其形式為“X-Forwarded-For:客戶端的真實IP,代理服務器1-IP, 代理服務器2-IP,代理服務器3-IP,……”。
因此,您可以通過獲取“X-Forwarded-For”對應的第一個IP來得到客戶端的真實IP。
通過WAF直接獲取客戶端真實IP
網站接入WAF后,WAF作為一個反向代理部署于客戶端和服務器之間,實現網站安全防護。根據業務需求,您可以通過以下兩種推薦方式獲取客戶端真實IP:
- WAF服務還支持使用X-Real-IP變量,獲取客戶的來源IP(使用過程中考慮了后面經過的多層反向代理對該變量的修改)。
各種語言通過調用SDK接口獲取X-Real-IP字段的方式:
- ASP:
Request.ServerVariables("HTTP_X_REAL_IP")
- ASP.NET(C#):
Request.ServerVariables["HTTP_X_REAL_IP"]
- PHP:
$_SERVER["HTTP_X_REAL_IP"]
- JSP:
request.getHeader("HTTP_X_REAL_IP")
Tomcat如何在訪問日志中獲取客戶端真實IP
如果您的源站部署了Tomcat服務器,可通過啟用Tomcat的X-Forwarded-For功能,獲取客戶端的真實IP地址。
- 打開“server.xml”文件(“tomcat/conf/server.xml”),AccessLogValue日志記錄功能部分內容如下:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.values.AccessLogValue" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
- 在pattern中增加“%{X-Forwarded-For}i”,修改后的server.xml為:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValue" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%{X-Forwarded-For}i %h %l %u %t "%r" %s %b" />
</Host>
- 查看“localhost_access_log”日志文件,可獲取X-Forwarded-For對應的訪問者真實IP。
Apache如何在訪問日志中獲取客戶端真實IP
如果源站部署的Apache服務器為2.4及以上版本,您可以使用Apache安裝包中自帶“remoteip_module”模塊文件“mod_remoteip.so”,獲取客戶端IP地址。
- CentOS 7.6
- 編輯“httpd.conf”配置文件,在文件中添加以下內容:
LoadModule remoteip_module modules/mod_remoteip.so ##加載mod_remoteip.so模塊
RemoteIPHeader X-Forwarded-For ##設置RemoteIPHeader頭部
RemoteIPInternalProxy WAF的回源IP段 ##設置WAF回源IP段
有關獲取WAF回源IP段的詳細介紹,請參見如何放行WAF回源IP段。
說明:
- “mod_remoteip.so”模塊已默認加載在以下文件:“/etc/httpd/conf.modules.d/00-base.conf:46”
- 多個回源IP段請使用空格分隔。
- 修改配置文件日志格式,即將日志格式文件中的“%h”修改為“%a”。
LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%a %l %u %t \"%r\" %>s %b" common
- 重啟Apache服務,使配置生效。
- Ubuntu 20.04.2
- 編輯“apache2.conf”配置文件,在文件中添加以下內容:
ln -s ../mods-available/remoteip.load /etc/apache2/mods-enabled/remoteip.load ##加載mod_remoteip.so模塊
RemoteIPHeader X-Forwarded-For ##設置RemoteIPHeader頭部
RemoteIPInternalProxy WAF的回源IP段 ##設置WAF回源IP段
有關獲取WAF回源IP段的詳細介紹,請參見如何放行WAF回源IP段。
說明:
- 修改配置文件日志格式,即將日志格式文件中的“%h”修改為“%a”。
LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%a %l %u %t \"%r\" %>s %b" common
- 重啟Apache服務,使配置生效。
如果源站部署的Apache服務器為2.2及以下版本,您可通過運行命令安裝Apache的第三方模塊mod_rpaf,并修改“http.conf”文件獲取客戶IP地址。
- 執行以下命令安裝Apache的一個第三方模塊mod_rpaf。
wget https://github.com/gnif/mod_rpaf/archive/v0.6.0.tar.gz
tar xvfz mod_rpaf-0.6.tar.gz
cd mod_rpaf-0.6
/usr/local/apache/bin/apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c
- 打開“httpd.conf”配置文件,并將文件內容修改為如下內容:
LoadModule rpaf_module modules/mod_rpaf-2.0.so ##加載mod_rpaf模塊
<IfModule mod_rpaf.c>
RPAFenable On
RPAFsethostname On
RPAFproxy_ips 127.0.0.1 <反向代理IPs>
RPAFheader X-Forwarded-For
</IfModule>
- 定義日志格式。
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" common
- 啟用自定義格式日志。
CustomLog "/[apache目錄]/logs/$access.log" common
- 重啟Apache,使配置生效。
/[apached目錄]/httpd/bin/apachectl restart
- 查看“access.log”日志文件,可獲取X-Forwarded-For對應的客戶端真實IP。
Nginx如何在訪問日志中獲取客戶端真實IP
如果您的源站部署了Nginx反向代理,可通過在Nginx反向代理配置Location信息,后端Web服務器即可通過類似函數獲取客戶的真實IP地址。
- 根據源站Nginx反向代理的配置,在Nginx反向代理的相應location位置配置如下內容,獲取客戶IP的信息。
Location ^ /<uri> {
proxy_pass ....;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
|
- 后端Web服務器通過定義Nginx日志參數$http_x_forwarded_for來獲取客戶的真實IP。
示例:log_format main ' "<$http_Cdn_Src_IP>" "{$http_x_real_ip}" "[$http_x_forwarded_for]" "$remote_addr" ' '$http_user_agent - $remote_user [$time_local] "$request" ' ' $status $body_bytes_sent "$http_referer" ';
IIS 6如何在訪問日志中獲取客戶端真實IP
如果您的源站部署了IIS 6服務器,您可以通過安裝“F5XForwardedFor.dll”插件,從IIS 6服務器記錄的訪問日志中獲取客戶端真實的IP地址。
- 下載F5XForwardedFor模塊。
- 根據您服務器的操作系統版本將“x86\Release”或者“x64\Release”目錄中的“F5XForwardedFor.dll”文件拷貝至指定目錄(例如,“C:\ISAPIFilters”),同時確保IIS進程對該目錄有讀取權限。
- 打開IIS管理器,找到當前開啟的網站,在該網站上右鍵選擇“屬性”,打開“屬性”頁面。
- 在“屬性”頁面,切換至“ISAPI篩選器”,單擊“添加”,在彈出的窗口中,配置如下信息:
- “篩選器名稱”:“F5XForwardedFor”;
- “可執行文件”:“F5XForwardedFor.dll”的完整路徑,例如:“C:\ISAPIFilters\F5XForwardedFor.dll”。
- 單擊“確定”,重啟IIS 6服務器。
- 查看IIS 6服務器記錄的訪問日志(默認的日志路徑為:“C:\WINDOWS\system32\LogFiles\ ”,IIS日志的文件名稱以“.log”為后綴),可獲取X-Forwarded-For對應的客戶端真實IP。
IIS 7如何在訪問日志中獲取客戶端真實IP
如果您的源站部署了IIS 7服務器,您可以通過安裝“F5XForwardedFor”模塊,從IIS 7服務器記錄的訪問日志中獲取客戶端真實的IP地址。
- 下載F5XForwardedFor模塊。
- 根據服務器的操作系統版本將“x86\Release”或者“x64\Release”目錄中的“F5XFFHttpModule.dll”和“F5XFFHttpModule.ini”文件拷貝到指定目錄(例如,“C:\x_forwarded_for\x86”或“C:\x_forwarded_for\x64”),并確保IIS進程對該目錄有讀取權限。
- 在IIS服務器的選擇項中,雙擊“模塊”,進入“模塊”界面。
- 單擊“配置本機模塊”,在彈出的對話框中,單擊“注冊”。
圖2 注冊模塊
- 在彈出的對話框中,按操作系統注冊已下載的DLL文件后,單擊“確定”。
- x86操作系統:注冊模塊“x_forwarded_for_x86”
- 名稱:x_forwarded_for_x86
- 路徑:“C:\x_forwarded_for\x86\F5XFFHttpModule.dll”
圖3 x86操作系統注冊模塊
- x64操作系統:注冊模塊“x_forwarded_for_x64”
- 名稱:x_forwarded_for_x64
- 路徑:“C:\x_forwarded_for\x64\F5XFFHttpModule.dll”
圖4 x64操作系統注冊模塊
- 注冊完成后,勾選新注冊的模塊(“x_forwarded_for_x86”或“x_forwarded_for_x64”)并單擊“確定”。
- 在“ISAPI和CGI限制”中,按操作系統添加已注冊的DLL文件,并將其“限制”改為“允許”。
- x86操作系統:
- ISAPI或CGI路徑:“C:\x_forwarded_for\x86\F5XFFHttpModule.dll”
- 描述:x86
- x64操作系統:
- ISAPI或CGI路徑:“C:\x_forwarded_for\x64\F5XFFHttpModule.dll”
- 描述:x64
- 重啟IIS 7服務器,等待配置生效。
- 查看IIS 7服務器記錄的訪問日志(默認的日志路徑為:“C:\WINDOWS\system32\LogFiles\ ”,IIS日志的文件名稱以“.log”為后綴),可獲取X-Forwarded-For對應的客戶端真實IP。
該文章在 2022/11/4 16:53:04 編輯過