CNAME 接入 Web Application Firewall(Web Application Firewall,簡稱WAF) 時,來源站點收到的請求源 IP 為最後一跳Proxy 位址而非用戶端真實 IP。WAF 通過在 HTTP 要求頭中插入 X-Forwarded-For 欄位傳遞真實 IP。本文介紹如何在各後端 Web 服務器配置,從該欄位提取用戶端真實 IP,以確保日誌記錄和安全審計正常工作。
工作原理
CNAME 接入 WAF 後,用戶端請求先經過 WAF 及可能存在的其他中間代理(如 CDN、DDoS 高防等),再轉寄至來源站點。此時來源站點接收到的 TCP 串連源 IP 為最後一跳代理的 IP,而非用戶端真實 IP。
WAF 轉寄 HTTP 要求時會自動添加 X-Forwarded-For 頭部欄位。該欄位初始值為用戶端 IP;每經過一個代理節點,該節點的 IP 會被追加至末尾,格式如下:
X-Forwarded-For: 用戶端IP, 代理1IP, 代理2IP, …
因此,需要在後端 Web 服務器配置從 X-Forwarded-For 頭部提取最左側的 IP 位址(即原始用戶端 IP)。以下分別介紹各平台的配置方法。
步驟一:擷取 WAF 回源 IP 段
登入Web Application Firewall控制台,在頂部功能表列選擇 WAF 執行個體的資源群組和地區(中國內地、非中國內地),單擊,記錄所有 WAF 回源 IP 段,供後續配置使用。
步驟二:配置來源站點伺服器
配置前請通過 ECS 快照或設定檔備份等方式完成環境備份,避免配置丟失。
Nginx 配置方案
Nginx 使用 http_realip_module 模組解析 X-Forwarded-For。按以下步驟修改 Nginx 配置。
檢查是否已安裝 http_realip_module
登入伺服器並執行以下命令:
nginx -V 2>&1 | grep -o with-http_realip_module
-
若輸出
with-http_realip_module,說明模組已安裝,跳至配置 Nginx 信任 WAF 回源 IP 段。 -
若無輸出,說明當前 Nginx 未編譯該模組,請繼續執行添加 realip 模組。
通過 yum install nginx 或 apt install nginx 安裝的版本通常包含該模組。自訂編譯版本或極簡鏡像可能缺失。
添加 realip 模組(僅缺失時適用)
方式一:通過系統包管理器重新安裝
# Alibaba Cloud Linux / CentOS / RHEL
sudo yum reinstall nginx -y
# Ubuntu / Debian
sudo apt install --reinstall nginx-core nginx-full
方式二:源碼編譯
-
安裝依賴。
# Alibaba Cloud Linux / CentOS / RHEL sudo yum install -y gcc pcre-devel zlib-devel openssl-devel # Ubuntu / Debian sudo apt update sudo apt install -y build-essential libpcre3-dev zlib1g-dev libssl-dev -
查看已安裝的 Nginx 版本。
# 查看版本(用於下載對應源碼) nginx -v # 查看完整編譯參數 nginx -V 2>&1 | grep 'configure arguments' | sed 's/configure arguments: //'記錄輸出內容,例如
--prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module。 -
下載對應版本的 Nginx 源碼,請替換為實際版本號碼。
cd /tmp wget http://nginx.org/download/nginx-1.26.0.tar.gz tar zxvf nginx-1.26.0.tar.gz cd nginx-1.26.0 -
配置編譯選項,將步驟 2 中的原始參數複製,並在末尾追加
--with-http_realip_module。./configure \ --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_realip_module -
編譯並升級服務。
make # make後會在 objs/ 目錄下產生新的 nginx 二進位檔案。 # 重新命名舊二進位(保留備份) sudo mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old # 替換為新編譯的版本 sudo cp objs/nginx /usr/local/nginx/sbin/nginx # 擷取當前主進程 PID OLD_PID=$(pgrep -f 'nginx: master' | head -1) # 啟動新主進程 sudo kill -USR2 $OLD_PID # 等待新進程啟動 sleep 2 # 關閉舊進程 sudo kill -QUIT $OLD_PID
配置 Nginx 信任 WAF 回源 IP 段
-
編輯
nginx.conf主設定檔(預設位於/etc/nginx/nginx.conf),在http {}塊中添加以下內容。http { # 信任來自 WAF 回源 IP 的 X-Forwarded-For 頭 # 請替換為實際從控制台擷取的 WAF 回源 IP 段,每個網段單獨一行 # 必須包含全部 WAF 回源網段,若有遺漏,則可能導致日誌仍顯示 WAF 的回源IP,而非用戶端真實 IP。 set_real_ip_from <ip_range1>; set_real_ip_from <ip_range2>; ... set_real_ip_from <ip_rangex>; # 指定從X-Forwarded-For要求標頭提取真實 IP real_ip_header X-Forwarded-For; } -
重載 Nginx 配置:
nginx -t && nginx -s reload
驗證
-
訪問網站,將
http://your-domain.com/替換為已接入 WAF 的網域名稱。curl http://your-domain.com/ -
查看 Nginx 訪問日誌,應顯示用戶端真實 IP 位址。
tail -f /var/log/nginx/access.log
IIS 7 配置方案(IIS 7 及以上版本適用)
WAF 作為反向 Proxy時,IIS 預設日誌中的 c-ip 欄位記錄的是 WAF 回源 IP 而非真實使用者 IP。通過 IIS 的 W3C 自訂日誌欄位功能,可將 X-Forwarded-For 要求標頭寫入日誌,便於審計和排查。
-
開啟 IIS 管理器,在左側串連樹中展開伺服器節點,選擇目標網站(例如
Default Web Site)。 -
雙擊右側功能視圖中的日誌表徵圖。
-
在記錄檔地區,確認日誌格式為 W3C(預設值)。若為其他格式,請切換為 W3C。
-
在記錄檔地區,單擊選擇欄位… 。
-
在快顯視窗底部,單擊添加欄位… 。
-
在添加自訂欄位對話方塊中填寫以下資訊,單擊確定。
配置項
配置說明
欄位名稱
填寫
X-FORWARDED-FOR源類型
選擇
請求標題源
填寫
X-Forwarded-For -
單擊確定儲存自訂欄位。
-
再次單擊確定關閉記錄欄位視窗,然後單擊右側應用儲存更改。
-
重啟 IIS 伺服器使配置生效。
-
訪問網站進行驗證,並查看訪問日誌(預設路徑
C:\inetpub\logs\LogFiles\W3SVC1\),應顯示真實用戶端 IP 位址。
Apache 配置方案
Apache 2.4 及以上版本內建 remoteip_module 模組(mod_remoteip.so),使用該模組可擷取用戶端真實 IP。
Alibaba Cloud Linux / CentOS / RHEL
-
編輯 Apache 主設定檔。
sudo vim /etc/httpd/conf/httpd.conf -
在檔案末尾添加以下內容。
# 啟用 mod_remoteip LoadModule remoteip_module modules/mod_remoteip.so # 指定 WAF 傳遞真實 IP 的要求標頭(WAF 使用 X-Forwarded-For) RemoteIPHeader X-Forwarded-For # 設定WAF回源IP段 請務必替換為阿里雲 WAF 的回源 IP 段 RemoteIPTrustedProxy 100.xx.xx.0/10 RemoteIPTrustedProxy 11.xx.xx.0/13 RemoteIPTrustedProxy 112.xx.xx.0/16 -
定位至設定檔的日誌格式部分,將
%h改為%a。%a表示串連的遠程 IP(經mod_remoteip修正後的真實用戶端 IP),%h為原始串連 IP(即 WAF 節點 IP)。修改後的樣本如下所示。<IfModule log_config_module> # # The following directives define some format nicknames for use with # a CustomLog directive (see below). # LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%a %l %u %t \"%r\" %>s %b" common <IfModule logio_module> # You need to enable mod_logio.c to use %I and %O LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio </IfModule> # # The location and format of the access logfile (Common Logfile Format). # If you do not define any access logfiles within a <VirtualHost> # container, they will be logged here. Contrariwise, if you *do* # define per-<VirtualHost> access logfiles, transactions will be # logged therein and *not* in this file. # #CustomLog "logs/access_log" common # # If you prefer a logfile with access, agent, and referer information # (Combined Logfile Format) you can use the following directive. # CustomLog "logs/access_log" combined </IfModule> -
重啟 Apache 服務使配置生效。
sudo systemctl restart httpd -
訪問網站進行驗證,並查看訪問日誌,應顯示真實用戶端 IP 位址。
tail -f /var/log/httpd/access_log
Ubuntu / Debian
-
啟用
remoteip模組。sudo a2enmod remoteip -
編輯 Apache 主設定檔。
sudo vim /etc/apache2/apache2.conf -
在檔案末尾添加以下內容。
# 指定 WAF 傳遞真實 IP 的要求標頭(WAF 使用 X-Forwarded-For) RemoteIPHeader X-Forwarded-For # 設定WAF回源IP段 請務必替換為阿里雲 WAF 的回源 IP 段 RemoteIPTrustedProxy 100.xx.xx.0/10 RemoteIPTrustedProxy 11.xx.xx.0/13 RemoteIPTrustedProxy 112.xx.xx.0/16 -
定位至設定檔的日誌格式部分,將
%h改為%a。%a表示串連的遠程 IP(經mod_remoteip修正後的真實用戶端 IP),%h為原始串連 IP(即 WAF 節點 IP)。修改後的樣本如下所示。# LogFormat "%v:%p %a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%a %l %u %t \"%r\" %>s %O" common LogFormat "%{Referer}i -> %U" referer LogFormat "%{User-agent}i" agent -
重啟 Apache 服務使配置生效。
sudo systemctl restart apache2 -
訪問網站進行驗證,並查看訪問日誌,應顯示真實用戶端 IP 位址。
tail -f /var/log/apache2/access.log
Tomcat 配置方案
Tomcat 通過啟用 X-Forwarded-For 功能擷取用戶端真實 IP。
-
前往 Tomcat 安裝目錄,開啟
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"/> -
重啟 Tomcat。
sudo systemctl restart tomcat -
訪問網站進行驗證,並查看訪問日誌,應顯示真實用戶端 IP 位址。
# 請將以下命令替換為實際的Tomcat安裝目錄路徑,並替換為實際的記錄檔 tail -f /opt/tomcat/logs/localhost_access_log.2026-01-01.txt
Kubernetes 叢集配置方案
使用 Nginx Ingress Controller 的 Kubernetes 叢集接入 WAF 時,用戶端真實 IP 會被 WAF 添加至 X-Forwarded-For 要求標頭。預設情況下 Nginx Ingress Controller 不信任該欄位,業務容器無法擷取真實用戶端 IP。
按以下步驟配置 Nginx Ingress Controller。
-
編輯 Ingress Controller 的 ConfigMap:
kubectl -n kube-system edit cm nginx-configuration -
在
data欄位中添加以下配置項:compute-full-forwarded-for: "true" forwarded-for-header: "X-Forwarded-For" use-forwarded-headers: "true" -
儲存並退出。配置將自動生效,無需重啟 Pod。
配置完成後,Ingress Controller 會將
X-Forwarded-For中的第一個 IP 識別為用戶端真實 IP,並在轉寄請求時保留該值。
進階最佳化:通過自訂 Header 透傳真實 IP
複雜網路架構中,依賴標準 X-Forwarded-For(XFF)頭存在被偽造、多層代理 IP 混淆等風險。可通過自訂 HTTP Header 透傳真實用戶端 IP,提升安全性和可控性。
以下樣本示範通過自訂 Header 擷取真實用戶端 IP。
-
CDN 配置
CDN 預設在回源請求中攜帶
Ali-Cdn-Real-IpHTTP 要求頭,表示用戶端與 CDN 節點串連時的真實 IP。通過增加自訂出站要求標頭,可將該 IP 傳遞至 WAF。CDN 控制台配置樣本如下。配置項
樣本
请求头操作
增加
自定义请求头参数
自訂回源要求標頭
自定义请求头名称
填寫自訂名稱,例如
TrueIP请求头值
$http_Ali_Cdn_Real_Ip是否允许重复
不允許
規則條件
不使用
-
WAF 配置
在 WAF 控制台完成以下兩項配置:
-
WAF前是否有七層代理(高防/CDN等):使 WAF 正確識別真實用戶端 IP。
-
啟用流量標記:使來源站點伺服器擷取真實用戶端 IP。
具體配置方法,請參見擷取真實用戶端資訊。
配置項
樣本
WAF前是否有七層代理(高防/CDN等)
選擇是,繼續選擇 【推薦】取指定Header欄位中的第一個IP作為客戶端源IP,避免XFF偽造,填寫上一步 CDN 配置中的 自定义请求头名称,例如
TrueIP。啟用流量標記
選擇 客戶端真實源IP,並填寫上一步 CDN 配置中的 自定义请求头名称,例如
TrueIP。 -
-
來源站點伺服器配置
以 Nginx 為例,編輯
nginx.conf主設定檔,在http {}塊中添加以下內容。詳情請參見Nginx 配置方案。http { # 信任來自 WAF 回源 IP 的要求標頭 # 請替換為實際從控制台擷取的 WAF 回源 IP 段,每個網段單獨一行 # 必須包含全部 WAF 回源網段,若有遺漏,則可能導致日誌仍顯示 WAF 的回源IP,而非用戶端真實 IP。 set_real_ip_from <ip_range1>; set_real_ip_from <ip_range2>; ... set_real_ip_from <ip_rangex>; # 指定從自訂的要求標頭提取真實 IP,本樣本使用TrueIP real_ip_header TrueIP; }建議在來源站點伺服器安全性群組配置僅允許存取 WAF 回源 IP 段,確保僅有 WAF 能與來源站點通訊,避免攻擊者繞過 WAF 直接存取來源站點公網 IP。
常見問題
來源站點伺服器的真實 IP 擷取配置與 WAF 控制台中的“WAF前是否有七層代理(高防/CDN等)”配置項有什麼區別?
-
來源站點伺服器的真實 IP 擷取配置(本文內容)
-
作用:CNAME 接入 WAF 後,使來源站點伺服器(如 Nginx)的訪問日誌(如
access.log)記錄真實用戶端 IP,而非 WAF 回源 IP。 -
是否必需:僅在需要在來源站點側查看或處理真實用戶端 IP 時才需配置。
-
-
WAF 控制台的WAF前是否有七層代理(高防/CDN等)配置項
-
適用情境:WAF 前方部署了其他七層代理(如 CDN、高防等)。
-
作用:告知 WAF 從指定 HTTP 要求頭(如
Ali-Cdn-Real-Ip或X-Forwarded-For)中提取真實用戶端 IP,確保安全報表和攻擊識別基於真實來源 IP。 -
是否必需:僅在 WAF 前存在七層代理時才需啟用;若無前置代理,保持預設值否。
-
X-Forwarded-For 偽造是什麼,如何避免?
X-Forwarded-For(XFF)偽造指攻擊者在 HTTP 要求中構造或篡改 X-Forwarded-For 要求標頭,注入虛假用戶端 IP,以繞過基於 IP 的存取控制、日誌審計或安全性原則。X-Forwarded-For 是非標準要求標頭,用戶端可任意設定,若後端服務未經驗證直接信任該欄位,將帶來安全風險。
樣本:XFF 偽造攻擊命令
攻擊者可使用 curl 命令偽造 X-Forwarded-For 頭,偽裝 IP 為 1.2.3.4:
curl -H "X-Forwarded-For: 1.2.3.4" https://example.com/
防範 XFF 偽造的方法是使用自訂可信要求標頭傳遞真實 IP:
配置 CDN 或 WAF 在回源時使用預定義的自訂 HTTP 要求頭傳遞真實用戶端 IP,來源站點側僅解析該自訂頭。該要求標頭由可信中介軟體(如 WAF)注入,用戶端無法直接控制,可有效避免偽造。