IIS Reverse Proxy 批次化部署
0 |
我有個需要中介伺服器轉接 WebAPI 請求的情境,ApWeb 主機與 ApiWeb 主機間網路不互通,故需要在中間網段架設 Proxy 串接,之前玩過 IIS ARR ,打算找台 IIS 設成 Reverse Proxy 負責轉送 ApWeb 主機發出的 WebAPI 請求。ARR 之前已設過幾次,但全憑 GUI 手工,操作步驟有點繁瑣怕有人為失誤,同時也不利自動化標準化,故我研究了以 PowerShell 及檔案部署為主的簡化安裝方法,特筆記備忘。
- 下載取得Application Request Routing 3.0 Stand-alone package (IExpress) x64 四合一安裝包,一次裝好 Web Farm Framework module、External cache module、URL Rewrite module 以及 ARR。加上 /Q 參數 ARRv3_setup_amd64_en-us.EXE /Q 可以批次方式安裝。
- 使用以下 PowerShell 指令啟用 ARR Proxy 功能
註:執行後會在 C:\Windows\System32\inetsrv\config\applicationHost.config 加入Set-WebConfigurationProperty -filter /system.webServer/proxy -name enabled -value True
<system.webServer><proxy enabled="true"/>
- 如果轉送時要加入自訂 HTTP Header,則要宣告名稱以 HTTP_* 起首 Server Variables。我希望直接寫在 web.config,但 allowedServerVariables 預設只能在 appicationHost.config 宣告。applicationHost.config configSections/sectionGroup name="rewrite"/section name="allowedServerVariables" 有個的 overrideModeDefault 設定為 Deny,改為 Allow 即可從 web.config 直接定義 allowedServerVariables。這裡依舊招喚 PowerShell 為我們搞定:
Set-WebConfigurationProperty -filter /system.webServer/rewrite -name 'sections["allowedServerVariables"].overrideModeDefault' -value Allow
- 在 web.config 加入以下設定
以上設定定義將連上 Reverse Proxy IIS 的 httq://rev-proxy/Test/* 一律導向 httq://172.28.1.1/Test/*,並在 HTTP Header 加入一條 X-Orig-ClientIP 傳入原始來源 IP。allowedServerVariables 中以 HTTP_* 為首的伺服器變數名稱,將會對應成 HTTP Header,而變數名稱中的 _ 會轉成 -。<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <rewrite> <allowedServerVariables> <add name="HTTP_X_Orig_ClientIP" /> </allowedServerVariables> <rules> <rule name="TestReverseProxy" stopProcessing="true"> <match url="Test/(.*)" /> <conditions> <add input="{CACHE_URL}" pattern="^(https?)://" /> </conditions> <action type="Rewrite" url="http://172.28.1.1/Test/{R:1}" /> <serverVariables> <set name="HTTP_X_Orig_ClientIP" value="{REMOTE_ADDR}" /> </serverVariables> </rule> </rules> </rewrite> </system.webServer> </configuration>
就醬,連 IIS 管理員都不用打開,我們已完成所有設定。
我寫了一個測試網頁觀察轉換效果:ShowHeaders.aspx
<%@ Page Language="C#" %>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
Response.ContentType = "text/plain";
Response.Write("[Headers]\n");
foreach (string key in Request.Headers.Keys)
{
Response.Write(key + ": " + Request.Headers[key] + "\n");
}
Response.Write("\n[Variables]");
Response.Write("\nUserHostAddress = " + Request.UserHostAddress);
Response.End();
}
</script>
在 Reverse Proxy 主機 (在本例為 172.28.1.11) 開 IE 直接連 172.28.1.1/Test/ShowHeaders.aspx 長這樣:
若改呼叫 localhost/Test/ShowHeaders.aspx 由 Reverse Proxy 轉接時長這樣:
紅色部分是我們加入的自訂 Header,黃色部分則是 ARR 自動加上的。
最後補充,如果要從 Header 取出原始 IP,不管是自訂 Header 或是 X-Forwarded-For 都有被偽造的可能,不可盡信。一個稍微提升安全度的做法是 - 以白名單列舉 Reverse Proxy 或 Proxy 的 IP,只有來自這些 IP 的 Request 才改由 Header 取 IP,否則以 Request.UserHostAddress 為準。
【延伸閱讀】
A script-based IIS reverse proxy setup procedures.
Comments
Be the first to post a comment