全部產品
Search
文件中心

Web Application Firewall:通過 HTTP 要求頭擷取用戶端真實 IP

更新時間:Jun 06, 2026

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 執行個體的資源群組和地區(中國內地非中國內地),單擊接入管理 > CNAME接入 > Web Application Firewall回源IP網段列表 ,記錄所有 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
說明

通過 yum install nginxapt install nginx 安裝的版本通常包含該模組。自訂編譯版本或極簡鏡像可能缺失。

添加 realip 模組(僅缺失時適用)

方式一:通過系統包管理器重新安裝

# Alibaba Cloud Linux / CentOS / RHEL
sudo yum reinstall nginx -y
# Ubuntu / Debian
sudo apt install --reinstall nginx-core nginx-full

方式二:源碼編譯

  1. 安裝依賴。

    # 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
  2. 查看已安裝的 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

  3. 下載對應版本的 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
  4. 配置編譯選項,將步驟 2 中的原始參數複製,並在末尾追加 --with-http_realip_module

    ./configure \
      --prefix=/usr/local/nginx \
      --with-http_ssl_module \
      --with-http_v2_module \
      --with-http_realip_module
  5. 編譯並升級服務。

    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 段

  1. 編輯 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;
    }
  2. 重載 Nginx 配置:

    nginx -t && nginx -s reload

驗證

  1. 訪問網站,將 http://your-domain.com/ 替換為已接入 WAF 的網域名稱。

    curl http://your-domain.com/
  2. 查看 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 要求標頭寫入日誌,便於審計和排查。

  1. 開啟 IIS 管理器,在左側串連樹中展開伺服器節點,選擇目標網站(例如 Default Web Site)。

  2. 雙擊右側功能視圖中的日誌表徵圖。

  3. 記錄檔地區,確認日誌格式W3C(預設值)。若為其他格式,請切換為 W3C。

  4. 記錄檔地區,單擊選擇欄位…

  5. 在快顯視窗底部,單擊添加欄位…

  6. 添加自訂欄位對話方塊中填寫以下資訊,單擊確定。

    配置項

    配置說明

    欄位名稱

    填寫 X-FORWARDED-FOR

    源類型

    選擇 請求標題

    填寫 X-Forwarded-For

  7. 單擊確定儲存自訂欄位。

  8. 再次單擊確定關閉記錄欄位視窗,然後單擊右側應用儲存更改。

  9. 重啟 IIS 伺服器使配置生效。

  10. 訪問網站進行驗證,並查看訪問日誌(預設路徑 C:\inetpub\logs\LogFiles\W3SVC1\),應顯示真實用戶端 IP 位址。

Apache 配置方案

Apache 2.4 及以上版本內建 remoteip_module 模組(mod_remoteip.so),使用該模組可擷取用戶端真實 IP。

Alibaba Cloud Linux / CentOS / RHEL

  1. 編輯 Apache 主設定檔。

    sudo vim /etc/httpd/conf/httpd.conf
  2. 在檔案末尾添加以下內容。

    # 啟用 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
  3. 定位至設定檔的日誌格式部分,將 %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>
  4. 重啟 Apache 服務使配置生效。

    sudo systemctl restart httpd
  5. 訪問網站進行驗證,並查看訪問日誌,應顯示真實用戶端 IP 位址。

    tail -f /var/log/httpd/access_log

Ubuntu / Debian

  1. 啟用 remoteip 模組。

    sudo a2enmod remoteip
  2. 編輯 Apache 主設定檔。

    sudo vim /etc/apache2/apache2.conf
  3. 在檔案末尾添加以下內容。

    # 指定 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
  4. 定位至設定檔的日誌格式部分,將 %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
  5. 重啟 Apache 服務使配置生效。

    sudo systemctl restart apache2
  6. 訪問網站進行驗證,並查看訪問日誌,應顯示真實用戶端 IP 位址。

    tail -f /var/log/apache2/access.log

Tomcat 配置方案

Tomcat 通過啟用 X-Forwarded-For 功能擷取用戶端真實 IP。

  1. 前往 Tomcat 安裝目錄,開啟 tomcat/conf/server.xml 設定檔。

  2. 將 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"/>
  3. 重啟 Tomcat。

    sudo systemctl restart tomcat
  4. 訪問網站進行驗證,並查看訪問日誌,應顯示真實用戶端 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。

  1. 編輯 Ingress Controller 的 ConfigMap:

    kubectl -n kube-system edit cm nginx-configuration
  2. data 欄位中添加以下配置項:

    compute-full-forwarded-for: "true"
    forwarded-for-header: "X-Forwarded-For"
    use-forwarded-headers: "true"
  3. 儲存並退出。配置將自動生效,無需重啟 Pod。

    配置完成後,Ingress Controller 會將 X-Forwarded-For 中的第一個 IP 識別為用戶端真實 IP,並在轉寄請求時保留該值。

進階最佳化:通過自訂 Header 透傳真實 IP

複雜網路架構中,依賴標準 X-Forwarded-For(XFF)頭存在被偽造、多層代理 IP 混淆等風險。可通過自訂 HTTP Header 透傳真實用戶端 IP,提升安全性和可控性。

以下樣本示範通過自訂 Header 擷取真實用戶端 IP。

  1. CDN 配置

    CDN 預設在回源請求中攜帶 Ali-Cdn-Real-Ip HTTP 要求頭,表示用戶端與 CDN 節點串連時的真實 IP。通過增加自訂出站要求標頭,可將該 IP 傳遞至 WAF。CDN 控制台配置樣本如下。

    配置項

    樣本

    请求头操作

    增加

    自定义请求头参数

    自訂回源要求標頭

    自定义请求头名称

    填寫自訂名稱,例如 TrueIP

    请求头值

    $http_Ali_Cdn_Real_Ip

    是否允许重复

    不允許

    規則條件

    不使用

  2. WAF 配置

    在 WAF 控制台完成以下兩項配置:

    • WAF前是否有七層代理(高防/CDN等):使 WAF 正確識別真實用戶端 IP。

    • 啟用流量標記:使來源站點伺服器擷取真實用戶端 IP。

    具體配置方法,請參見擷取真實用戶端資訊

    配置項

    樣本

    WAF前是否有七層代理(高防/CDN等)

    選擇,繼續選擇 【推薦】取指定Header欄位中的第一個IP作為客戶端源IP,避免XFF偽造,填寫上一步 CDN 配置中的 自定义请求头名称,例如 TrueIP

    啟用流量標記

    選擇 客戶端真實源IP,並填寫上一步 CDN 配置中的 自定义请求头名称,例如 TrueIP

  3. 來源站點伺服器配置

    以 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-IpX-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)注入,用戶端無法直接控制,可有效避免偽造。