IIS 7.0 で HTTP 詳細エラーを使用する方法

作成者: IIS チーム

はじめに

Web サイト管理者や Web 開発者は誰でも、ブラウザーで "404 - ファイルが見つかりません"、"401 - 権限がありません"、"500 - サーバー エラー" というメッセージを見たことがあります。 この記事を読むと、IIS がこれらのエラーをなぜ、どのように生成するかを理解でき、またそれらの構成方法も理解できます。

多くの人は、エラー メッセージを生成するだけでは完全な記事にならないと思うかもしれません。 しかし、エラーには見かけ以上のものがあります。 エラー メッセージはデリケートなトピックです。すべてのエラーによって、Web サイトについて、自分が明らかにしたいと思う以上のことが明らかになってしまうからです。 サイトについて誰かが収集できる情報が多ければ多いほど、そのサイトはハッキングされる可能性も高くなります。 "google ハッキング" や "クロスサイト スクリプティング" を検索すると、このトピックに関する豊富な情報が見つかります。

ただし、エラー メッセージは、問題のトラブルシューティングを行うための貴重なツールでもあります。 開発者および Web サイト 管理者は、エラーが発生したとき、できるだけ多くの詳細情報が必要になります。 エラー メッセージによって、問題の解決方法に関する推奨事項が示されるのが理想的です。 ここでは、IIS がこれらの根本的に相反する目標にどのように対処するかを説明します。

エラーの種類

この記事では、HTTP RFC (RFC 2616 - セクション 6.1.1) で指定されている HTTP エラーについて説明します。 HTTP エラーは常に、状態コードが 400 を超える応答を要求元のクライアントに送り返すことによって表現されます。

クライアント エラー

状態コード 400 から 500 は、不適切な構文や存在しないリソースへの要求など、クライアントで発生したエラーを示します。 これを試すには、任意の Web サイトから架空の URL (例: http://<IIS7Server>/this_resource_does_not_exist) を要求します。 これにより、"404 - ファイルが見つかりません" エラーが発生します。

サーバー エラー

500 で始まる状態コードは、サーバーで発生したエラーです。 IIS システムで 500 エラーが発生する最も一般的な原因は次のとおりです。

  • 構文エラーが含まれる ASP または ASPX ページ
  • Web サーバー構成またはアプリケーション構成を読み取ることができない、またはこれらが無効
  • サイトが停止している

IE などのブラウザーでは、多くの場合、Web サーバーから返されたエラーが独自のエラーに置き換えられるので注意してください。 これにより、トラブルシューティングが困難になります。 IE では、この機能をオフにできます。 [ツール] メニューに移動し、[インターネット オプション] を選択し、[詳細設定] タブをクリックし、[HTTP エラー メッセージを簡易表示する] チェック ボックスを見つけてチェックを解除します。 未加工の応答を表示するには、IIS 6.0 リソース キットの WFETCH などの HTTP ツールを使用します (「関連リンク」を参照)。

IIS の HTTP エラー

httpError モジュール (custerr.dll) でエラーが発生した場合に実行される可能性があるのは、次の 2 つです。

  • カスタム エラーが生成される
  • 詳細エラーが生成される

カスタム エラーは、Web サイトの通常のユーザーに表示されるエラー ページです。 これには、エラーが発生した理由の簡単な説明が含まれますが、それ以外は何も含まれません。 存在しないリソースを要求したときに生成されるカスタム エラーを次に示します (例: http://<IIS7Server>/this_resource_does_not_exist)。

Screenshot of the the H T T P Error 404 file or directory not found webpage in Internet Explorer.

詳細エラーは、ローカル管理者と開発者を対象としています。 これらは、問題を直ちに解決するのに役立つ情報を提供します。 以下では同じ要求の例を使用していますが、詳細エラーが返されています。

Screenshot of the Server Error in Default Web Site Application webpage, showing a Cause and Solution section for the error.

詳細エラーには Web サイトの内部動作に関する情報が含まれるため、これは危険です。 詳細エラーは、信頼できる担当者にのみ表示する必要があります。 これを確実に行う唯一の方法は、要求がローカル マシンから送信された場合にのみ詳細エラーを生成するという方法です。 要求がローカルでない場合、直ちにカスタム エラーが生成されるようにします。 次のフロー図をご覧ください。

Diagram of the Status Substatus, Entity Body, and Set Error's path of creating a detailed error.

Data Flow

1: エラー チェック

httpError モジュールは、応答が送信される場合に通知を受け取ります (RQ_SEND_RESPONSE 通知)。 httpError モジュールは、この応答の状態コードをチェックし、状態コードが 400 を超えない場合は直ちにリターンします。

2: カスタム エラーまたは詳細エラー

次のチェックは、要求の送信元 (要求がローカル要求であるかリモート要求であるか) と errorMode プロパティの設定によって決まります。 errorMode プロパティが DetailedLocalOnly に設定されていると、すべてのリモート要求に対してカスタム エラーが生成されます。 errorMode が "Custom" に設定されていると、すべてのエラー応答がカスタム エラーになります。 errorMode が "Detailed" に設定されていると、すべてのエラー応答が詳細エラーになります。 この動作を次の表に示します。

errorMode 要求の送信元 アクション
DetailedLocalOnly (既定値) ローカル 詳細なエラー
DetailedLocalOnly (既定値) Remote カスタム エラー
Custom ローカル カスタム エラー
Custom Remote カスタム エラー
詳細 ローカル 詳細なエラー
詳細 Remote 詳細なエラー

httpError モジュールは、カスタム エラーを生成する必要があると判断した場合、その構成を調べて、一致するエラーが見つかるかどうかを確認します。 一致が見つかった場合、静的ファイルを送信するか、要求をリダイレクトするか、指定された URL を実行します。 一致が見つからない場合、IIS は状態コードを含む基本的な 1 行のメッセージを送信します。 次のセクションでは、カスタム エラーの構成について詳しく説明します。

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 という名前のファイルを返します。

サブ状態コード

多くの 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 セグメント (2 つのスラッシュの間の文字) を拒否しました。
404.9 IIS が隠しファイルの提供を拒否しました。
404.11 要求フィルター モジュールが、二重にエスケープされた要求を拒否しました。
404.12 要求フィルター モジュールが、ハイビット文字を含む要求を拒否しました。
404.14 要求フィルター モジュールが、URL が長すぎる要求を拒否しました。
404.15 要求フィルター モジュールが、クエリ文字列が長すぎる要求を拒否しました。
413.1 要求フィルター モジュールが、長すぎる要求 (要求 + エンティティ本体) を拒否しました。
431 要求フィルター モジュールが、長すぎるヘッダーを拒否しました。

特定のサブ状態コードのカスタム エラーを表示するように httpErrors セクションを構成できます。 httpErrors 構成セクションに次の行を追加すると、IIS MimeMap (<staticContent> 構成セクション) に含まれていないファイル拡張子を持つファイルが要求された場合、IIS は 404_3.htm を返します。

<error statusCode="404" subStatusCode="3" prefixLanguageFilePath="c:\inetpub\custerr" path="404_3.htm" />

この例を実際に試す方法を次に示します。

  1. 上記のエントリを httpErrors 構成セクションに追加します。
  2. c:\inetpub\custerr\en-us ディレクトリに 404_3.htm という名前のファイルを作成します。
  3. c:\inetpub\wwwroot ディレクトリに test.yyy という名前のファイルを作成します。
  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 Language Pack for German をインストールする必要があります。 これにより、カスタム エラー ファイルを含む c:\inetpub\custerr\de-DE ディレクトリが作成されます。 これで、ブラウザーが "de-DE" という値の "Accept-Language" ヘッダーを送信すると、返されるファイルは c:\inetpub\custerr\de-DE\404.htm になります。

ディレクトリ "de-DE" が存在しない場合、IIS は常にシステム言語にフォールバックします。

Note

Internet Explorer では、Accept-Language ヘッダーを構成できます。 [ツール] - [インターネット オプション] に移動し、[全般] タブを選択し、[言語] ボタンをクリックします。

カスタム エラーのオプション

上記の例では、IIS はカスタム エラー応答としてファイルの内容を送信します。 IIS には、エラーに応答する方法が他に 2 つあります。URL を実行する方法と要求をリダイレクトする方法です。

ExecuteUrl

電子メールの送信やデータベースへのエラーの記録など、カスタム エラーでさらに多くのことを行いたい場合、URL を実行できます。 これにより、ASP.NET ページなどの動的コンテンツを実行できます。 次の例は、404 カスタム エラーを置き換えます。 これにより、IIS は、404 エラーが発生するたびに /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 が同じアプリケーション プールにある場合にのみその 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 サーバーのセキュリティを損なうことなく、問題のトラブルシューティングを行うのに役立ちます。 多くの構成オプションは、ユーザーのエクスペリエンスをカスタマイズするのに役立ちます。 最も重要なのは、このようなことを試すのが楽しいという点です。

関連項目