IIS 6.0 と IIS 7.0 のセキュリティに関する変更点
公開日: 2007 年 11 月 16 日 (作業者: pharr (英語))
更新日: 2008 年 3 月 11 日 (作業者: pharr (英語))
はじめに
IIS 7.0 では、IIS 6.0 に比べて多くのセキュリティ機能が向上しています。 このドキュメントでは、認証、承認、SSL、Web サービス拡張制限一覧、および IP 制限に関して、強化された機能の概要を説明します。
この記事の内容:
認証
IIS 7.0 で認証された ID を特定する仕組み
承認
SSL
Web サービス拡張制限一覧
IP 制限
認証
IIS 7.0 以前は、ASP.NET アプリケーション開発者がプログラミングしなければならない認証モデルが 2 つありました。 IIS、そして ASP.NET のパイプラインです。 まず、IIS が要求を調べて認証ルーチンを実行した後、ASP.NET に要求を渡して、ASP.NET が同様のタスクを実行できるようにします。
IIS 7.0 では、この 2 つのモデルを統合して、各モデルの最も優れた機能を備えた新しい堅牢なパイプラインが誕生しました。 IIS では古い認証プロトコルをすべて継続的にサポートしていますが、さらに、Windows アカウントに依存せずにすべてのコンテンツ タイプを保護できるフォーム認証のサポートが追加されました。 ユーザーが愛着を持っている古い機能をすべてサポートすることに加えて、匿名認証機能など、一部の古い機能の強化も行っています。
これらの変更点については、以降のセクションで説明します。
匿名認証の変更点
IIS 7.0 の匿名認証の動作は、以前のバージョンでの動作と同様ですが、唯一の変更点として、ワーカー プロセス ID のコンテキストで実行することが可能になっています。 各アプリケーション プールはユーザー アカウントのコンテキストで実行されるように構成されています。このアカウントの既定値は NETWORKSERVICE です。
以前は、web.config ファイルで次のコードを使用することによって、ASP.NET アプリケーションで権限借用を無効にして、アプリケーション プール ID の下で実行することが一般的でした。
<identity impersonate="false"/>
アプリケーションをプロセス ID のコンテキストで実行することが必要になるシナリオはいくつかあります。
- プロセス ID が低い特権のアカウントであり、管理者がそのアカウントに対してシステムをロックダウンしている場合
- ネットワーク アクセスが許可されているプロセス ID を、データベースなどのバックエンド リソースにアクセスするために使用する場合
IIS 7.0 を新しく設計するにあたって、このようなシナリオを安全で使いやすいものにしたいと考えていました。 このシナリオを実装するために、IIS 7.0 で次のような設定が必要です。
- 匿名認証モジュールをインストールして有効にする
- 匿名ユーザー名とパスワードに空の文字列を設定する
このためには、匿名認証の構成を次のように変更します。
<anonymousAuthentication enabled="true" userName="" defaultLogonDomain="" />
この構成によって、IIS は常にワーカー プロセス ID のコンテキストで実行されます。
既定では、IIS 7.0 の匿名認証 ID は IUSR アカウントです。 このアカウントは、最小限の権限と特権を持つ低い特権の ID です。 新しいビルトイン アカウントの詳細については、「IIS 7.0 での組み込みユーザーとグループ アカウントとは」を参照してください。
Passport の変更点
Passport 認証は、Windows Server® 2008 オペレーティング システムではサポートされなくなりました。 Passport を使用していたユーザーは、代替サービスである Active Directory フェデレーション サービス (ADFS) の移行を検討してください。 ADFS の詳細については、こちらのホワイト ペーパーを参照してください。
フォーム認証
フォーム認証は ASP.NET の一部であり、Windows と Windows 以外の両方の ID で認証を行い、ユーザー オブジェクト (アプリケーションで使用) を取得できるようにします。 IIS 7 はフォーム認証を完全にサポートしており、すべてのコンテンツ タイプに対するアクセスを保護するように構成できます。
IIS 7.0 で認証された ID を特定する仕組み
IIS 7.0 の認証規則は、以前のバージョンの IIS と同様にコア エンジンによって処理されますが、小さな変更点がいくつかあります。 処理の順序が理解しやすいように、ここでは、IIS が評価する順序に従って規則を説明します。
- まず、IIS はユーザー名とパスワードが仮想ディレクトリで構成されているかどうかを特定します。 資格情報が既に定義されている場合、その資格情報が使用されます。 IIS 7.0 以前の管理者にとっては、この資格情報は UNC 資格情報に当たります。
- 資格情報が仮想ディレクトリで構成されていない場合、IIS は認証時に提供された資格情報を使用します。 この資格情報は、匿名認証用に構成されている ID に属している情報か、または、基本認証、ダイジェスト認証、Windows 認証が有効になったときに認証ハンドシェイクでユーザーが指定した資格情報です。
- 認証されたユーザーが設定されない場合 (たとえば、フォーム認証が有効である場合)、プロセス ID を使用するべきかどうかを判断します。
- 現時点で ID がない場合は、IIS はアクセス拒否を返します。
承認
AzMan サポート
IIS 6.0 において、AZMan 規則に基づく新しい承認モデルが導入されました。 IIS 7.0 では、この機能を廃止し、ASP.NET 承認モデルによく似た新しいモデルに置き換えました (後出の「URL 承認モデル」を参照)。
URL 承認
IIS 7.0 には、2 つの承認ソリューションがあります。 1 つは ASP.NET 承認モデルを使用するものです。 この方法では、<system.web> 構成ですべての承認規則を定義しておく必要があり、既に ASP.NET 用の規則が作成されているアプリケーションについては変更は不要です。 もう 1 つのモデルは、新しい IIS 7.0 承認アーキテクチャへの移行です。 このモデルは ASP.NET のモデルによく似ていますが、いくつかの 小さな変更点があります。
- 規則は順序に依存しません。
- 拒否規則はリストの先頭に並べ替えられます。
- 規則は ASP.NET とは逆の順序で処理され、親の親、親、子の順になります (ASP.NET の承認では、子、親、親の親という逆の順序で規則が処理されます)。
ASP.NET と IIS 7.0 の承認モデルの違いを理解するために、まず ASP.NET の承認の構成を見てみましょう。
<authorization>
<allow users="Vik_Malhotra" />
<deny roles="administrators" />
<deny users="*" />
</authorization>
この例では、Vik_Malhotra を許可していますが、他のすべてのユーザーを拒否しています。 IIS 7.0 でも、これと似た構文で構成できます。
<authorization>
<add accessType="allow" users="Vik_Malhotra" />
<add accessType="deny" roles="administrators" />
<add accessType="deny" users="*" />
</authorization>
このように構文を変更した理由は、アプリケーション開発者が両モデルの違いを認識できるようにすると同時に、小さな労力で規則の実装を移行できるようにするためです。
SSL
IIS 6.0 では、IIS は SSL 関連情報をメタベースに保存し、SSL ネゴシエーション プロセスの大部分を HTTP.SYS との組み合わせで管理していました。 IIS 7.0 では、この構成の多くを HTTP.SYS のストアに移動しました。
IIS 6.0 の各構成設定の IIS 7.0 の構成 (または HTTP.SYS の構成) への移行状況を確認するには、以下の表を参照してください。
IIS 6.0 メタベースの構成 |
プロパティの説明 |
IIS 7.0 アーキテクチャ |
AccessSSLFlags |
AccessSSLFlags は以下のビットマスクです。 値 0 は SSL なしを意味します。 |
このプロパティは IIS 7.0 の構成でも <access> セクションでサポートされています。 |
CertCheckMode |
CRL (証明書失効リスト) のチェックを有効または無効にします。 |
この値は、http.sys の PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトに格納されます。 |
RevocationFreshnessTime |
RevocationFreshnessTime プロパティが 1 (true) に設定されている場合、証明書クライアントでキャッシュされている証明書失効リスト (CRL) が有効である場合でも、証明書クライアント上の CRL がリモートの場所にある CRL によって更新されます。 既定のタイムアウト間隔は、RevocationURLRetrievalTimeout を使用して別のタイムアウト間隔 (分単位) を指定していない限り、1 日です。 |
この値は、http.sys の PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトに格納されます。 |
SecureBindings |
SecureBindings プロパティは、IIS がサーバー インスタンスで使用するセキュリティで保護されたネットワーク エンドポイントを決定するために使用する文字列を指定します。 |
このプロパティは、引き続き IIS 7.0 の構成の <sites> の <binding> セクションでサポートされます。 プロトコルは "https" を使用します。 |
SSLAlwaysNegoClientCert |
SSLAlwaysNegoClientCert プロパティは、SSL クライアント接続のネゴシエーションを制御します。 このプロパティが true に設定されている場合、SSL 接続がネゴシエートされるたびに、サーバーは即座にクライアント証明書のネゴシエーションを行い、処理負荷のかかる再ネゴシエーションの実行を防止します。 SSLAlwaysNegoClientCert を設定すると、クライアント証明書の再ネゴシエーションのデッドロックを回避するのに役立ちます。このデッドロックは、再ネゴシエーション要求を受信したときに、クライアントでサイズの大きい要求ボディの送信がブロックされる場合に発生する可能性があります。 |
この値は、http.sys の PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトに格納されます。 |
SSLCertHash |
SSLCertHash プロパティは、使用している SSL 証明書のハッシュを格納するために使用されます。 |
この値は、http.sys の PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトに格納されます。 |
SslCtlIdentifier |
SslCtlIdentifier プロパティには、特定の証明書信頼リスト (CTL) を識別する一意の値が格納されます。SslCtlStoreName と共に使用して、正確に CTL を参照する必要があります。 |
この値は、http.sys の PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトに格納されます。 |
SslCtlStoreName |
SslCtlStoreName プロパティには、証明書信頼リスト (CTL) を格納する CryptoAPI ストアの名前が格納されます。 SslCtlIdentifier と共に使用して、正確に CTL を参照する必要があります。 |
この値は、http.sys の PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトに格納されます。 |
SSLStoreName |
SSLStoreName プロパティは、証明書のキーのペアが保存されているストアの名前を格納するために使用されます。 |
この値は、http.sys の PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトに格納されます。 |
SslUseDsMapper |
SslUseDsMapper プロパティは、IIS が Windows ディレクトリ サービス証明書マッパーを使用するか、IIS 証明書マッパーを使用するかを指定します。 SSLUseDSMapper が false に設定されている場合、IIS は IIS 証明書マッパーを使用します。 |
この値は、http.sys の PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトに格納されます。 |
HTTP.SYS の PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトの詳細については、こちらのドキュメント (英語) を参照してください。
これらのすべての変更は、内部で処理されるので、サーバー管理者が特に作業を行う必要はありません。IIS によって自動的に処理されます。 HTTP.SYS の構成ストアに移動された古い IIS 6.0 のプロパティにアクセスしているアプリケーションがある場合、ABO マッパー インターフェイスによって適切な値が読み書きされるので、アプリケーションは障害が発生することなく正常に動作します。
Web サービス拡張制限一覧
IIS 7.0 では、この機能は若干変更され、名前が "isapiCgiRestrictionList" になっていますが、動作は IIS 6.0 の場合と同様です。
このように名前を変更した理由は、本来の用途を強調することにあります。 IIS 6.0 では、悪質な ISAPI または CGI バイナリが IIS サーバーにコピーされ、実行が許可されないようにするために、この機能が追加されました。 新しい IIS 7.0 の設計では、2 つのモデルをサポートしています。
- "クラシック" ISAPI パイプライン
- 新しい統合パイプライン
"クラシック" ISAPI パイプラインでは、すべての機能が IIS 6.0 を使用した場合と同様に動作します。 わかりやすく説明するために、ISAPI モードで実行されている場合の ASP.NET の動作を考えてみます。 最初に、次に示すように aspnet_isapi.dll への完全なパスを追加して、allowed="true" に設定する必要があります。
<isapiCgiRestriction>
<add path="F:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll"
allowed="true" groupId="ASP.NET v2.0.50727" description="ASP.NET v2.0.50727"
</isapiCgiRestriction>
このようにすることで初めてこのコード (aspnet_isapi.dll) の実行が許可されます。 パイプラインのモードを統合モードに切り替えて、allowed="false" に変更しても、ASP.NET コードは引き続き実行されます。
これは、 isapiCgiRestrictionList が ISAPI および CGI コードにのみ適用されるからです。 統合モードでは、ASP.NET は新しいアーキテクチャの一部となるため、isapiCgiRestrictionList の影響を受けません。 新しい統合パイプラインで ASP.NET コードを実行したくない場合は、モジュールの一覧から managedEngine を削除します。
IP 制限
IP 制限はこれまでととまったく同様に動作します。新たに、"allowUnlisted" という新しいプロパティがサポートされています。 このプロパティの追加によって、グローバル レベルでのシステムのセキュリティ ポリシーを容易に構成できるようになりました。 たとえば、ポリシーで特定の IP アドレスのみを許可し、リストに含まれないアドレスをすべて拒否するように設定するのは、簡単ではありませんでした。 同様に、特定の IP アドレスのみ拒否し、リストには含まれない IP アドレスはすべて許可するという設定も簡単に行えるようになりました。 サーバー管理者はグローバル ポリシーを設定してこの値をロックし、サーバー上でアプリケーション管理者やサイト管理者が変更できないようにすることができます。
わかりやすいように、ユーザーがローカルでのみアクセスできる開発用のコンピューターを考えてみます。 以下の構成では、このポリシーを実装するために、allowUnlisted="false" を設定して、localhost (127.0.0.1) のアクセスのみを明示的に許可しています。
<system.webServer>
<security>
<ipSecurity allowUnlisted="false">
<add ipAddress="127.0.0.1" allowed="true" />
</ipSecurity>
</security>
</system.webServer>