如何在 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

Internet Explorer 中找不到 H T T P 錯誤 404 檔案或目錄網頁的螢幕擷取畫面。

詳細的錯誤適用于本機系統管理員和開發人員。 他們應該提供有助於立即修正問題的資訊。 以下是相同要求的範例,但現在會傳回詳細的錯誤:

[預設網站應用程式] 網頁中 [伺服器錯誤] 的螢幕擷取畫面,其中顯示錯誤的原因和解決方案區段。

這很危險,因為詳細錯誤包含網站內部工作的相關資訊。 只有受信任的人員應該會看到詳細的錯誤。 確保唯一的方法是,只有在要求來自本機電腦時,才會產生詳細的錯誤。 一旦要求不是本機,就會產生自訂錯誤。 查看下列流程圖:

狀態子狀態、實體本文和設定錯誤建立詳細錯誤路徑的圖表。

資料流程

第一個:錯誤檢查

如果回應即將傳送 (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" />

以下是如何讓範例運作:

  1. 將上述專案新增至 HTTPErrors 組態區段。
  2. 在目錄中建立名為 404_3.htm 的 c:\inetpub\custerr\en-us 檔案。
  3. 在您 c:\inetpub\wwwroot 目錄中建立名為 test.yyyy 的檔案。
  4. 現在要求 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 伺服器的安全性。 許多組態選項可協助您自訂自訂使用者的體驗。 最重要的是:進行實驗是有趣的。

另請參閱