網站接入Web Application Firewall(Web Application Firewall,簡稱WAF)後,訪問請求在到達來源站點伺服器之前,需要經過WAF的代理轉寄。這種情況下,來源站點伺服器可以通過解析回源請求中的X-Forwarded-For記錄,擷取用戶端的真實IP。本文介紹如何配置不同類型的Web應用伺服器(包括Nginx、IIS 6、IIS 7、Apache、Tomcat)以及容器K8s,以擷取用戶端的真實IP。
背景資訊
WAF在將用戶端的訪問請求轉寄到下一環節的伺服器時,會在HTTP的要求標頭中添加一條X-Forwarded-For記錄,用於記錄用戶端的IP,格式為X-Forwarded-For:用戶端IP
。如果用戶端和來源站點伺服器之間有多個Proxy 伺服器(例如WAF、DDoS高防、CDN等),則X-Forwarded-For記錄使用以下格式記錄用戶端IP和依次經過的Proxy 伺服器IP:X-Forwarded-For:用戶端IP, Proxy 伺服器1的IP, Proxy 伺服器2的IP, Proxy 伺服器3的IP, ……
。
因此,常見的Web應用伺服器(包括Nginx、IIS 6、IIS 7、Apache、Tomcat)以及容器K8s可以通過解析X-Forwarded-For記錄擷取用戶端真實IP。
Nginx配置方案
Nginx伺服器使用http_realip_module模組解析X-Forwarded-For記錄。您可以參考如下步驟,安裝http_realip_module模組,修改Nginx配置。
- 安裝http_realip_module模組。 在Nginx伺服器上執行
# nginx -V | grep http_realip_module
命令,查看是否已安裝http_realip_module模組。- 如果已在Nginx伺服器上安裝該模組,請跳過該步驟。
- 如果沒有在Nginx伺服器上安裝該模組,請重新編譯Nginx服務並參考如下方法安裝該模組。說明 一般情況下,通過一鍵安裝包安裝的Nginx伺服器預設不安裝http_realip_module模組。
wget http://nginx.org/download/nginx-1.12.2.tar.gz tar zxvf nginx-1.12.2.tar.gz cd nginx-1.12.2 ./configure --user=www --group=www --prefix=/alidata/server/nginx --with-http_stub_status_module --without-http-cache --with-http_ssl_module --with-http_realip_module make make install kill -USR2 `cat /alidata/server/nginx/logs/nginx.pid` kill -QUIT `cat /alidata/server/nginx/logs/ nginx.pid.oldbin`
- 修改Nginx伺服器設定檔。
- 開啟
default.conf
設定檔。 - 在
location / {}
中添加以下內容:set_real_ip_from <ip_range1>; set_real_ip_from <ip_range2>; ... set_real_ip_from <ip_rangex>; real_ip_header X-Forwarded-For;
其中,
<ip_range1>
、<ip_range2>
、<ip_rangex>
需要設定為Proxy 伺服器(即WAF)的回源IP段。擷取WAF回源IP段的具體操作,請參見允許存取WAF回源IP段。多個回源IP段必須分行添加。假設WAF的回源IP段包含10.0.0.1、10.0.0.2、10.0.0.3,則使用如下格式:set_real_ip_from 10.0.0.1; set_real_ip_from 10.0.0.2; set_real_ip_from 10.0.0.3; real_ip_header X-Forwarded-For;
- 開啟
- 修改log_format日誌記錄格式。
- 開啟
nginx.conf
設定檔,定位到http
配置部分的log_format
。 - 在
log_format
中添加x-forwarded-for
欄位,替換預設的remote-address
欄位。修改後的log_format內容如下:log_format main '$http_x_forwarded_for - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" ';
- 開啟
- 執行
nginx -s reload
命令,重啟Nginx伺服器,使配置生效。
IIS 6配置方案
IIS 6伺服器使用F5XForwardedFor模組解析X-Forwarded-For記錄。您可以參考如下步驟,安裝F5XForwardedFor模組。
- 將
x86\Release
或x64\Release
目錄下的F5XForwardedFor.dll
檔案拷貝到某個自訂目錄(例如C:\ISAPIFilters\x86
、C:\ISAPIFilters\x64
)。說明- 請確保IIS進程擁有自訂目錄的讀寫權限。
- 如果該目錄下,沒有
F5XForwardedFor.dll
檔案,請手動下載該檔案,並將該檔案放到自訂目錄。下載路徑,請參見F5XForwardedFor.dll。
- 開啟IIS管理器,定位到目標網站,按右鍵屬性。
- 在ISAPI篩選器頁簽,單擊添加。完成如下配置後,單擊確定。以32位作業系統為例:
- 篩選器名稱:
x_forwarded_for_x86
。 - 可執行檔:
F5XForwardedFor.dll
檔案所在的完整路徑(例如C:\ISAPIFilters\x86\F5XForwardedFor.dll
)。
- 篩選器名稱:
- 重啟IIS 6伺服器,使配置生效。
IIS 7配置方案
IIS 7伺服器使用F5XForwardedFor模組解析X-Forwarded-For記錄。您可以參考如下步驟,安裝F5XForwardedFor模組。
- 將
x86\Release
或x64\Release
目錄下的F5XFFHttpModule.dll
和F5XFFHttpModule.ini
檔案拷貝到某個自訂目錄(例如C:\x_forwarded_for\x86
、C:\x_forwarded_for\x64
)。說明- 請確保IIS進程擁有自訂目錄的讀寫權限。
- 如果該目錄下,沒有
F5XForwardedFor.dll
和F5XFFHttpModule.ini
檔案,請手動下載檔案,並將檔案放到自訂目錄。下載路徑,請參見F5XForwardedFor模組。
- 開啟IIS管理器,在IIS地區,雙擊模組。
- 在模組頁面右側操作地區,單擊配置本機模組。
- 在配置本機模組對話方塊,單擊註冊。填寫註冊資訊後,單擊確定。 以32位作業系統為例:
- 名稱:
x_forwarded_for_x86
。 - 路徑:
F5XFFHttpModule.dll
檔案所在的完整路徑(例如C:\x_forwarded_for\x86\F5XFFHttpModule.dll
)。
- 名稱:
- 在配置本機模組對話方塊,選中新註冊的模組,單擊確定。
- 在ISAPI 和CGI限制頁面,添加登入的DLL,並將限制設定為允許。
- 重啟IIS 7伺服器,使配置生效。
Apache配置方案
Windows作業系統
Apache 2.4及以上版本的安裝包中內建remoteip_module模組檔案(mod_remoteip.so
),Apache伺服器使用該模組擷取用戶端IP地址。
- 進入Apache伺服器的extra設定檔夾(
conf/extra/
),建立httpd-remoteip.conf
設定檔。說明 通過引入remoteip.conf
設定檔的方式載入相關配置,減少直接修改httpd.conf
設定檔的次數,避免因操作失誤導致業務異常。 - 編輯
httpd-remoteip.conf
設定檔,在檔案中添加以下內容:# 載入mod_remoteip.so模組 LoadModule remoteip_module modules/mod_remoteip.so # 設定RemoteIPHeader頭部 RemoteIPHeader X-Forwarded-For # 設定回源IP段 RemoteIPInternalProxy <ip_range1> <ip_range2> …… <ip_rangex>
其中,
<ip_range1>
、<ip_range2>
、<ip_rangex>
需要設定為Proxy 伺服器(即WAF)的回源IP段。擷取WAF回源IP段的具體操作,請參見允許存取WAF回源IP段。多個回源IP段之前使用空格分隔。假設Proxy 伺服器的回源IP段包含10.0.0.1、10.0.0.2、10.0.0.3,則使用以下格式:RemoteIPInternalProxy 10.0.0.1 10.0.0.2 10.0.0.3
- 編輯conf/httpd.conf設定檔,在檔案中添加以下內容:
Include conf/extra/httpd-remoteip.conf
以上命令表示在conf/httpd.conf中插入
httpd-remoteip.conf
設定檔。 - 在
httpd.conf
設定檔中修改日誌格式。LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%a %l %u %t \"%r\" %>s %b" common
- 重啟Apache服務,使配置生效。
Linux作業系統
您可以參考上述Windows作業系統伺服器的配置方式,添加Apache 2.4及以上版本內建的remoteip_module模組(mod_remoteip.so
)並配置日誌格式,擷取用戶端IP地址。
如果Linux伺服器使用的Apache版本低於2.4,請參照以下步驟,通過設定Apache的第三方模組(mod_rpaf),擷取用戶端IP地址。
- 安裝mod_rpaf模組。
wget https://github.com/gnif/mod_rpaf/archive/v0.6.0.tar.gz tar zxvf mod_rpaf-0.6.tar.gz cd mod_rpaf-0.6 /alidata/server/httpd/bin/apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c
- 編輯Apache設定檔
/alidata/server/httpd/conf/httpd.conf
,在檔案最後添加以下內容:LoadModule rpaf_module modules/mod_rpaf-2.0.so RPAFenable On RPAFsethostname On RPAFproxy_ips <rpaf ip地址> RPAFheader X-Forwarded-For
其中,
<rpaf ip地址>
不是Proxy 伺服器的公網IP地址,具體IP請通過Apache日誌查詢。通常包含兩個IP地址,樣本如下:LoadModule rpaf_module modules/mod_rpaf-2.0.so RPAFenable On RPAFsethostname On RPAFproxy_ips 10.XX.XX.65 10.XX.XX.131 RPAFheader X-Forwarded-For
- 重啟Apache服務,使配置生效。
/alidata/server/httpd/bin/apachectl restart
更多Apache相關模組的資訊,請參見Apache協助文檔。
Tomcat配置方案
Tomcat伺服器通過啟用X-Forwarded-For功能,擷取用戶端IP地址。
- 開啟
tomcat/conf/server.xml
設定檔。 - 將AccessLogValve日誌記錄功能部分修改為以下內容:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%{X-FORWARDED-FOR}i %l %u %t %r %s %b %D %q %{User-Agent}i %T" resolveHosts="false"/>
容器K8s配置方案
如果您的服務部署在K8s上,K8s會將真實的用戶端IP記錄在X-Original-Forwarded-For欄位中,並將WAF回源地址記錄在X-Forwarded-For欄位中。您需要修改容器的設定檔,使Ingress將真實的IP添加到X-Forwarded-For欄位中,以便您正常擷取真實的用戶端IP地址。
您可以參考以下步驟,對容器設定檔進行修改。
- 執行以下命令修改設定檔
kube-system/nginx-configuration
。kubectl -n kube-system edit cm nginx-configuration
- 在設定檔中添加以下內容:
compute-full-forwarded-for: "true" forwarded-for-header: "X-Forwarded-For" use-forwarded-headers: "true"
- 儲存設定檔。儲存後配置即刻生效,Ingress會將真實的用戶端IP添加到X-Forwarded-For欄位中。
- 將業務程式擷取用戶端真實IP的欄位修改為X-Original-Forwarded-For。