應用程式閘道允許你重寫請求與回應中選定的內容。 透過此功能,您可以翻譯網址、查詢字串參數,並修改請求與回應標頭。 你也可以加入條件,確保只有在符合特定條件時,URL 或指定的標頭才會被重寫。 這些條件所根據的是要求和回應資訊。
HTTP 標頭和 URL 重寫功能僅適用於應用程式閘道 v2 SKU (部分機器翻譯)。
要求與回應標頭
應用程式閘道可讓您在要求和回應封包於用戶端與後端集區之間移動時,新增、移除或更新 HTTP 要求和回應標頭。 HTTP 標頭讓客戶端和伺服器透過請求或回應傳遞額外資訊。 透過重寫這些標頭,可以完成的重要任務包括:
- 新增安全相關的標頭欄位,如 HSTS 和 X-XSS-Protection
- 移除可能洩露敏感資訊的回應標頭欄位
- 移除 X-Forwarded-For 標頭中的端口資訊
你可以重寫所有請求和回應中的標頭,除了標頭Connection和標頭Upgrade。 您也可以使用應用程式閘道來建立自訂標頭,並將其新增至透過其路由傳送的要求和回應。 想了解如何使用 Azure 入口網站重寫 Application Gateway 的請求與回應標頭,請點 此。
URL 路徑和查詢字串
應用程式閘道中的 URL 重寫功能可讓您:
重寫請求 URL 的主機名稱、路徑和查詢字串
選擇重寫接聽程式上所有要求的 URL,或僅重寫符合您所設定一或多個條件的要求。 這些條件以要求屬性為基礎 (要求標頭和伺服器變數)。
選擇根據原始 URL 或重寫的 URL 來路由傳送要求 (選取後端集區)
想了解如何使用 Azure 入口網站重寫 Application Gateway 的 URL,請點 此。
理解應用閘道中的重寫規則
重寫集合是路由規則、條件與動作的集合。
請求路由規則關聯: 重寫設定透過其路由規則關聯到來源監聽器。 當您使用 Basic 類型的路由規則時,重寫配置會與其監聽器相關聯,並作為全域重寫生效。 當你使用基於路徑的路由規則時,你會根據 URL 路徑映射來定義重寫設定。 若為後者,其只適用於網站的特定路徑區域。 你可以將重寫規則集套用到多個路由規則,但一個路由規則只能有一個重寫。
重寫條件: 此配置為可選配置。 根據您定義的條件,應用閘道會評估 HTTP(S) 請求與回應的內容。 當 HTTP(S) 請求或回應符合此條件時,接續的「重寫動作」會發生。 如果您將多個條件與某個動作相關聯,則只有在符合所有條件時,才會發生此動作。 換句話說,這是一個邏輯“AND”運算。 您可以使用重寫條件來評估 HTTP(S) 要求和回應的內容。 此選擇性設定可讓您只在符合一或多個條件時執行重寫。 應用程式閘道會使用這些類型的變數來評估要求和回應的內容:
您可以選擇下列類型來尋找條件:
- HTTP 標頭 (要求和回應)
- 支援的伺服器變數
條件允許你透過文字或正則表達式模式來匹配指定的標頭或變數值是否存在。 針對進階的重寫設定,您也可以擷取標頭或伺服器變數的值,以供稍後在「重寫動作」下使用。 了解更多關於 模式與擷取的資訊。
重寫行動: 重寫動作集允許你重寫標頭(請求或回應)或 URL 元件。
動作可以擁有下列值類型,或這些類型的組合:
- Text。
- 請求標頭的值 - 要使用擷取的請求標頭值,請指定語法為
{http_req_headerName}。 - 回應標頭的值 - 要使用前述條件捕捉的回應標頭值,請指定語法為
{http_resp_headerName}。 「重寫動作」區塊也支援對 Set-Cookie 標頭使用「標頭值比對器」欄位。 這個選用欄位讓你在存在多個同名 Set-Cookie 標頭時,匹配並擷取特定標頭的值。 若要操作該特定 Cookie 的擷取值,您接著可以使用{capt_header_value_matcher}。 在 動作集下了解更多關於捕捉的資訊。 - 伺服器變數 - 若要使用伺服器變數,請將語法指定為
{var_serverVariable}。 支援的伺服器變數清單。
附註
目前入口網站不支援使用 Header Value Matcher 欄位 {capt_header_value_matcher}。 因此,如果你使用這個欄位,任何 PUT 操作都需要使用非入口的方法。
當你使用動作重寫 URL 時,支援以下操作:
- URL 路徑:新設的路徑值。
- URL 查詢字串:查詢字串必須重寫為的新值。
- 重新評估路徑對應:指定在重寫後是否必須重新評估 URL 路徑對應。 如果你不勾選這個選項,原始的 URL 路徑會被用來匹配 URL 路徑圖中的路徑模式。 如果你將此選項設為 true,URL 路徑圖會被重新評估以檢查是否與重寫路徑相符。 啟用此切換參數有助於在重寫後,將要求路由傳送至不同的後端集區。
模式比對和擷取
應用閘道支援條件與動作下的模式匹配與擷取。 在動作模式中,它只支援特定標頭的模式匹配與擷取。
模式比對
應用程式閘道會使用規則運算式來比對模式。 撰寫模式匹配語法時,請使用相容的正則表達式 2(RE2)。
您可以在「條件」和「動作」下使用模式比對。
- 條件:使用此設定來匹配標頭或伺服器變數的值。 要在「條件」下匹配圖案,請使用「pattern」屬性。
-
動作:行動集合下的模式匹配僅適用於回應標頭
Set-Cookie。 要在Set-Cookie的模式下匹配模式,請使用HeaderValueMatcher屬性。 若被捕獲,其值可用作{capt_header_value_matcher}。 由於標頭可能有多個Set-Cookie,這裡的模式匹配可以讓你尋找特定的 cookie。 舉例來說,針對特定版本的 user-agent,你要將set-cookie的回應標頭cookie2重寫為max-age=3600(一小時)。 在此情況下,您可以使用- 條件 - 類型:要求標頭、標頭名稱:user-agent、要比對的模式:*2.0
- 動作 - 重寫型別:回應標頭,動作型別:Set,標頭名稱:Set-Cookie,標頭值比對器:
cookie2=(.*),標頭值:cookie2={capt_header_value_matcher_1};Max-Age=3600
附註
如果你正在運行應用閘道網頁應用防火牆(WAF),並使用核心規則集 3.1 或更早版本,使用 Perl 相容正則表達式(PCRE)來執行前瞻與後顧(負或正)斷言時,可能會遇到問題。
擷取語法
你可以用模式來擷取子字串,方便日後使用。 將括弧放在 regex 定義中的子模式周圍。 第一對括弧會將其子字串儲存在 1 中,而第二對會儲存在 2,以此類推。 你可以用任意多的括號。 Perl 定義了更多編號變數來表示這些被捕獲的字串。 你可以在這份 Perl 程式設計指引中找到一些範例。
- (\d)(\d) # 比對兩位數字,將其擷取至群組 1 和 2
- (\d+) # 比對一或多個數字,將所有位數擷取至群組 1
- (\d+) # 比對一或多次,將最後一次擷取至群組 1
擷取之後,您可以使用下列格式將其用於動作集的值:
- 對於要求標頭擷取,您必須使用 {HTTP_req_headerName_groupNumber}。 例如,{HTTP_req_User-Agent_1} 或 {HTTP_req_User-Agent_2}
- 對於回應標頭擷取,您必須使用 {HTTP_resp_headerName_groupNumber}。 例如,{http_resp_Location_1} 或 {http_resp_Location_2}。 對於透過「HeaderValueMatcher」屬性擷取的回應標頭 Set-Cookie,則必須使用 {capt_header_value_matcher_groupNumber}。 例如,{capt_header_value_matcher_1} 或 {capt_header_value_matcher_2}。
- 對於伺服器變數,您必須使用 {var_serverVariableName_groupNumber}。 例如,{var_uri_path_1} 或 {var_uri_path_2}
附註
- 用 / 來在圖案前加上後綴,不應該在圖案中指定以匹配值。 例如,(\d)(\d) 會比對兩位數字。 /(\d)(\d)/ 不會比對兩位數字。
- 條件變數的大小寫必須符合擷取變數的大小寫。 例如,如果我的條件變數是 User-Agent,我的擷取變數必須是 User-Agent(也就是 {http_req_User-Agent_2})。 如果我的條件變數定義為 user-agent,那麼我的擷取變數必須是 user-agent(也就是 {http_req_user-agent_2})。
- 如果你想用整個數值,就不應該提到數字。 單純使用 {HTTP_req_headerName} 格式之類,而不使用 groupNumber。
伺服器變數
應用程式閘道會使用伺服器變數來儲存伺服器、與用戶端的連線,以及連線上目前要求的相關實用資訊。 儲存的資訊範例包括用戶端的 IP 位址和網頁瀏覽器類型。 例如,當新頁面載入或張貼表單時,伺服器變數會動態地變更。 您可以使用這些變數來評估重寫條件和重寫標頭。 若要使用伺服器變數的值來重寫標頭,您必須在語法 {var_serverVariableName} 中指定這些變數
應用程式閘道支援下列伺服器變數:
| 變數名稱 | 描述 |
|---|---|
| add_x_forwarded_for_proxy | 以 IP1、IP2、IP3 等格式附加 client_ip 變數的 X-Forwarded-For 用戶端要求標頭欄位 (請參閱下表稍後的說明)。 如果 X-Forwarded-For 欄位不在用戶端要求標頭中,則 add_x_forwarded_for_proxy 變數等於 $client_ip 變數。 當您想要重寫應用程式閘道設定的 X-Forwarded-For header 標頭時,此變數會很有用,如此可讓標頭只包含 IP 位址,而不包含連接埠資訊。 |
| 支持的加密法 | 用戶端支援的加密清單。 |
| 使用的加密算法 | 用於所建立 TLS 連線的加密字串。 |
| 客户端IP (client_ip) | 應用程式閘道接收要求所在用戶端的 IP 位址。 如果應用程式閘道和原始用戶端之前有反向 Proxy,client_ip 會傳回反向 Proxy 的 IP 位址。 |
| client_port | 用戶端連接埠。 |
| client_tcp_rtt | 用戶端 TCP 連線的相關資訊。 適用於支援 TCP_INFO 通訊端選項的系統。 |
| client_user | 使用 HTTP 驗證時,提供用於驗證的使用者名稱。 |
| 主持人 | 優先順序如下:來自要求行的主機名稱、來自 Host 要求標頭欄位的主機名稱,或是與要求相符的伺服器名稱。 範例:在要求 http://contoso.com:8080/article.aspx?id=123&title=fabrikam 中,主機值為 contoso.com |
| cookie_name | name Cookie。 |
| http_method | 用來提出 URL 要求的方法。 例如,GET 或 POST。 |
| http_status | 工作階段狀態。 例如,200、400 或 403。 |
| http_version | 要求通訊協定。 通常是 HTTP/1.0、HTTP/1.1 或 HTTP/2.0。 |
| 查詢字串 | 在請求的 URL 中,? 後面接著的變數/值對清單。 範例:在要求 http://contoso.com:8080/article.aspx?id=123&title=fabrikam 中,query_string 值為 id=123&title=fabrikam |
| 接收字節數 | 要求的長度 (包括要求行、標頭和要求本文)。 |
| request_query | 要求行中的引數。 |
| request_scheme | 要求結構配置:http 或 https。 |
| request_uri | 完整的原始要求 URI (含引數)。 範例:在要求 http://contoso.com:8080/article.aspx?id=123&title=fabrikam* 中,request_uri 值為 /article.aspx?id=123&title=fabrikam |
| sent_bytes | 傳送給用戶端的位元組數。 |
| 伺服器端口 | 已接受要求的伺服器連接埠。 |
| ssl_connection_protocol | 所建立 TLS 連線的通訊協定。 |
| SSL 已啟用 | 如果連線以 TLS 模式運作,則為「On」。 否則便為空字串。 |
| uri_path | 識別 Web 用戶端想要存取主機中的特定資源。 變數指的是任何操作前的原始 URL 路徑。 這是要求 URI 中不含引數的部分。 例如,在要求 http://contoso.com:8080/article.aspx?id=123&title=fabrikam 中,uri_path 值為 /article.aspx。 |
相互驗證伺服器變數
應用程式閘道支援下列用於相互驗證案例的伺服器變數。 像使用其他伺服器變數一樣使用這些伺服器變數。
| 變數名稱 | 描述 |
|---|---|
| 用戶端憑證 | 用於已建立 SSL 連線的 PEM 格式用戶端憑證。 |
| 用戶憑證結束日期 | 用戶端憑證的結束日期。 |
| 客戶憑證指紋 | 用於已建立 SSL 連線的用戶端憑證 SHA1 指紋。 |
| 用戶端憑證發行者 | 用於已建立 SSL 連線的用戶端憑證「issuer DN」字串。 |
| 客戶憑證序列 | 用於已建立 SSL 連線的用戶端憑證序號。 |
| 客戶憑證開始日期 | 用戶端憑證的開始日期。 |
| 用戶端憑證主題 | 用於已建立 SSL 連線的用戶端憑證「subject DN」字串。 |
| 用戶端憑證驗證 | 客戶端憑證驗證結果為: 成功、 失敗:<原因>,或若無憑證則為 無 。 |
標頭重寫的常見案例
從 X-Forwarded-For 標頭中移除連接埠資訊
應用程式閘道會將 X-Forwarded-For 標頭插入所有要求,再將要求轉送至後端。 此標頭是以逗號分隔的 IP 連接埠清單。 在某些情況下,後端伺服器只需要標頭來包含 IP 位址。 您可以使用標頭重寫,以從 X-Forwarded-For 標頭中移除連接埠資訊。 其中一種方法是將標頭設定為 add_x_forwarded_for_proxy 伺服器變數。 或者,您也可以使用變數 client_ip:
修改重新導向 URL
在某些情況下,修改重定向網址可能很有用。 舉例來說,你一開始可能把客戶導向到像「/blog」這樣的路徑,但因為內容結構改變,現在想把他們導向「/updates」。
警告
你可能需要在設定應用閘道(Application Gateway)時修改重定向 URL,以覆蓋後端的主機名稱。 在此配置下,後端看到的主機名稱與瀏覽器不同。 重定向沒有使用正確的主機名稱。 不建議使用此設定。
欲了解更多此類配置的限制與影響,請參閱「 在反向代理與其後端網頁應用程式間保留原始 HTTP 主機名稱」。 關於 App Service 的建議設定,請參閱「Configure App Service with Application Gateway」中的「自訂網域(推薦)」。 如以下範例所述,重寫回應位置標頭應視為一種權宜之計,並未解決根本原因。
當 App Service 傳送重新導向回應時,會在其回應的位置標頭中使用與其從應用程式閘道所接收要求中主機名稱相同的主機名稱。 因此,用戶端會直接對 contoso.azurewebsites.net/path2 提出要求,而非透過應用程式閘道 (contoso.com/path2)。 不需要略過應用程式閘道。
您可以將位置標頭中的主機名稱設定為應用程式閘道的網域名稱,以解決此問題。
以下是取代主機名稱的步驟:
建立一個重寫規則,並有一個條件檢查回應中的位置標頭是否包含 azurewebsites.net。 輸入圖案 '(https?)://.azurewebsites.net(.)。
執行動作來重寫位置標頭,使其具有應用程式閘道的主機名稱。 輸入
{http_resp_Location_1}://contoso.com{http_resp_Location_2}標頭值。 或者,您也可以使用伺服器變數host來設定主機名稱以符合原始要求。
實作安全性 HTTP 標頭以防止弱點
您可以在應用程式回應中實作必要的標頭,以修正數個安全性弱點。 這些安全性標頭包括 X-XSS-Protection、Strict-Transport-Security 和 Content-Security-Policy。 您可以使用應用程式閘道來設定所有回應的這些標頭。
刪除不必要的標頭
您可能想要從 HTTP 回應中移除顯示敏感性資訊的標頭。 例如,您可能想要移除後端伺服器名稱、作業系統或程式庫詳細資料等資訊。 您可以使用應用程式閘道來移除這些標頭:
你無法建立重寫規則來刪除主機標頭。 如果您嘗試建立重寫規則,並將動作類型設定為 delete,且將標頭設定為 host,則會產生錯誤。
檢查標頭是否存在
您可以評估 HTTP 要求或回應標頭,以瞭解標頭或伺服器變數是否存在。 您想要僅在特定標頭存在才執行標頭重寫時,此評估相當實用。
URL 重寫的常見案例
參數型路徑選取
為了根據請求中的標頭、URL 部分或查詢字串的值來選擇後端池,請結合 URL 重寫功能與路徑路由。
建立一個重寫集,並設定條件檢查特定參數(查詢字串、標頭等),然後執行一個動作改變 URL 路徑(確保啟用 Reevaluate 路徑映射 )。 將重寫集與基於路徑的規則關聯起來。 路徑型規則必須包含重寫集及其對應後端集區中指定的相同 URL 路徑。
因此,重寫集允許你檢查特定參數並為它指派新路徑,而基於路徑的規則則允許你將後端池指派給這些路徑。 只要啟用「重新評估路徑圖」,流量就會根據重寫集中指定的路徑進行路由。
如需使用查詢字串的使用案例範例,請參閱在入口網站中使用參數型路徑選取項目來路由流量。
根據 URL 重寫查詢字串參數
想像一個購物網站的情境,使用者可見的連結簡單且易讀,但後端伺服器需要查詢字串參數來顯示正確的內容。
在這種情況下,應用閘道可以從 URL 擷取參數,並將包含這些參數的查詢字串鍵值對新增到 URL 中。 例如,如果使用者想重寫 https://www.contoso.com/fashion/shirts 為 https://www.contoso.com/buy.aspx?category=fashion&product=shirts,可以透過以下 URL 重寫設定達成此目標。
條件 - 如果伺服器變數 uri_path 等於模式 /(.+)/(.+)
動作 - 將 URL 路徑設定為 buy.aspx,並將查詢字串設定為 category={var_uri_path_1}&product={var_uri_path_2}
欲取得逐步達成上述情境的指南,請參閱 使用 Azure 入口網站的 Rewrite URL with Application Gateway 。
重寫設定的常見陷阱
你無法啟用「重新評估路徑圖」來執行基本的請求路由規則。 此限制防止基本路由規則產生無限評估迴圈。
針對路徑型路由規則,你需要至少一條條件重寫規則或一條未啟用「重新評估路徑映射」的重寫規則。 此要求防止基於路徑的路由規則產生無限評估迴圈。
如果迴圈是根據用戶端輸入動態建立,收到的請求會以 500 錯誤代碼結束。 應用閘道在此情境下仍可繼續服務其他請求,且不會造成損壞。
使用 URL 重寫或主機標頭重寫搭配 Web 應用程式防火牆 (WAF_v2 SKU)
當您設定 URL 重寫或主機標頭重寫時,WAF 評估會在修改要求標頭或 URL 參數之後 (重寫後) 發生。 當你移除應用程式閘道上的 URL 重寫或主機標頭重寫設定時,WAF 評估會在標頭重寫之前(重寫前)進行。 此命令確保 WAF 規則適用於你的後端池收到的最終請求。
例如,假設你有以下標頭重寫規則 "Accept" : "text/html" ——如果標頭 "Accept" 的值等於 "text/html",則將該值重寫為 "image/png"。
僅配置標頭重寫時,WAF 評估將發生在 "Accept" : "text/html"。 但當你設定 URL 重寫或主機標頭重寫時,WAF 評估會在 "Accept" : "image/png"。
URL 重寫與 URL 重新導向
對於 URL 重寫,Application Gateway 會在將請求送回後端之前先重寫 URL。 這個動作不會改變使用者在瀏覽器中看到的內容,因為這些變更對使用者是隱藏的。
針對 URL 重新導向,應用程式閘道會使用新的 URL 將重新導向回應傳送至用戶端。 該回應要求客戶端將請求重新傳送至重定向中提供的新網址。 使用者在瀏覽器中看到的 URL 會更新為新的 URL。
限制
- 當應用程式閘道設定為重新導向要求或顯示自訂錯誤頁面時,不支援重寫。
- 要求標頭名稱可以包含英數字元和連字號。 包含其他字元的標頭名稱在向後端目標發送請求時會被丟棄。
- 回應標頭名稱可以包含任何英數字元和 RFC 7230 (英文) 中所定義的特定符號。
- 你無法重寫
X-Original-Host、Connection和upgrade標頭。 - 對於直接由 Application Gateway 產生的 4xx 和 5xx 回應,不支援重寫。