如何在 IIS 7.0 中使用 HTTP 詳細錯誤
由 IIS 小組
簡介
每個Web-Site系統管理員或 Web 開發人員在瀏覽器中看到「404 - 檔案找不到」、「401 - 未經授權」或「500 - 伺服器錯誤」訊息。 本文可協助您瞭解 IIS 產生這些錯誤的方式和原因,以及如何設定這些錯誤。
許多可能認為產生錯誤訊息似乎不合理化完整文章。 但是,錯誤比符合眼睛還多。 錯誤訊息是一個敏感性主題,因為每個錯誤都會顯示您網站的詳細資訊,而不是您可能想要顯示的。 有人可以收集網站的詳細資訊,就像您遭到駭客入侵一樣。 搜尋「Google 駭客」或「跨網站腳本」會顯示本主題的豐富資訊。
不過,錯誤訊息也是針對問題進行疑難排解的重要工具。 開發人員和Web-Site系統管理員在發生錯誤時,需要盡可能詳細資料。 在理想情況下,錯誤訊息會提供如何修正問題的建議。 以下是 IIS 如何解決這些基本上相反的目標。
錯誤、哪些錯誤?
本文討論 HTTP RFC (RFC 2616 - 第 6.1.1 節) 中指定的 HTTP 錯誤。 HTTP 錯誤一律會透過將狀態碼大於 400 的回應傳送回要求用戶端來表示。
用戶端錯誤
狀態碼介於 400 到 500 之間,指定用戶端所做的錯誤,例如不正確的語法或不存在之資源的要求。 您可以從您選擇的網站要求偽造 URL,例如:HTTP:// < IIS7Server > /this_resource_does_not_exist。 您收到「404 - 找不到檔案」錯誤。
伺服器錯誤
從 500 開始的狀態碼是伺服器所造成的錯誤。 IIS 系統上 500 個錯誤最常見的原因如下:
- 包含語法錯誤的 ASP 或 ASPX 頁面
- Web 服務器組態或應用程式組態無法讀取或無效
- 月臺已停止
請務必注意,IE 之類的瀏覽器通常會以自己的錯誤取代從網頁伺服器傳回的錯誤。 這會使疑難排解更困難。 在 IE 中,您可以關閉此功能。 移至 [工具] 功能表,選取 [網際網路選項],按一下 [進階] 索引標籤並尋找 [顯示易記 HTTP 錯誤訊息] 核取方塊,然後取消核取。 若要查看原始回應,請在 IIS 6.0 Resource Kit 中使用 WFETCH 之類的 HTTP 工具, (請參閱「相關連結」) 。
IIS 中的 HTTP 錯誤
當 HTTPError 模組 (custerr.dll) 發生錯誤時,會發生兩件事:
- 產生自訂錯誤
- 產生詳細的錯誤
自訂錯誤是您網站一般使用者看到的錯誤頁面。 它們包含錯誤發生原因的簡短錯誤描述,但沒有其他內容。 以下是當您要求不存在的資源時所產生的自訂錯誤,例如:HTTP:// < IIS7Server > /this_resource_does_not_exist
詳細的錯誤適用于本機系統管理員和開發人員。 他們應該提供有助於立即修正問題的資訊。 以下是相同要求的範例,但現在會傳回詳細的錯誤:
這很危險,因為詳細錯誤包含網站內部工作的相關資訊。 只有受信任的人員應該會看到詳細的錯誤。 確保唯一的方法是,只有在要求來自本機電腦時,才會產生詳細的錯誤。 一旦要求不是本機,就會產生自訂錯誤。 查看下列流程圖:
資料流程
第一個:錯誤檢查
如果回應即將傳送 (RQ_SEND_RESPONSE通知,HTTPError 模組就會收到通知) 。 HTTPError 模組會檢查此回應的狀態碼,並在狀態碼不大於 400 時立即傳回。
第二個:自訂錯誤或詳細錯誤
下一個檢查取決於要求來源 (是要求本機或遠端要求) 和 errorMode 屬性的設定。 errorMode 屬性會設定為 DetailedLocalOnly,這表示會針對每個遠端要求產生自訂錯誤。 如果 errorMode 設定為 「Custom」,則所有錯誤回應都會變成自訂錯誤。 如果 errorMode 設定為 「詳細」,所有錯誤回應都會變成 「詳細錯誤」。 下表厘清此行為:
errorMode | 要求來源 | 動作 |
---|---|---|
DetailedLocalOnly (預設) | 本機 | 詳細錯誤 |
DetailedLocalOnly (預設) | 遠端 | 自訂錯誤 |
Custom | 本機 | 自訂錯誤 |
Custom | 遠端 | 自訂錯誤 |
詳細 | 本機 | 詳細錯誤 |
詳細 | 遠端 | 詳細錯誤 |
如果 HTTPError 模組判斷必須產生自訂錯誤,它會查看其設定,以查看是否可以找到相符的錯誤。 如果找到相符專案,它會傳送靜態檔案、重新導向要求或執行指定的 URL。 如果找不到相符專案,IIS 會傳送包含狀態碼的基本單行訊息。 下一節會詳細說明自訂錯誤設定。
如果custerr.dll判斷必須產生詳細錯誤,則需要另一個檢查。 如果模組以自己的錯誤描述覆寫回應的實體,IIS 就不會觸碰回應。 它可能包含重要資訊。 ASP.NET 是不錯的範例。 ASP.NET 錯誤回應的實體可能包含例外狀況堆疊及其本身的錯誤描述。 只有在回應的實體主體是空的時,才會產生詳細錯誤。
<httpErrors>
組態
以下是在全新安裝上取得的 IIS 自訂錯誤區段:
<httpErrors>
<error statusCode="401" prefixLanguageFilePath="c:\inetpub\custerr" path="401.htm" />
<error statusCode="403" prefixLanguageFilePath="c:\inetpub\custerr" path="403.htm" />
<error statusCode="404" prefixLanguageFilePath="c:\inetpub\custerr" path="404.htm" />
<error statusCode="405" prefixLanguageFilePath="c:\inetpub\custerr" path="405.htm" />
<error statusCode="406" prefixLanguageFilePath="c:\inetpub\custerr" path="406.htm" />
<error statusCode="412" prefixLanguageFilePath="c:\inetpub\custerr" path="412.htm" />
<error statusCode="500" prefixLanguageFilePath="c:\inetpub\custerr" path="500.htm" />
<error statusCode="501" prefixLanguageFilePath="c:\inetpub\custerr" path="501.htm" />
<error statusCode="502" prefixLanguageFilePath="c:\inetpub\custerr" path="502.htm" />
</httpErrors>
您會看到,如果回應的狀態碼為 401,IIS 會傳回名為 401.htm 的檔案。
Sub-Status代碼
許多 HTTP 錯誤都有子狀態。 IIS 預設的自訂錯誤設定不會區分以子狀態碼為基礎的。 如果您輸入錯誤的認證 (401.1) ,或根據存取檔案的許可權無效而遭到拒絕,則會傳送相同的自訂錯誤頁面 (401.3) 。 您可以在記錄檔或透過詳細錯誤查看不同的子狀態碼。 以下是 IIS 產生的不同 404 子狀態代碼清單:
狀態 | 描述 |
---|---|
404.1 | 找不到網站 |
404.2 | 原則拒絕。 限制清單中不允許要求 ISAPI 或 CGI 程式。 |
404.3 | 靜態檔案處理常式在其 MimeMap 中沒有檔案,因此拒絕要求。 |
404.4 | 找不到處理程式來提供要求。 |
404.5 | 要求篩選模組拒絕要求中的 URL 序列。 |
404.6 | 要求篩選模組拒絕要求的 HTTP 動詞。 |
404.7 | 要求篩選模組拒絕要求的副檔名。 |
404.8 | 要求篩選模組拒絕了兩個斜線) 之間的特定 URL 區段 (字元。 |
404.9 | IIS 拒絕提供隱藏的檔案。 |
404.11 | 要求篩選模組拒絕了重複逸出的要求。 |
404.12 | 要求篩選模組拒絕包含高位字元的要求。 |
404.14 | 要求篩選模組拒絕了 URL 太長的要求。 |
404.15 | 要求篩選模組拒絕了查詢字串太長的要求。 |
413.1 | 要求篩選模組拒絕了要求太長 (要求 + 實體主體) 。 |
431 | 要求篩選模組拒絕了太長標頭。 |
您可以設定 HTTPErrors 區段,以顯示特定子狀態碼的自訂錯誤。 如果您將下列這一行新增至 HTTPErrors 組態區段,IIS 會傳回404_3.htm如果要求副檔名為的檔案未包含在 IIS MimeMap (< staticContent > 組態區段) 。
<error statusCode="404" subStatusCode="3" prefixLanguageFilePath="c:\inetpub\custerr" path="404_3.htm" />
以下是如何讓範例運作:
- 將上述專案新增至 HTTPErrors 組態區段。
- 在目錄中建立名為 404_3.htm 的
c:\inetpub\custerr\en-us
檔案。 - 在您
c:\inetpub\wwwroot
目錄中建立名為 test.yyyy 的檔案。 - 現在要求
http://localhost/test.yyy
。
副檔名 .yyy 不是 IIS MimeMap 的一部分,靜態檔案處理常式將不會提供它。
IIS 的新功能:特定語言自訂錯誤
每個較新的瀏覽器都包含用戶端的語言做為要求標頭。 以下是此標頭外觀的範例:
Accept-Language: en-us
接受語言的語法和登錄是在 RFC1766中指定。
產生錯誤時,IIS 會在尋找傳回的自訂錯誤檔案時,將此標頭納入考慮。 它會使用下列邏輯產生自訂錯誤的路徑:
prefixLanguageFilePath 組態設定 (例如 c:\inetpub\custerr
) +
用戶端 (傳送的Accept-Language標頭,例如 en-us) +
路徑組態設定 (例如 404.htm)
範例:
如果瀏覽器傳送非現有資源的要求,而 「Accept-Language」 標頭的值為 「en-us」,則傳回的檔案會是 c:\inetpub\custerr\en-us\404.htm
。
例如,如果您是來自德國,您會想要德文中的錯誤訊息。 若要這樣做,您必須安裝適用于德文的 Windows Vista 語言套件。 這會建立 c:\inetpub\custerr\de-DE
目錄中具有自訂錯誤檔案的目錄。 現在,如果瀏覽器傳送具有 「de-DE」 值的 「Accept-Language」 標頭,則傳回的檔案將會是 c:\inetpub\custerr\de-DE\404.htm
。
如果目錄 「de-DE」 不存在,IIS 一律會回復為系統語言。
注意
Internet Explorer 可讓您設定Accept-Language標頭。 移至 [工具] - [網際網路選項],選取 [一般] 索引標籤,然後按一下 [語言] 按鈕。
自訂錯誤選項
在上述範例中,IIS 會將檔案的內容傳送為自訂錯誤回應。 IIS 有兩種方式可回應錯誤:執行 URL 或重新導向要求。
ExecuteUrl
如果您想要在自訂錯誤中執行更多動作,例如傳送電子郵件或記錄錯誤至資料庫,您可以執行 URL。 這可讓您執行動態內容,例如 ASP.NET 網頁。 下列範例會取代 404 自訂錯誤。 現在,每當發生 404 錯誤時,IIS 就會執行 /404.aspx。
<httpErrors>
<!-- default custom error for 401 errors -->
<!-- <error statusCode="404" prefixLanguageFilePath="c:\inetpub\custerr" path="404.htm" />-->
<!-- ExecuteURL replaces default file response mode -->
<error statusCode="404" path=/404.aspx" responseMode="ExecuteURL"/>
<error statusCode="403" prefixLanguageFilePath="c:\inetpub\custerr" path="403.htm" />
<error statusCode="404" prefixLanguageFilePath="c:\inetpub\custerr" path="404.htm" />
<error statusCode="405" prefixLanguageFilePath="c:\inetpub\custerr" path="405.htm" />
<error statusCode="406" prefixLanguageFilePath="c:\inetpub\custerr" path="406.htm" />
<error statusCode="412" prefixLanguageFilePath="c:\inetpub\custerr" path="412.htm" />
<error statusCode="500" prefixLanguageFilePath="c:\inetpub\custerr" path="500.htm" />
<error statusCode="501" prefixLanguageFilePath="c:\inetpub\custerr" path="501.htm" />
<error statusCode="502" prefixLanguageFilePath="c:\inetpub\custerr" path="502.htm" />
</httpErrors>
安全性考量
注意:基於架構考慮,IIS 只有在位於相同的應用程式集區時,才能執行 URL。 使用重新導向功能在不同的應用程式集區中執行自訂錯誤。
IIS 也可以在發生特定錯誤時,傳回 302 重新導向至瀏覽器。 如果您有伺服器陣列,則重新導向是不錯的。 例如,您可以將所有錯誤重新導向至您密切監視的中央位置。
不過,有風險:responseMode=「File」 (這是預設) 可讓您指定磁片上的每個檔案。 如果您非常有安全性意識,這將無法運作。
可運作的案例可能只允許委派 errorMode 設定。 這可讓開發人員接收其應用程式的詳細錯誤,即使他使用的是遠端用戶端也一樣。 只需要設定 errorMode=「Detailed」。 以下是如何設定此案例:
允許委派 HTTPErrors 區段:
<section name="httpErrors" overrideModeDefault="Allow" />
其次,移至 applicationHost.config 中的 區 <httpErrors>
段並加以變更,以便只委派 errorMode:
<httpErrors lockAllAttributesExcept="errorMode" lockElements="error">
<error statusCode="404" prefixLanguageFilePath="E:\inetpub\custerr" path="404.htm" />
<error statusCode="401" prefixLanguageFilePath="E:\inetpub\custerr" path="401.htm" />
<error statusCode="403" prefixLanguageFilePath="E:\inetpub\custerr" path="403.htm" />
<error statusCode="405" prefixLanguageFilePath="E:\inetpub\custerr" path="405.htm" />
<error statusCode="406" prefixLanguageFilePath="E:\inetpub\custerr" path="406.htm" />
<error statusCode="412" prefixLanguageFilePath="E:\inetpub\custerr" path="412.htm" />
<error statusCode="500" prefixLanguageFilePath="E:\inetpub\custerr" path="500.htm" />
<error statusCode="501" prefixLanguageFilePath="E:\inetpub\custerr" path="501.htm" />
<error statusCode="502" prefixLanguageFilePath="E:\inetpub\custerr" path="502.htm" />
</httpErrors>
總結
自訂和詳細錯誤是功能強大的 IIS 功能。 它們可協助您針對問題進行疑難排解,而不會危害 IIS 伺服器的安全性。 許多組態選項可協助您自訂自訂使用者的體驗。 最重要的是:進行實驗是有趣的。