Active Directory
AD LDS のプロキシ認証について理解する
Ken St. Cyr
概要:
- プロキシ認証を定義する
- プロキシ認証が便利な理由
- プロキシ オブジェクトの内部
- 認証中に実行される処理
目次
プロキシ認証とは
プロキシ認証のメリット
プロキシ オブジェクトの内部
実際の認証処理のしくみ
プロキシ認証ラボを構成する
まとめ
Microsoft Active Directory ライト ウェイト ディレクトリ サービス (AD LDS、旧称 ADAM) では、他のすべての LDAP 対応ディレクトリ サービスと同様、ディレクトリに対して LDAP 操作を実行する前に、ユーザーをバインドする必要があります。このバインドは、簡易 LDAP バインド、簡易認証およびセキュリティ層 (SASL) バインド、バインドのリダイレクトなど、いくつかの方法を使用して実行できます。バインドは匿名にすることもでき、その場合、ユーザーは NULL パスワードを指定します。この記事では、特にバインドのリダイレクト、別名プロキシ認証と呼ばれる方法について詳しく説明し、この方法を分析します。
プロキシ認証とは
ユーザーは、プロキシ認証を使用すると、Active Directory アカウントとの関連付けを維持しながら、AD LDS インスタンスへの簡易バインドを実行できます。このトランザクションでは 2 つのアカウントが使用されます。1 つ目は AD LDS の特殊なオブジェクトで、userProxy オブジェクトと呼ばれます。2 つ目は Active Directory 内のユーザー アカウントです。
AD LDS userProxy オブジェクトは、Active Directory アカウントを表します。このプロキシ オブジェクトは Active Directory アカウントのセキュリティ識別子 (SID) を通じて、そのアカウントに関連付けられます。実際のプロキシ オブジェクト自体に格納されるパスワードはありません。
ユーザーがプロキシ オブジェクトを使用して LDS インスタンスへの簡易バインドを実行すると、そのバインドは、SID とパスワードをドメイン コントローラに渡すことによって Active Directory にリダイレクトされます。認証は AD LDS サーバーによって実行され、このプロセスをエンド ユーザーが意識することはありません。図 1 は、このプロセスを表しています。ここでは、Lucy が自分の AD LDS ユーザー アカウントを使用して、AD LDS インスタンス "CN=AppDir,DC=contoso,DC=com" に接続しています。
図 1 AD LDS への接続 (画像をクリックすると拡大表示されます)
Lucy はこの認証に簡易バインドを使用しています。また、通常の LDAP バインドと同様に、自分の識別名 (DN) とパスワードを指定しています。Lucy は自分の通常の LDS ユーザー アカウントに接続しているように見えますが、実際にはプロキシ オブジェクトを使用しています。Active Directory への認証はバックグラウンドで実行されるので、Lucy は、実際には自分の Active Directory アカウントがバインドに使用されていることには気が付きません。
プロキシ認証のメリット
プロキシ認証のメリットは、アプリケーション開発者に、Active Directory アカウントへのアクセスを提供することなくユーザー オブジェクトへのアクセスを提供できることです。たとえば、新しいディレクトリ対応アプリケーションを開発していて、このアプリケーションでデータを Active Directory に格納する必要があるとします。このアプリケーションは、既存の属性を使用することも、新しい属性を作成することもできます。
使用したことがない既存の属性を使用するときに注意する必要があるのは、この属性が別の目的で提供されている可能性があることです。つまり、現在は使用されていなくても、将来使用される可能性があります。この属性が別の目的で使用される場合、Active Directory 管理者はその使用状況を追跡する必要があります。では、アプリケーション開発者が複数の属性を必要とする場合はどうでしょうか。
プロキシ認証を使用する場合、Active Directory ユーザー オブジェクトの表現は AD LDS ディレクトリ内に存在します。アプリケーション開発者は、アプリケーション固有のディレクトリを使用することによって、AD LDS のコンテキスト内でスキーマを自由に変更できます。開発者は任意の方法で属性を追加または変更したり、異なる目的で再利用したりできるので、Active Directory 管理者が何回もスキーマを変更したり、属性の使用状況を追跡することについて心配する必要はありません。別のアプリケーションがオンラインになり、そのアプリケーションで同じ属性を使用する必要があるとしても、問題はありません。これには別の AD LDS インスタンスを使用できるので、属性の競合が発生することはありません。
プロキシ認証は、X.500 形式を必要とする状況でも役立ちます。Active Directory では、DN に一般的な X.500 表記を使用しません。たとえば、Active Directory 内のユーザー オブジェクトには、"CN=Lucy D. Smith,CN=Users,DC=contoso,DC=com" という形式の DN が使用されますが、AD LDS では、X.500 と互換性がある "CN=Lucy D. Smith,CN=Users,O=Contoso,C=US" という形式がユーザーの DN として使用される可能性があります。
これは、サードパーティ製の LDAP クライアントを使用する場合や、X.500 形式を必要とするサードパーティ製のディレクトリとの統合を行う場合に便利です。この場合、LDS をサードパーティ製のディレクトリと Active Directory を仲介するディレクトリとして使用できます。プロキシ認証を使用すると、サードパーティ製のディレクトリが LDS インスタンスへのバインドに使用するサービス アカウントを、LDS 自体ではなく Active Directory 内で保持できます。
プロキシ オブジェクトの内部
ここまでは、LDS プロキシ オブジェクトがどのようにして Active Directory ユーザー アカウントに関連付けられるかについて、簡単に説明しました。このセクションでは、ここまで説明したことをさらに掘り下げ、バックグラウンドでは実際にどのような処理が実行されるかを分析します。まず最初に、オブジェクト クラスについて説明します。
Windows Server 2008 の %SYSTEMROOT%\ADAM ディレクトリ内には、プロキシ オブジェクトを表す次の 2 つの LDF ファイルがあります。
- MS-UserProxy.LDF
- MS-UserProxyFull.LDF
MS-UserProxy.LDF は、簡易 userProxy クラスの定義を保持します。このクラスには、基本属性と msDS-BindProxy 補助型クラスが含まれます。MS-UserProxyFull.LDF にも msDS-BindProxy 補助型クラスが含まれますが、このクラスの mayContain 属性には、追加のユーザー属性が事前に設定されます。このような理由から、あらかじめ属性クラスが存在する必要があります。したがって、userProxyFull クラスをインポートするときは、まずユーザーまたは inetOrgPerson クラスをインポートする必要があります。userProxyFull が使用する属性の属性クラス定義は、ユーザーと inetOrgPerson の両方に含まれます。図 2 は、userProxy クラスと userProxyFull クラスの違いを示しています。
図 2 userProxy クラスと userProxyFull クラス (画像をクリックすると拡大表示されます)
どちらのクラスにも msDS-BindProxy が補助型クラスとして含まれていることは重要です。補助型クラスは、追加のデータを構造型クラスに提供できるクラスの種類です。たとえば、LDS の User クラスは、Organizational-Person クラスから継承される構造型クラスです。つまり、User クラスには Organizational-Person クラスの内容がすべて含まれます。ただし、User クラスには msDS-BindableObject という補助型クラスも含まれるので、User には Organizational-Person クラスの属性に加えて、msDS-BindableObject の必須属性と省略可能な属性がすべて含まれます。ここでは、msDS-BindableObject を補助型クラスとして使用することによって、User クラスをバインドできるようにします。
userProxy クラスには msDS-BindProxy が補助型クラスとして含まれる (図 3 参照) ので、msDS-BindProxy の必須属性と省略可能な属性もすべて含まれます。msDS-BindProxy 補助型クラスは、オブジェクトをプロキシ オブジェクトに変換するクラスです。したがって、カスタム クラスを使用する場合でも、msDS-BindProxy 補助型クラスを追加し、カスタム オブジェクトを使用してプロキシ認証を実行できます。
図 3 プロキシ オブジェクトの作成 (画像をクリックすると拡大表示されます)
msDS-BindProxy クラスを調べると、objectSID という必須属性が 1 つのみ定義されていることがわかります。これは、LDS 内のプロキシ オブジェクトと Active Directory 内のユーザー オブジェクトとの間の関連付けを作成する目的で、Active Directory ユーザー アカウントの SID を格納する属性です。この属性は、オブジェクトの作成時にのみ値を設定できます。値を変更するには、オブジェクトを削除して再作成する必要があります。
実際の認証処理のしくみ
バックグラウンドでどのような処理が実行されるかを正確に理解するには、認証がどのように実行されるかについて、もう少し詳しく見ていく必要があります。ここでは、プロキシ認証のしくみについて理解するのに役立つ、2 種類のネットワーク トレースについて説明します。1 つ目のトレースは、Windows XP ワークステーションから Windows Server 2008 LDS インスタンスへのプロキシ ユーザーの簡易バインドに関するネットワーク キャプチャです。このキャプチャでは、Lucy が自分のワークステーションから LDP.EXE を使用して、自分のプロキシ ユーザー オブジェクトにバインドします。
図 4 は、ここで確認する必要がある、キャプチャ内の 3 つのパケットを示しています。パケット 1 は、ワークステーション (10.0.0.107) から Active Directory LDS サーバー (10.0.0.201) へのバインド要求です。このバインド要求には、Lucy の DN である "cn=lucy,cn=people,cn=appdir,dc=contoso,dc=com" が含まれます。パケット 2 は、Active Directory LDS サーバーからワークステーションへの応答で、バインドが成功したことを示しています。パケット 3 は、ワークステーションから Active Directory LDS サーバーへの受信確認で、バインド応答の受信確認を示しています。
図 4 バインド要求と応答 (画像をクリックすると拡大表示されます)
パケット 1 の内容を詳しく確認すると (図 5 参照)、驚くべきことがわかります。キャプチャ内では、Lucy が指定したパスワード (P@ssw0rd) がクリア テキストで表示されています。実は、これは認証に簡易 LDAP バインドを使用することの短所の 1 つです。バインドが SSL 暗号化によってラップされない限り、ユーザーのパスワードはネットワーク上でリッスンしているすべてのユーザーに知られてしまいます。
図 5 SSL が無効になっている簡易バインド (画像をクリックすると拡大表示されます)
ただし、Active Directory LDS では、SSL が既定で有効になっています。SSL を無効にするには、意図的に設定を変更する必要があります。この演習では、ネットワーク トレースの内容を確認できるように、実際にこの操作を行いました。ここでは、Active Directory LDS サーバーに証明書を割り当てませんでしたが、実際の実装では、SSL に使用できる有効な証明書を Active Directory LDS サーバーに割り当てるようにしてください。
2 つ目のトレースは、Active Directory LDS サーバーからドメイン コントローラ (DC) へのネットワーク キャプチャです。このトレースは 1 つ目のトレースに比べると少し長いので、いくつかに分けて説明します。図 6 は、このトレースの最初の 9 パケットを示しています。
図 6 ドメイン コントローラに接続する AD LDS (画像をクリックすると拡大表示されます)
最初のパケットには見覚えがあると思います。このパケットは、ワークステーションからの受信バインド要求に含まれます。このパケットにも Lucy の DN とパスワードがクリア テキストで格納されています。パケット 2 ~ 9 は AD LDS サーバー (10.0.0.201) からドメイン コントローラ (10.0.0.200) への接続を示しています。これは、いくつかのアドレス解決プロトコル (ARP) メッセージと、DC へのリモート プロシージャ コール (RPC) 接続で構成されます。
図 7 のパケット 10 と 11 では、LsarLookupSids3 というメソッドを呼び出します。これは、DC に一連の SID を取得してそれらに対応する名前を返すことを指示する RPC 呼び出しです。AD LDS サーバーはパケット 10 でこの要求を送信し、パケット 11 で DC からの応答を受信します。
図 7 Kerberos 認証の試行 (画像をクリックすると拡大表示されます)
次に、Kerberos セッションを開始するための短い TCP ハンドシェイクが実行され (パケット 12 ~ 14)、パケット 15 で、AD LDS サーバーが認証サービス チケット (AS-REQ) をキー配布センター (KDC) から取得しようとします。パケット 16 では、この認証サービス チケット要求が拒否されます。これは、DC が事前認証データを必要とし、AD LDS サーバーがこれを提供しなかったからです。ここでは、DC は ID 確認に使用できるタイムスタンプを必要とします。その後、Kerberos セッションが終了し、リセットが要求されます (パケット 17 ~ 19)。
図 8 は、キャプチャの残りの部分を示しています。パケット 20 ~ 22 で新しい Kerberos セッションが確立され、パケット 23 で AD LDS サーバーから DC に新しい認証サービス要求が送信されます。この新しい要求には、必要な事前認証データが含まれるので、パケット 25 で DC から成功応答が返されます。これで AD LDS サーバーは認証サービス チケットを取得し、チケット保証サービスに Lucy の資格情報を認証するよう要求できるようになりました。
図 8 成功した認証 (画像をクリックすると拡大表示されます)
チケット保証サービスの要求と応答は、パケット 33 と 34 でキャプチャされています。パケット 34 での KRB_TGS_REP の受信は、Lucy の認証が成功したことを示しています。最後のパケット 38 では、AD LDS サーバーがバインド応答をワークステーションに渡し、AD LDS インスタンスに無事にバインドされたことを Lucy に通知します。このプロセスにはいくつかの段階がありますが、このトランザクション全体に必要な時間の合計は、わずか 0.1 秒ほどです。
では、Lucy が誤ったパスワードを入力した場合はどうなるでしょうか。この例では、パケット 25 の認証サービス要求が失敗します。この認証サービス要求の失敗により、AD LDS サーバーに Lucy の資格情報が無効であることが通知されます。AD LDS サーバーは、チケット保証サービスの要求を発行せず、バインド応答をワークステーションに返し、資格情報が無効であったことを通知します。
交換が成功した場合のプロセスは、次のとおりです。
- ワークステーションが AD LDS サーバーにバインド要求を送信します。
- AD LDS サーバーが DC との接続を確立します。
- AD LDS サーバーが、Lucy の SID を認証に使用できる ID に変換するよう DC に要求します。
- DC が AD LDS サーバーに Lucy の ID を渡します。
- AD LDS サーバーが、Lucy の ID を使用してチケット保証チケット (TGT) を DC から取得します。
- AD LDS サーバーが、Lucy の TGT を使用して自身へのセッション チケットを取得します。
- AD LDS サーバーが成功のバインド応答をワークステーションに返します。
このプロセスは、ワークステーションから AD LDS サーバーへの接続が、標準の LDAP バインド トランザクションであることを示しています。その後、AD LDS サーバーが DC に対して Kerberos を使用し、セキュリティで保護された状態でユーザーを認証します。
プロキシ認証ラボを構成する
プロキシ認証のしくみを理解できたところで、次はラボ環境でプロキシ認証を構成する方法について説明します。この演習では、プロキシ認証の SSL 要件を無効にします。ただし前述のとおり、実際の実装では、この要件を無効にしないようにしてください。
作業を開始する前に、Windows Server 2008 メンバ サーバーとワークステーションが参加していて、すべての機能が提供されるドメインを用意する必要があります。この Windows Server 2008 メンバ サーバーは AD LDS を実行し、ワークステーションはクライアント エンドポイントとして機能します。これらのコンピュータを分けるメリットは、これらのコンピュータ間の対話をネットワーク キャプチャによって取得できることです。ラボを構成するには、次の手順を実行します。
- メンバ サーバーに AD LDS をインストールします。
- プロキシ認証の SSL 要件を無効にします。
- userProxy クラスを AD LDS スキーマにインポートします。
- プロキシ オブジェクトを作成し、そのオブジェクトにアクセス許可を割り当てます。
- 作成したプロキシ オブジェクトを使用して、AD LDS ディレクトリにバインドします。
まず、Windows Server 2008 メンバ サーバーに AD LDS をインストールします。サーバー マネージャから役割の追加ウィザードを起動し、LDS をインストールするオプションを使用します。AD LDS の役割が追加されると、[Active Directory ライトウェイト ディレクトリ サービス セットアップ ウィザード] という新しいオプションが [管理ツール] メニューに表示されます。このウィザードを使用して、新しい LDS インスタンスを作成します。
アプリケーション パーティションの名前を入力するよう求められたら、任意の DN を入力します。LDS では X.500 名前付け規則がサポートされるので、"DC=" 形式以外の名前も使用できます。この例では "cn=appdir,dc=contoso,dc=com" を使用しますが、"cn=appdir,o=contoso,c=us" を使用することもできます。
AD LDS インスタンスがインストールされたら、次はプロキシ認証の SSL 要件を無効にします。ADSI エディタ スナップイン (adsiedit.msc) から、インストール中に指定した管理者アカウントを使用して、AD LDS インスタンスの構成パーティションに接続します。構成パーティションの DN が不明な場合は、ADSI エディタの [接続の設定] ダイアログ ボックスにある [既知の名前付けコンテキストを選択する] ドロップダウン リストで、[構成] をクリックします。
"CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,CN={guid}" コンテナを参照し、"CN=Directory Service" コンテナのプロパティ ダイアログ ボックスを表示します。複数の文字列を表示する msDS-Other-Settings という属性一覧には、複数値の文字列属性が含まれます。各文字列は、AD LDS インスタンスの設定をそれぞれ示しています。この属性を編集し、文字列 "RequireSecureProxyBind" を値 0 に変更します。
次は、userProxy クラスのスキーマ クラス定義をインポートします。この定義は、AD LDS ウィザードでインポートを要求されたときに、既にインポートしている可能性があります。インポートが完了している場合、この手順は省略してください。まだインポートしていない場合は、次の LDIFDE.EXE コマンドを使用してインポートします。コマンドには、AD LDS サーバーの名前と正しいポートを指定するようにしてください。
C:\> ldifde –i -f c:\windows\adam\ms-userproxy.ldf –s
server:port –k –j . –c
"cn=schema,cn=configuration,dc=X"
#schemaNamingContext
オブジェクト クラスをインポートしたら、プロキシ オブジェクトを作成できます。ここでは LDP.EXE を使用しますが、他のツールや、プログラムによる方法を使用することもできます。LDP を使用して AD LDS インスタンスに接続し、管理者の資格情報を使用してバインドします。AD LDS インスタンスの DN を参照し、プロキシ オブジェクトの作成先となるコンテナを選択します。目的のコンテナを右クリックし、ドロップダウン リストの [子を追加] をクリックします。[追加] ダイアログ ボックスの [DN] フィールドに、新しいプロキシ オブジェクトの DN を入力する必要があります。たとえば、「cn=lucy,cn=appdir,o=contoso,c=us」と入力します。
また、このオブジェクトの 2 つの属性を作成する必要があります。1 つは objectClass で、これは作成するオブジェクトの種類を示します。この例では、値として userProxy を設定します。ダイアログ ボックスの [エントリの編集] セクションにこの情報を入力し、[入力] をクリックします。
2 つ目に追加する属性は objectSID で、この属性にはプロキシ オブジェクトを関連付ける Active Directory ユーザー アカウントの SID が格納されます。この SID はさまざまな方法で取得できますが、ここでは別の LDP インスタンスから Active Directory に接続し、そこで管理されているユーザー アカウントの objectSID 属性をコピーします。この情報を入力すると、[追加] ダイアログ ボックスは図 9 のようになります。最後に [実行] をクリックして変更を確定します。
図 9 プロキシ オブジェクトの作成
上記で作成したプロキシ オブジェクトを使用するには、このオブジェクトにいくつかのアクセス許可を与える必要があります。この作業は簡単で、まず LDP の "CN=Roles" コンテナにある "CN=Readers" オブジェクトを選択します。このオブジェクトを右クリックし、ドロップダウン リストの [変更] をクリックします。member という属性とその値を追加し、作成した userProxy オブジェクトの DN を入力します。[実行] をクリックする前に [入力] をクリックすることを忘れないでください。これで、userProxy オブジェクトが LDS インスタンスの Readers グループのメンバになります。
必要な環境を構成したら、プロキシ認証をテストできます。LDP の新しいインスタンスを開き、AD LDS サーバーに接続します。ただし今回は、インスタンスにバインドするときに [簡易バインド] を選択し、ユーザー名のフィールドにプロキシ オブジェクトの DN を入力します。また、パスワードとして、このプロキシ オブジェクトを関連付けた Active Directory アカウントのパスワードを入力します。[OK] をクリックすると、読み取り専用モードでインスタンスにバインドされます。
ぜひ時間を設けてネットワーク トレースを実行し、他のバインド方法も試してみてください。たとえば、SSL を再度有効にし、LDAP バインド プロセスをキャプチャしてみてもよいでしょう。また、意図的にユーザー名やパスワードを誤入力し、認証プロセスで発生する動作を確認することもできます。
まとめ
プロキシ認証の使用は難しいという警告には耳を貸さないでください。この記事では、バックグラウンドでどのような処理が実行されるかを理解できるように、LDP と ADSI エディタを使用して、このプロセスのデモンストレーションを行いました。この記事の例は、このような目的で、非常に実践的な観点からプロキシ認証のしくみをわかりやすく示しています。
実際には、userProxy オブジェクトを作成してこれらを操作するという面倒なプロセスは、多くの場合、ID 管理システムや独自に開発されたアカウント作成フロント エンドによって体系化されます。ぜひご自分で LDS ラボを構築し、プロキシ認証を使用してサードパーティ製のディレクトリとアプリケーションを統合してみてください。
Ken St. Cyr はマイクロソフトのコンサルタントで、Active Directory の誕生以来、Active Directory ベースのディレクトリ ソリューションを設計および実装してきました。彼は最近、ディレクトリ サービスの Microsoft Certified Master を初めて取得した 1 人となりました。連絡先は、ken.stcyr@microsoft.com (英語のみ) です。