The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

如何讓 IIS6 與 IIS7 強迫 ASP.NET 收到指定的 Host 標頭

上週在處理一件 IIS 問題時意外發現這個詭異的設定,他讓我的網站透過 Response.Redirect 轉向時無論如何都會轉到固定網址,讓我的程式行為大亂,還好大叔我有練過 (天啊, 我變大叔了),透過 adsutil.vbs 查詢出一個十分詭異 SetHostName 屬性,這個難得的經驗當然要好好記錄一下。

我先描述一下我當時的問題,假設當時我瀏覽的網站網址為 http://www.example.com/

而我出問題的程式碼很簡單,一個簡單的網址轉向(HTTP Redirect)

Response.Redirect("/default.aspx");

然而,這一行程式照理說從 HTTP Response 標頭回傳所對應的 Header 當然是:

Location: http://www.example.com/default.aspx

���是我當時收到的 HTTP Response Header 卻是:

Location: http://www.abc.com/default.aspx

根本與我瀏覽時所連結的網址完全不同,但是我同樣的程式在任何其他 IIS 主機都沒有這個問題啊!

我找了一些時間,最後透過 adsutil.vbs 管理指令碼工具查出了以下異樣的參數(再次聲明,當 IT 不只要有腦袋,眼力也不能太差,除了要會察言觀色,還要能觀察入裡 ^^ )

 

備註: 假設這裡顯示的 SetHostName www.abc.com

這個 SetHostName 並不會顯示在 IIS6 的 GUI 管理介面中,所以不會使用 adsutil.vbs 管理指令碼的人基本上肯定很挫折了!(難道又要重灌?)

最後我的解決方式就是將這個屬性(Property)刪除,如下指令(注意: 1603528565站台識別元

cscript adsutil.vbs delete w3svc/1603528565/SetHostName

如果要手動設定 SetHostName 的話可以用以下指令

cscript adsutil.vbs set w3svc/1603528565/SetHostName "www.example.com"

 

以上是 IIS6 的設定方式,到了 IIS7 的年代已經不再使用 Metabase 了,而是改用 applicationHost.config 設定檔,但你也可以使用 appcmd 進行設定。

若要自行指定 HostName 在 IIS7 可以輸入以下指令 (針對所有站台的預設值設定):

appcmd.exe set config -section:system.webServer/serverRuntime /alternateHostName:"www.example.com"  /commit:apphost

也可以針對特定站台 (Default Web Site) 設定 alternateHostName 參數:

appcmd.exe set config "Default Web Site" -section:system.webServer/serverRuntime /alternateHostName:"www.example.com"  /commit:apphost

 

你可會納悶為什麼要設定 SetHostNamealternateHostName 呢,這也是有點歷史因素的,主要是有些資安方面的考量,避免主機名稱或內部 IP 暴露到外面,有興趣研究的人可以參考這篇文章

 

最後,透過 SetHostNamealternateHostName 的在寫程式方面有幾個要注意的地方:

  • 所有 ASP.NET 程式收到的 Request.Url.Host 將永遠會是 SetHostNamealternateHostName  的值!
  • 所有 Response.Redirect 若用相對路徑時,都會被轉向到 SetHostNamealternateHostName 設定的 HostName
  • 如果你用 Request.Headers["Host"] 取得到的值才會是 Client 端送來的 HostName

 

相關連結