具有 URL 重寫 v2 和應用程式要求路由的反向 Proxy
作者: Ruslan Yakushev
本逐步解說將引導您使用 URL 重寫模組和 應用程式要求路由 (ARR) ,為多個後端應用程式實作 反向 Proxy 伺服器 。
必要條件
若要執行此逐步解說,您必須具備下列專案:
- 已啟用 ASP.NET 角色服務的 IIS 7 或更新版本。
- 如果您想要完成回應重寫) 的相關部分,則需要安裝 (2.0 版的 URL 重寫模組
- 已安裝應用程式要求路由 1.0 版或 2.0 版
簡介
藉由使用 URL 重寫模組和應用程式要求路由,您可以實作複雜且彈性的負載平衡和反向 Proxy 組態。 非常常見的反向 Proxy 案例是透過網際網路提供數個內部 Web 應用程式。 可存取網際網路的 Web 服務器會當做接收 Web 要求的反向 Proxy 伺服器,然後轉送至數個內部網路應用程式進行處理:下圖說明反向 Proxy 案例的一般設定:
假設 ARR 伺服器具有功能變數名稱 http://contoso.com
,您可以使用下列 URL 來存取每個 Web 應用程式:
http://contoso.com/webmail/
http://contoso.com/payroll/
對 提出 http://contoso.com/webmail/default.aspx
要求時,ARR 會使用 URL http://webmail/default.aspx
將這些要求轉送至內部伺服器。 同樣地,的要求 http://contoso.com/payroll/
會轉送到 http://payroll/default.aspx
。
此外,如果內部應用程式將連結插入其連結到這些應用程式中其他位置的回應 HTML,則應在回應傳回用戶端之前修改這些連結。 例如,來自 http://webmail/default.aspx
的頁面可能包含如下的連結:
<a href="/default.aspx?id=1">link</a>
然後 ARR 伺服器應該將此連結變更為下列專案:
<a href="/webmail/default.aspx?id=1">link</a>
建立範例網站
為了簡單起見,您將在本逐步解說中使用的反向 Proxy 案例會在單一伺服器上實作,而 IIS「預設網站」作為反向 Proxy 網站,以及裝載于相同伺服器上的個別 IIS 網站中的 Webmail 和薪資應用程式。
若要建立範例網站:
在下列資料夾中建立名為 「webmail」 和 「薪資」 的兩個資料夾:
%SystemDrive%\inetpub\ folder.
建立兩個名為 「webmail」 和 「薪資」 的 IIS 網站,指向 底下的
%SystemDrive%\inetpub\
對應資料夾。 針對每個月臺使用不同的 IP 埠。
您可以使用下列命令來建立月臺:%windir%\System32\inetsrv\appcmd.exe add site /name:"webmail" /bindings:http/*:8081: /physicalPath:"%SystemDrive%\inetpub\webmail" %windir%\System32\inetsrv\appcmd.exe add site /name:"payroll" /bindings:http/*:8082: /physicalPath:"%SystemDrive%\inetpub\payroll"
在下列資料夾中建立名為 default.aspx 的檔案:
%SystemDrive%\inetpub\webmail
複製下列 ASP.NET 標記、將它貼到檔案中,然後儲存檔案:
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Reverse Proxy Test - WebMail Application</title> </head> <body> <h1>Reverse Proxy Test Page - WebMail Application</h1> <p>Requested URL path is <%= Request.ServerVariables["SCRIPT_NAME"] %><p> <p><a href="<%= Request.ServerVariables["SCRIPT_NAME"] %>">Here</a> is the link to this page.</p> </body> </html>
在下列資料夾中建立名為 default.aspx 的檔案:
%SystemDrive%\inetpub\payroll
複製下列 ASP.NET 標記、將它貼到檔案中,然後儲存檔案:
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Reverse Proxy Test - Payroll Application</title> </head> <body> <h1>Reverse Proxy Test Page - Payroll Application</h1> <p>Requested URL path is <%= Request.ServerVariables["SCRIPT_NAME"] %><p> <p><a href="<%= Request.ServerVariables["SCRIPT_NAME"] %>">Here</a> is the link to this page.</p> </body> </html>
若要確定網站正常運作,請開啟 Web 流覽並要求下列 URL:
http://localhost:8081/default.aspx
http://localhost:8082/default.aspx
設定反向 Proxy 的規則
在逐步解說的本節中,您將設定反向 Proxy 功能,以使用您已建立的範例網站。
啟用反向 Proxy 功能
預設會停用反向 Proxy 功能,因此您必須從啟用它開始。
建立 Webmail 應用程式的規則
您將建立兩個重寫規則:
- 只要要求的 URL 路徑開頭為 「webmail」,重寫規則就會將任何要求 Proxy 至 Webmail 應用程式
http://localhost:8081/
。 - 只要要求的 URL 路徑開頭為 「薪資」,重寫規則就會將任何要求 Proxy 至薪資應用程式
http://localhost:8082/
。
若要新增反向 Proxy 重寫規則:
開啟位於下列位置 的web.config 檔案:
%SystemDrive%\inetpub\wwwroot\
在 /configuration/system.webServer 元素下,新增下列內容,然後儲存檔案:
<rewrite> <rules> <rule name="Reverse Proxy to webmail" stopProcessing="true"> <match url="^webmail/(.*)" /> <action type="Rewrite" url="http://localhost:8081/{R:1}" /> </rule> <rule name="Reverse Proxy to payroll" stopProcessing="true"> <match url="^payroll/(.*)" /> <action type="Rewrite" url="http://localhost:8082/{R:1}" /> </rule> </rules> </rewrite>
如需建立重寫規則的詳細資訊,請參閱 建立 URL 重寫模組的重寫規則。
測試反向 Proxy 功能
開啟網頁瀏覽器,並向 提出要求 http://localhost/webmail/default.aspx
。 您應該會看到來自 Webmail 測試頁面的回應。 此外,請向 http://localhost/payroll/default.aspx
提出要求。 您應該會看到薪資測試頁面的回應。
請注意,在這兩種情況下,回應點內的連結會 http://localhost/default.aspx
指向 。 如果您按一下此連結,將會導致來自伺服器的 404 (檔案找不到) 回應。 在下一節中,您將瞭解如何建立輸出規則,以修正應用程式所產生的回應 HTML 連結。
設定回應重寫的規則
本檔章節適用于 適用于 IIS 7 的 URL 重寫模組 2.0版。
您將定義輸出規則,以取代回應 HTML 中的所有連結,如下所示:
<a href="/default.aspx">...</a>
將會取代為:
<a href="/webmail/default.aspx">...</a>
(回應是否來自 webmail 應用程式)
及
<a href="/payroll/default.aspx">...</a>
(回應是否來自薪資應用程式)
警告
當輸出重寫規則修改回應標頭或回應內容時,應該特別小心,以確保插入回應中的文字不包含任何用戶端可執行程式碼,這可能會導致跨網站腳本弱點。 當重寫規則使用 HTTP 標頭或查詢字串等不受信任的資料來建置將插入 HTTP 回應的字串時,這特別重要。 在這種情況下,取代字串應該使用 HtmlEncode 函式進行 HTML 編碼,例如:
<action type="Rewrite" value="{HtmlEncode:{HTTP_REFERER}}" />
若要建立規則,請遵循下列步驟:
- 移至 IIS 管理員
- 選取 [預設網站]
- 在 [功能檢視] 中,按一下 [URL 重寫]
- 在右側的 [動作] 窗格中,按一下 [新增規則...]。 在 [新增規則] 對話方塊中,選取 [輸出規則] 類別下的 [空白規則],然後按一下 [確定]:
現在,您必須定義實際的輸出規則。 在 URL Rewrite Module 2.0 中,會藉由指定下列資訊來定義輸出重寫規則:
- 規則的名稱。
- 選擇性前置條件,可控制此規則是否應套用至回應。
- 用於比對回應中字串的模式。
- 一組選擇性的條件。
- 比對模式且所有條件檢查都成功時要執行的動作。
為規則命名
在 [名稱] 文字方塊中,輸入可唯一識別規則的名稱,例如:「新增應用程式前置詞」。
定義前置條件
前置條件是用來評估是否應該在回應上執行輸出規則評估。 例如,如果修改 HTML 內容的規則,只有內容類型標頭設定為 「text/html」 的 HTTP 回應應該針對此規則進行評估。 輸出規則評估和內容重寫是 CPU 密集作業,可能會對 Web 應用程式的效能造成負面影響。 因此,使用前置條件來縮小套用輸出規則時的案例範圍。
因為您所建立的規則應該只套用在 HTML 回應上,所以您將定義一個前置條件,以檢查 HTTP 回應標頭 內容類型 是否等於 「text/html」。
若要定義前置條件:
在 [前置條件] 清單中,選取 [ < 建立新的預先條件... > ]。
這會帶您前往 [條件前編輯器] 對話方塊,您必須在其中定義前置條件。 指定前置條件設定,如下所示:
按一下 [確定] 以儲存前置條件,並返回 [編輯規則] 頁面。
定義相符的範圍
輸出重寫規則可以在 HTTP 標頭的內容或回應本文內容上運作。 此規則必須取代回應內容中的連結,因此在 [比對範圍] 下拉式清單中,選擇 [回應]。
定義標籤篩選
標籤篩選準則是用來限定特定 HTML 元素的模式比對範圍,而不是評估規則模式的整個回應。 模式比對是非常耗 CPU 的作業,而且如果針對模式評估整個回應,它可能會大幅降低 Web 應用程式回應時間。 標籤篩選可讓您指定模式比對只能在特定 HTML 標籤的內容內套用,因而大幅減少必須針對正則運算式模式進行評估的資料量。
若要定義標籤篩選,請展開下拉式清單「比對下列內容 」,然後選取並核取核取方塊「A (href 屬性) 」。
這會設定規則,將模式只套用至超連結 的 href 屬性值,如下列範例所示:
<a href="this string will be used for pattern matching">Some link</a>
定義模式
在 [模式] 文字方塊中,輸入下列字串:
^/(.*)
此字串是正則運算式,指定模式會符合以 「/」 符號開頭的任何 URL 路徑字串。
請注意模式內括弧的使用方式。 這些括弧會建立擷取群組,稍後可以使用反向參考在規則中參考。
定義條件
只有在回應來自 Webmail 或薪資應用程式時,您才需要變更回應 HTML 中的連結。 若要檢查您是否將使用條件來分析用戶端所要求的 URL 路徑。 此外,您也會定義條件模式,以從要求的 URL 擷取應用程式資料夾,以便在重寫回應中的連結時重複使用該規則。
- 展開 [條件] 群組方塊。
- 按一下 [新增...]按鈕可顯示用於定義條件的對話方塊。
- 在 [條件輸入:] 中,輸入下列字串:「{URL}」。 這會設定 URL 重寫模組,以使用 Web 用戶端要求的 URL 路徑。
- 在下拉式方塊中,選取 [符合模式]。
- 在[模式] 文字方塊中輸入
^/(webmail|payroll)/.*
。 這個正則運算式是用來比對開頭為 或/payroll
的/webmail
URL 路徑。 模式內的括弧會擷取相符 URL 字串的一部分,以便在建構取代 URL 時使用。 - 按一下 [確定] 以儲存條件,並返回 [新增規則] UI。
定義動作
選擇 [動作] 群組方塊中所列的 [重寫] 動作類型。 在 [值] 文字方塊中,輸入下列字串:
/{C:1}/{R:1}
此字串會指定應該重寫連結位址的新值。 {C:1} 是條件模式擷取群組的回溯參考,它會以 「webmail」 或 「薪資」 字串取代。 {R:1} 是規則模式擷取群組的回溯參考,在此情況下,它會以超連結中使用的原始 URL 路徑取代。
保留所有其他設定的預設值。 [編輯輸出規則] 屬性頁應該如下所示:
按一下右側的 [套用] 動作來儲存規則。
若要檢查我們剛才建立的規則組態,請開啟位於 中的 %SystemDrive%\inetput\wwwroot\
web.config檔案。 在此檔案中,您應該會看到 <rewrite>
包含此規則定義的區段:
<rewrite>
<rules>
<rule name="Reverse Proxy to webmail" stopProcessing="true">
<match url="^webmail/(.*)" />
<action type="Rewrite" url="http://localhost:8081/{R:1}" />
</rule>
<rule name="Reverse Proxy to payroll" stopProcessing="true">
<match url="^payroll/(.*)" />
<action type="Rewrite" url="http://localhost:8082/{R:1}" />
</rule>
</rules>
<outboundRules>
<rule name="Add application prefix" preCondition="IsHTML">
<match filterByTags="A" pattern="^/(.*)" />
<conditions>
<add input="{URL}" pattern="^/(webmail|payroll)/.*" />
</conditions>
<action type="Rewrite" value="/{C:1}/{R:1}" />
</rule>
<preConditions>
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
測試規則
若要測試規則是否正確地重寫回應中的 URL,請開啟網頁瀏覽器,並要求 http://localhost/webmail/default.aspx
或 http://localhost/payroll/default.aspx
。 您應該會看到輸出重寫規則已變更 HTML 回應內的連結:
總結
在本逐步解說中,您已瞭解如何設定 URL 重寫模組和應用程式要求路由,以實作反向 Proxy 案例。 此外,您已瞭解如何使用 URL 重寫模組 2.0 的新輸出重寫功能,在將連結提供給 Web 用戶端之前,先修正應用程式回應中的連結。
請注意,使用反向 Proxy 時,通常也需要重寫 HTTP 回應標頭。 若要瞭解如何使用 URL 重寫模組 2.0 來修改回應 HTTP 標頭,請參閱 修改 HTTP 回應標頭。