カスタム IIS 7.0 サーバーの構築
公開日: 2007 年 11 月 22 日 (作業者: saad (英語))
更新日: 2008 年 5 月 1 日 (作業者: saad (英語))
はじめに
IIS 6.0 およびそれ以前のバージョンでは、広く使用されているサーバー機能の多くをサーバー自体の内部に実装していました。 これとは対照的に、IIS 7.0 の Web サーバー エンジンにはモジュール化されたアーキテクチャが用意されており、このアーキテクチャ上ですべてのサーバー機能がプラグイン可能なコンポーネントとして提供されます。 これによって、次のように、あらゆる面で機能が大幅に向上します。
- サーバーに読み込んで使用する機能セットを厳格に管理し、不要な機能を削除してサーバー上の攻撃にさらされる領域やメモリ フットプリントを減らすことができます。
- 各機能をサード パーティの実装やカスタム実装に置き換えることができます。
- サーバー トポロジにおけるサーバーの役割に応じて、サーバーの役割を特化させることができます。
- サーバーの機能セットを、詳細なレベルおよびアプリケーションの委任可能なレベルで細かく管理できます。
モジュールと呼ばれるこれらのサーバー コンポーネントは、アプリケーション プール ワーカー プロセスの初期化時に読み込まれ、サーバー上で要求処理サービスを提供します。 各 IIS 7.0 アプリケーションは、アプリケーションで有効になっているモジュールが提供するサービスの組み合わせであり、これらのサービスで使用されるコンテンツに関連付けられます。 サーバーは、モジュールを通じて 2 つの大きな役割を果たします。
- 認証や出力キャッシュなどの要求サービスを提供します (IIS 6.0 の ISAPI フィルターに類似する機能)。
- 静的ファイルの処理、CGI、ASP.NET ページの処理などの要求の処理を提供します (IIS 6.0 の ISAPI 拡張機能に類似する機能)。
モジュールをさまざまに組み合わせて有効にすることで、サーバーのアプリケーションで必要なサービスを提供できるようにサーバーを構成できます。
ここでは、次のようなタスクについて説明します。
- サーバーの構成、既定の設定、および既定でサーバーに読み込まれるモジュールのセットを確認する
- すべてのモジュールを削除して、サーバーの最小限の構成にし、フットプリントに対する効果を調査する
- モジュールを徐々に追加して特定のシナリオをサポートするカスタム サーバーを構築する
この記事の内容:
既定のモジュール構成の確認
サーバーのフットプリントの調査
サーバーのスリム化
カスタム サーバーの構築
まとめ
既定のモジュール構成の確認
サーバーの主要な構成は、IIS 7.0 構成ディレクトリ (%windir%\system32\inetsrv\config\) にある applicationHost.config ファイルに格納されています。 ここでは、<system.webServer> セクション グループに含まれている次の構成について見ていきます。
<globalModules> セクション。 このサーバー レベルのセクションには、サーバー ワーカー プロセスによって読み込まれるモジュールの一覧、およびその機能を実装する関連ネイティブ DLL が格納されます。
<modules> セクション。 このアプリケーション レベルのセクションには、特定のアプリケーションについて有効になっているモジュールの一覧が格納されます。 このセクションは、読み込まれているモジュールの中で、アプリケーションでアクティブになっている必要があるサブセットを選択したり、追加のアプリケーション レベルのモジュールを読み込んだりするために使用されます。
<handlers> セクション。 この URL レベルのセクションには、受信した要求を、それを処理するモジュールにマップするためにサーバーが使用するハンドラー マッピングが格納されます。 これは IIS 6.0 のスクリプトマップや ASP.NET に似ており、ネイティブ コンテンツ ハンドラーとマネージ コンテンツ ハンドラーの両方に対して、統一された要求マッピングを提供します。
すべての IIS 7.0 モジュールの詳細については、「IIS 7.0 のモジュールの概要」を参照してください。
構成のバックアップの作成
最初に、復元が必要な場合に備えて、サーバーの構成をバックアップします。 管理者としてコマンド プロンプトを起動し、次のコマンドを実行します。
%windir%\system32\inetsrv\appcmd add backup initial
これで、次のコマンドを実行することによって、サーバーの構成を初期状態に戻すことができます。
%windir%\system32\inetsrv\appcmd restore backup initial
既定のモジュール一覧の確認
<system.webServer>/<globalModules> セクションに移動します。 サーバー レベルでのみ構成できるこのセクションには、各サーバー ワーカー プロセスによって読み込まれるモジュールが含まれます。 各エントリは、モジュールの名前と、モジュールの機能を実装する DLL を設定します。
<globalModules>
<!--several modules omitted -->
<add name="BasicAuthenticationModule" image="'\authbas.dll" />
<add name="WindowsAuthenticationModule" image="'\authsspi.dll" />
</globalModules>
既定のサーバー構成のさまざまなモジュールの名前を見ると、IIS 6.0 のサーバーの一部として見慣れたサービスも含まれています。
Windows 認証モジュール (NTLM 要求の認証)
<add name="WindowsAuthenticationModule" image="'\authsspi.dll" />
静的ファイルハンドラー モジュール (静的ファイルの提供)
<add name="StaticFileModule" image="'\static.dll" />
動的圧縮モジュール (応答の圧縮)
<add name="DynamicCompressionModule" image="'\compdyn.dll" />
<system.webServer>/<modules> セクションに移動します。 サーバー レベルまたはアプリケーション レベルで構成できるこのセクションでは、<globalModules> セクションで読み込まれたモジュールの中から、特定のアプリケーションで有効にするモジュールを指定します。 このセクションの大部分は、前のセクションと同じモジュール名で占められます。モジュールは、既定ですべてのアプリケーションで有効になります。
注: 一覧の最後には、さらに項目がいくつかあります。これらは、ASP.NET 拡張機能モデルを使用して開発されたマネージ モジュールです。 マネージ モジュールの構築の詳細については、「.NET を使用したモジュールの開発 (英語)」のウォークスルーを参照してください。
<system.webServer>/<handlers> セクションに移動します。 サーバー、アプリケーション、または URL レベルで構成できるこのセクションでは、要求の処理方法を指定します。 モジュールは通常、すべての要求で使用されますが、ハンドラーは特定の URL に対する要求のみを取得します。
モジュールの典型的な例が圧縮モジュールです。 圧縮モジュールはすべての応答を監視し、必要に応じて応答を圧縮します。 ASP.NET ページ ハンドラーはハンドラーの典型的な例です。 このハンドラーは、ハンドラーに対してマップされている要求のみを受信します (例: 拡張子が .aspx の要求)。 <handlers> の一覧では、URL や動詞に基づく要求と、この要求を処理するために使用される処理モジュールとのマッピングが定義されます。各マッピングを構成するために使用される追加情報も示されますが、ここでは説明しません。
<handlers>
<!-- certain details omitted -->
<add name="CGI-exe" path="*.exe" verb="*" modules="CgiModule" ... />
<add name="ISAPI-dll" path="*.dll" verb="*" modules="IsapiModule" ... />
<add name="ASPClassic" path="*.asp" verb="GET,HEAD,POST" modules="IsapiModule" ... />
</handlers>
サーバーのフットプリントの調査
1. Internet Explorer を開いて次の URL を指定し、Enter キーを押してサーバーに対して要求を送信します。
https://localhost/iisstart.htm
これによって、サーバー アプリケーション プールが起動し、iisstart.htm ドキュメントが提供されます。
2. タスク マネージャーを起動し、[プロセス] タブをクリックします。 IIS 7.0 ワーカー プロセスは別のユーザー アカウントで実行されているので、[全ユーザーのプロセスを表示する] チェック ボックスをオンにする必要があります。 w3wp.exe サーバー ワーカー プロセスのサイズに注目してください。
図 1: タスク マネージャーでの IIS ワーカー プロセスの表示
3. ここで、次のコマンド ラインを実行します。
TASKLIST /fi "imagename eq w3wp.exe" /m
このワーカー プロセスによって、90 個以上の DLL が読み込まれていることがわかります。 そのほとんどは \intersrv\ ディレクトリにあります。DLL の多くは最初のタスクの <globalModules> セクションで見たモジュール DLL であり、その他のいくつかは .NET Framework およびサーバー ランタイム自体をサポートするものです。
サーバーのスリム化
前のタスクでは、サーバーに読み込まれる既定のコンポーネントの一覧を調べました。この一覧には、認証から静的ファイルの提供まで、さまざまなサービスを提供する 35 を超えるモジュールが含まれていました。 サーバーに読み込まれている各コンポーネントは、サーバーのフットプリント、攻撃にさらされる領域、ランタイムのパフォーマンス、および有効な機能設定に影響します。
次のタスクで必要な機能のみ搭載したカスタム サーバーを構築する前に、まず、すべてのモジュールを削除して空のサーバーを起動し、高速で、小規模な、セキュリティで保護された Web サーバーを構築します。
前のタスクで applicationHost.config ファイルを変更した場合は、コマンド ラインから %windir%\system32\inetsrv\appcmd restore backup initial を実行することで、元の状態に戻すことができます。
それでは、サーバーのスリム化の作業を始めます。
1. テキスト エディターを使用して、%windir%\system32\inetsrv\config\applicationHost.config を開きます。
2. <system.webServer>/<globalModules> セクションに移動します。
3. コレクション内のエントリをすべて切り取り、空のセクション定義だけを残します。
<globalModules> <!—Remove Everything --> </globalModules>
4. 後で使用するために、切り取ったアイテムを空白のメモ帳ウィンドウに貼り付けます。 <system.webServer>/<modules> セクションについても同じ手順を繰り返します。このセクション内のエントリをすべて切り取り、後で使用するために、空白のメモ帳に貼り付けます。これによって、読み込まないモジュールが有効にならないようにします。 後で使用するために、切り取ったアイテムを空白のメモ帳ウィンドウに貼り付けます。
5. <system.webServer>/<handlers> セクションについても同じ手順を繰り返します。このセクション内のエントリをすべて切り取り、無効にしたモジュールに対してハンドラー マッピングを指定しないようにします。 後で使用するために、切り取ったアイテムを空白のメモ帳に貼り付けます。 applicationHost.config ファイルを保存して、変更内容を有効にします。
スリム化したサーバーのフットプリントの調査
これで、スリム化したサーバーを読み込む準備ができました。以前と同じ手順を繰り返して、サーバーの新しいフットプリントを調べます。
1. Internet Explorer を開いて次の URL を指定し、Enter キーを押してサーバーに対して要求を送信します。
https://localhost/iisstart.htm
これによってサーバー アプリケーション プールが起動しますが、要求されたリソースを提供するハンドラーが登録されていないのでブラウザーにエラーが返されます。
2. タスク マネージャーを実行して、[プロセス] タブをクリックします。 w3wp.exe サーバー ワーカー プロセスのサイズに注目してください。
3. 次のコマンド ラインを実行します。
TASKLIST /fi "imagename eq w3wp.exe" /m
サーバーのフットプリントが約 8 MB まで削減されたことを確認します。 サーバーのタイムフレームでは、空のサーバーのフットプリントはさらに削減されます。
読み込まれる DLL の数は、90 個以上あったのが 50 個に減ります。これは、モジュール DLL がサーバーにまったく読み込まれていないことを意味します。DLL 数が違うのは、これが直接的/間接的な原因です。 サーバー上のサービスが無効になっているだけではなく、これらの機能のコードもプロセスに読み込まれていません。 最適化を行うと、空のサーバーの DLL 数は大幅に減ります。
次のタスクでは、必要な機能のみ搭載したカスタム サーバーを構築します。
カスタム サーバーの構築
前のタスクでは、サーバーを最小限の構成までスリム化し、コア サーバー エンジンのみ実行して、追加モジュールは読み込まれないようにしました。 ここでは、企業ネットワーク上の Web ファイル サーバーとして使用するカスタム サーバーを構築します。 これを行うにあたって、サーバーでは次のサービスのみを有効にします。
- 静的ファイルを提供する
- ディレクトリ一覧を提供する
- 基本認証と URL ベースの承認規則によってコンテンツを保護する
サーバーが静的ファイルを提供できるようにする
このタスクでは、前のタスクに従って、実行していたすべてのモジュールを削除し、サーバーのスリム化を行っていることを前提としています。 この状態のサーバーは、すべての要求に対して、常に空の 401 エラー応答を返します。これは、どのような要求処理を提供するモジュールも読み込まれていないためです。
1. テキスト エディターを使用して、%windir%\system32\inetsrv\config\applicationHost.config を開きます。
2. <system.webServer>/<globalModules> セクションに移動します。 次の太字の 2 行をコレクションに追加します。前に既定のコレクション アイテムを保存するために使用したメモ帳のファイルからコピーします。 これによって、静的ファイルの要求を処理する静的ファイル ハンドラー モジュールと、要求に対して既定の認証トークンを生成する匿名認証モジュールが読み込まれます。
<globalModules>
<add name="StaticFileModule" image="%windir%\System32\inetsrv\static.dll" />
<add name="AnonymousAuthenticationModule" image="%windir%\System32\inetsrv\authanon.dll" />
</globalModules>
3. <system.webServer>/<modules> セクションに移動します。 次の太字の行を追加することによって、静的ファイル ハンドラー モジュールと匿名認証モジュールを有効にします。
<modules>
<add name="AnonymousAuthenticationModule" />
<add name="StaticFileModule" />
</modules>
4. <system.webServer>/<handlers> セクションに移動します。 次の太字の行を追加することによって、静的ファイル ハンドラー モジュールをすべてのファイル要求にマップします。
<handlers>
<add name="StaticFile" path="*" verb="GET,HEAD" modules="StaticFileModule" resourceType="Either" requireAccess="Read"/>
</handlers>
5. applicationHost.config ファイルを保存します。
6. Internet Explorer を開き、次の URL に対して要求を送信します。
https://localhost/iisstart.htm
要求されたドキュメントが提供されます。 これで、サーバー上で静的ファイルを提供する機能が有効になりました。
6. 次に、次の URL に対して要求を送信して、ディレクトリ一覧を要求します。
https://localhost
現在はディレクトリ一覧を処理するハンドラーの読み込み、有効化、およびマッピングが行われていないので、空の応答 (200 OK) が送信されます。 次のタスクでは、このハンドラーを追加します。
サーバーがディレクトリ一覧を提供できるようにする
このタスクでは、前のタスクを実行して、サーバーをスリム化した後、ファイルの提供機能を追加してあることを前提としています。
1. テキスト エディターを使用して、%windir%\system32\inetsrv\config\applicationHost.config を開きます。
2. 前と同様に、次の構成を追加して、ディレクトリ参照モジュールを有効にし、マッピングを行ってディレクトリ要求を処理できるようにします。前の手順に続けてこの手順を実行した後の構成は、次に示すとおりになります。
<globalModules>
<add name="AnonymousAuthenticationModule" image="%windir%\system32\inetsrv\authanon.dll" />
<add name="StaticFileModule" image="%windir%\system32\inetsrv\static.dll" />
<add name="DirectoryListingModule" image="%windir%\System32\inetsrv\dirlist.dll" />
</globalModules>
<modules>
<add name="AnonymousAuthenticationModule" />
<add name="StaticFileModule" />
<add name="DirectoryListingModule" />
</modules>
<handlers>
<add name="StaticFile" path="*" verb="GET,HEAD" modules="StaticFileModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
</handlers>
これで、サーバー上でのディレクトリ一覧機能が有効になりました。 ただし、この機能には、セキュリティ上の理由から、ディレクトリ一覧表示が許可されているかどうかを制御する追加の構成があります。 この構成は、<system.webServer>/<directoryBrowse> セクションで指定します。
3. このエントリを次のように変更します。
<directoryBrowse enabled="true" />
4. applicationHost.config ファイルを保存します。
5. Internet Explorer を開き、もう一度次の URL に対して要求を送信して、ディレクトリ一覧を要求します。
https://localhost
要求したディレクトリの一覧が表示されます。これで、サーバー上でディレクトリ一覧機能が有効になりました。
次に、認証サービスと承認サービスを追加して、不正なアクセスからサーバー上のコンテンツを保護します。
URL 承認によってリソースを保護する
このタスクでは、前のタスクを実行して、サーバーをスリム化した後、ファイルの提供機能とディレクトリ一覧機能を追加してあることを前提としています。
1. テキスト エディターを使用して、%windir%\system32\inetsrv\config\applicationHost.config を開きます。
2. 今回は、次の 2 つのモジュールを追加します。
- 基本認証モジュール。このモジュールは、http 1.1 上でサーバーの Windows 資格情報に対して、基本認証スキームをサポートします。
- URL 承認モジュール。このモジュールは、ユーザーと役割ルールに基づくアクセス制御をサポートします。
3. これらのモジュールを追加するには、<system.webServer>/<globalModules> セクションにモジュール読み込みエントリを追加し、<system.webServer>/<modules> セクションでそのモジュールを有効にします。これは、前に静的ファイル ハンドラーやディレクトリ ブラウザーで行った手順と同じです。
注: 今回は、<system.webServer>/<handlers> セクションに何も追加する必要はありません。これらのモジュールは要求の処理を行わず、すべての要求に対して要求サービスを提供するだけだからです。 次の太字のアイテムを追加した後、最終的な構成は次のようになります。
<globalModules>
<add name="AnonymousAuthenticationModule" image="%windir%\system32\inetsrv\authanon.dll" />
<add name="StaticFileModule" image="%windir%\system32\inetsrv\static.dll" />
<add name="DirectoryListingModule" image="%windir%\system32\inetsrv\dirlist.dll" />
<add name="UrlAuthorizationModule" image="%windir%\System32\inetsrv\urlauthz.dll" /> <add name="BasicAuthenticationModule" image="%windir%\System32\inetsrv\authbas.dll" />
</globalModules>
<modules>
<add name="AnonymousAuthenticationModule" />
<add name="StaticFileModule" />
<add name="DirectoryListingModule" />
<add name="BasicAuthenticationModule" />
<add name="UrlAuthorizationModule" />
</modules>
追加した機能を使用するには、構成を行う必要があります。
4. 基本認証サービスを有効にします。 <basicAuthentication> 要素に移動し、enabled 属性を true に設定します。
<basicAuthentication enabled="true" />
5. 匿名認証を無効にします。 <anonymousAuthentication> 要素に移動し、enabled 属性を false に設定します。
<anonymousAuthentication enabled="false" userName="IUSR" />
これによって匿名認証は無効になります。アクセスを許可するにあたって、ユーザーを正しく認証するために、基本認証モジュールが必要です。
7. applicationHost.config ファイルを保存します。
8. Internet Explorer を開き、もう一度次の URL に対して要求を送信して、ディレクトリ一覧を要求します。
https://localhost
ディレクトリ一覧が要求されます。 ブラウザーで認証が行われないので、URL 承認モジュールで要求が拒否されます。 基本認証モジュールはこの拒否応答をインターセプトし、ブラウザーに対して基本認証チャレンジをトリガーします。これにより、ブラウザーに基本認証ログイン ダイアログ ボックスが表示されます。
9. 無効な資格情報を使用してログインします。 要求は拒否され、もう一度資格情報を入力するよう求められます。
10. コンピューターにログインするときに使用した管理者アカウントを使用してログインします。 ディレクトリ一覧が表示され、サーバーに認証機能および承認機能が正しく追加されたことがわかります。
まとめ
この記事では、サーバーのコンポーネント化について紹介し、用意されている IIS の機能を確認し、ユーザーが必要とするサービスのみを搭載したカスタム Web サーバーを構築する方法を説明しました。
再びサーバーを使用する前に、このウォークスルーで行ったサーバーの構成に対する変更を元に戻します。 バックアップを作成してある場合は、コマンド ラインから %windir%\system32\inetsrv\appcmd restore backup initial を実行することによって構成を復元できます。
関連リンク
詳細情報については、以下のリンクをご覧ください。
- IIS 7.0 コア アーキテクチャの詳細については、IIS.NET の「Server Core での IIS 7.0」を参照してください。
- IIS 7.0 のモジュールの詳細については、「IIS 7.0 のモジュールの概要」を参照してください。
- IIS 7.0 の機能を拡張または置換するモジュールの構築の詳細については、「.NET を使用したモジュールの開発 (英語)」および「ネイティブ (C/C++) モジュールの開発」を参照してください。