次の方法で共有


IIS 6.0 と IIS 7 以降の間のセキュリティの変更

作成者: IIS チーム

はじめに

IIS 7 以降では、IIS 6.0 に対して多数のセキュリティが新たに強化されています。 このドキュメントでは、認証、認可、SSL、Web サービス拡張機能の制限一覧、IP 制限に関するこれらの機能強化の概要を説明します。

認証

ASP.NET アプリケーション開発者にとって、IIS 7 以前は、2 つの認証モデルに対してプログラミングする必要がありました。 これらのモデルは、IIS と ASP.NET パイプラインです。 最初に IIS が要求を調べて認証ルーチンを実行し、その後、それを ASP.NET が同様のタスクを実行できるように渡します。

IIS 7 以降では、これら 2 つのモデルが統合され、両方の古いモデルで行っていた処理を最適に行う、新しい堅牢なパイプラインが登場しています。 IIS では引き続きすべての古い認証プロトコルがサポートされますが、フォーム認証もサポートされるようになりました。これは、すべてのコンテンツ タイプに対して保護でき、Windows アカウントに依存しません。 また、ユーザーが理解して慣れてきていたすべての古い機能のサポートに加え、匿名認証機能など、そのいくつかを強化しています。

これらの変更について、この後のセクションで説明します。

匿名認証の変更

IIS 7 以降で、匿名認証は以前のバージョンと同様の方法で動作しますが、1 つだけ変更されたのはワーカー プロセス ID の内容で実行できることです。 各アプリケーション プールは、ユーザー アカウントの内容で実行するように構成され、このアカウントの既定値は NETWORKSERVICE です。

ASP.NET アプリケーションでは、web.config ファイルで次のコードを使用することで、偽装を無効にして、アプリケーション プール ID で実行するのが非常に一般的でした。

<identity impersonate="false"/>

アプリケーションをプロセス ID のコンテキストで実行する必要があるシナリオがいくつかあります。

  • プロセス ID が低い特権アカウントで、管理者がそのアカウントのシステムをロックダウンしている
  • プロセス ID にネットワーク アクセスが許可され、データベースなどのバックエンド リソースへのアクセスに使用される

IIS 7 以降の再設計の一環として、このシナリオを安全かつ簡単に行えるようにしたいと考えていました。 このシナリオを実装するための IIS 要件は次のとおりです。

  • 匿名認証モジュールのインストールと有効化
  • 匿名ユーザー名とパスワードに空の文字列を設定

これを行うには、次のように匿名認証の構成を変更します。

<anonymousAuthentication enabled="true" userName="" defaultLogonDomain="" />

この構成により、常にワーカー プロセス ID のコンテキストで実行するように IIS に指示されます。

既定では、IIS 7.0 以降の匿名認証 ID は IUSR アカウントです。 このアカウントは、最小限の権利と特権が含まれる低い特権の ID です。 新しい組み込みアカウントの詳細については、「IIS 7 の組み込みのユーザー アカウントとグループ アカウントについて」の記事を参照してください。

Passport の変更

従来の Passport 認証のサポートは、IIS 5/6 と Windows Server 2000 および 2003 に組み込まれていました。 IIS 5 および 6 での Passport のサポートは、IIS サービス マネージャーの [ディレクトリ セキュリティ] タブ内で [Passport 認証を有効にする] チェックボックスとして示されていました。 このチェックボックスにより、IIS が従来の Tweener プロトコル チャレンジを送信することができました。 これに加えて、IIS 統合が機能するためには、前もって Web サイトを Passport サービス プロビジョニング ポータルに登録し、暗号化キーを取得し、サーバー上で従来の Passport Manager を構成する必要がありました。

Windows Server 2008 以降では、従来の Passport バイナリおよび IIS との統合が削除されました。

その後、Passport サービスは Windows Live ID に変更されました。 新しい Live ID サービスが、従来の Passport サービスから生じたことは確かですが、大きな変更があります。 最も大きな変更の 1 つは、パートナー サイトと Live ID の統合方法です。 一般公開されている Windows Live ID Web 認証 SDK を使用して、Live ID 認証を追加できます。 Windows Live ID サービスでも ID フェデレーションと ADFS がサポートされていますが、この機能は特定ケース向けの新機能であり、"Passport" の代わりではありません。

フォーム認証

フォーム認証は ASP.NET の一部です。これを使用すると、Windows ID と Windows 以外の ID の両方で自身を認証でき、アプリケーションが後で使用できるユーザー オブジェクトを取得できます。 IIS 7 以降ではフォーム認証が完全にサポートされるようになり、すべてのコンテンツ タイプへのアクセスを保護するように構成できます。

IIS 7 以降で認証済み ID を判別する方法

IIS 7 以降では、認証規則は以前のバージョンの IIS と同様の方法でコア エンジンによって処理され、変更はごくわずかです。 処理の順序を理解しやすいように、IIS がそれらを評価する順序の規則を次に示します。

  • まず、IIS は、仮想ディレクトリでユーザー名とパスワードが構成されているかどうかを判断します。 資格情報のセットが定義されている場合は、それらの資格情報が使用されます。 IIS 7 より前の管理者の場合、これらの資格情報は UNC 資格情報です
  • 仮想ディレクトリで資格情報が構成されていない場合、IIS は認証時に指定された資格情報を使用します。 これらの資格情報は、匿名認証用に構成された ID に属することも、認証ハンドシェイク中にユーザーによって提供される資格情報 (基本、ダイジェスト、または Windows 認証が有効になっている場合) に属することもあります。
  • 認証済みユーザーが確立されなかった場合 (フォーム認証が有効な場合など) は、プロセス ID を使用する必要があるかどうかを判断します
  • この時点で ID がない場合、IIS はアクセス拒否を返します

承認

AzMan のサポート

IIS 6.0 には、AZMan ルールに基づく新しい認可モデルが導入されました。 IIS 7 以降では、ASP.NET 認可モデルによく似た新しいモデルを優先して、この機能を非推奨にしました (以下の URL 認可に関するトピックを参照してください)。

URL 認証

IIS 7 以降には、2 つの認可ソリューションがあります。 1 つ目は、ASP.NET 認可モデルを使用することです。 この方法では、<system.web> 構成にすべての認可規則を定義する必要があり、ASP.NET に対して既に規則が記述されているアプリケーションについての変更は必要ありません。 2 つ目のモデルは、新しい IIS 認可アーキテクチャに移行することです。 このモデルは ASP.NET のモデルによく似ていますが、小さない変更がいくつかあります。

  • 規則は順序に依存しません
  • 拒否規則が一覧の先頭に並びます
  • 規則は ASP.NET とは反対の順序、主に祖父母、親、子の順に処理されます。ASP.NET 認可は逆の順序 (子、親、祖父母) で規則を処理します。

ASP.NET 認可モデルと IIS 認可モデルの違いをより深く理解するために、まず ASP.NET 認可構成を見てみましょう。

<authorization>
    <allow users="Vik_Malhotra" />
    <deny roles="administrators" />
    <deny users="*" />
</authorization>

この例では、Vik_Malhotra を許可していますが、それ以外のすべてを拒否しています。 IIS では、構成が非常によく似ています。

<authorization>
    <add accessType="allow" users="Vik_Malhotra" />
    <add accessType="deny" roles="administrators" />
    <add accessType="deny" users="*" />
</authorization>

構文変更の理由は、これら 2 つのモデルが実際に違うことをアプリケーション開発者に認識してもらいたいが、同時に、最小限の労力で 1 つの実装から別の実装にルールを移動できるようにするためです。

SSL

IIS 6.0 では、IIS は SSL 関連情報をメタベースに格納し、SSL ネゴシエーション プロセスの大部分を HTTP.SYS と組み合わせて管理していました。 IIS 7 以降では、この構成の大部分を HTTP.SYS のストアに移行しました。

IIS 6.0 の各構成設定が IIS 7 以降の構成 (すなわち HTTP.SYS 構成) にどのように引き継がれているかを説明するために、次の図を作成しました。

IIS 6.0 のメタベース構成 プロパティの説明 IIS 7.0 以降のアーキテクチャ
AccessSSLFlags AccessSSLFlags は AccessSSL AccessSSL128 AccessSSLNegotiateCert AccessSSLRequireCert AccessSSLMapCert のビットマスクであり、0 値は "SSL がないこと" を意味します。 IIS 7.0 以降の構成の <access> セクションで引き続きサポートされるプロパティ
CertCheckMode CRL (証明書失効リスト) チェックを有効または無効にします。 現在、この値は PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトのhttp.sysに格納されています。
RevocationFreshnessTime RevocationFreshnessTime プロパティが 1 (true) に設定されている場合、証明書クライアントにキャッシュされている CRL が有効であっても、証明書クライアントの証明書失効リスト (CRL) は、リモートの場所からの CRL によって更新されます。 RevocationURLRetrievalTimeout を使用して別のタイムアウト期間 (分単位) を指定しない限り、既定のタイムアウト期間は 1 日です。 現在、この値は PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトのhttp.sysに格納されています。
SecureBindings SecureBindings プロパティに指定される文字列を IIS が使用して、サーバー インスタンスによって使用されるセキュリティで保護されたネットワーク エンドポイントを決定します。 このプロパティは、IIS 7.0 以降の構成では <sites> の <binding> セクションで引き続きサポートされます。. 使用されるプロトコルは、"https" にする必要があります。
SSLAlwaysNegoClientCert SSLAlwaysNegoClientCert プロパティは、SSL クライアント接続ネゴシエーションを制御します。 このプロパティが true に設定されている場合、SSL 接続がネゴシエートされるたびに、サーバーはすぐにクライアント証明書をネゴシエートし、コストのかかる再ネゴシエーションを防ぎます。 SSLAlwaysNegoClientCert を設定すると、クライアント証明書の再ネゴシエーションのデッドロックを排除することにも役立ちます。これが発生する可能性があるのは、再ネゴシエーション要求の受信時にクライアントが大きな要求本文の送信をブロックされたときです。 現在、この値は PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトのhttp.sysに格納されています。
SSLCertHash SSLCertHash プロパティは、使用されている SSL 証明書のハッシュを格納するために使用されます。 現在、この値は PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトのhttp.sysに格納されています。
SslCtlIdentifier SslCtlIdentifier プロパティには、特定の証明書信頼リスト (CTL) を指定する一意の値が含まれています。 CTL を正確に参照するには、SslCtlStoreName と共に使用する必要があります。 現在、この値は PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトのhttp.sysに格納されています。
SslCtlStoreName SslCtlStoreName プロパティには、証明書信頼リスト (CTL) を含む CryptoAPI ストアの名前が含まれています。 CTL を正確に参照するには、SslCtlIdentifier と共に使用する必要があります。 現在、この値は PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトのhttp.sysに格納されています。
SSLStoreName SSLStoreName プロパティは、証明書のキー ペアが存在するストアの名前を格納するために使用されます。 現在、この値は PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトのhttp.sysに格納されています。
SslUseDsMapper SslUseDsMapper プロパティは、IIS が Windows ディレクトリ サービス証明書マッパーと IIS 証明書マッパーのどちらを使用するかを指定します。 SSLUseDSMapper が false に設定されている場合、IIS は IIS 証明書マッパーを使用します。 現在、この値は PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトのhttp.sysに格納されています。

HTTP.SYS PHTTP_SERVICE_CONFIG_SSL_PARAM オブジェクトの詳細については、次のドキュメントを参照してください。

これらの変更はすべて透過的に処理されるため、サーバー管理者として特別な操作を行う必要はありません。IIS によってすべてが処理されます。 以前の IIS 6.0 プロパティ (現在 HTTP.SYS の構成ストア内にある) にアクセスするアプリケーションがあるとしても、ABO マッパー インターフェイスによって正しい値の読み取り/書き込みが保証されるため、アプリケーションは失敗せずに作動し続けます。

Web サービス拡張機能の制限一覧

IIS 7 以降では、この機能の名前が "isapiCgiRestrictionList" に変更されました。ただし、それ以外の動作は IIS 6.0 と同じです。

この変更の理由は、実際の用途を強調するためです。 IIS 6.0 にこの機能が追加されたのは、不正な ISAPI または CGI バイナリを IIS サーバーにコピーして実行が許可されないようにするためでした。 IIS 7 以降のために設計が見直され、次の 2 つのモデルがサポートされています。

  • "クラシック" ISAPI パイプライン
  • 新しい統合パイプライン

"クラシック" ISAPI パイプラインでは、IIS 6.0 の使用時に想定するとおりに引き続きすべてが機能します。 この点を説明するために、ASP.NET が ISAPI モードで実行する際にどのように作動するかを考えてみましょう。 まず、次に示すように、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 アドレスのセットのみを拒否し、一覧にないすべての 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>