リンク属性の Active Directory は、オブジェクト間の関係を説明するために使用される、特別な種類の Active Directory 属性です。この投稿では、リンク属性とは何か、そしてどのように機能するのかを解説します。
厳選した関連コンテンツ:
属性が「リンクされた属性(linked attribute)」になるのは何によるのでしょうか?
Active Directory の各属性は、Active Directory のスキーマパーティション内の AttributeSchema オブジェクトによって定義されています。リンクされた属性(linked attributes)を定義する AttributeSchema オブジェクトだけが、値が設定された LinkID 属性を保有している唯一のスキーマオブジェクトです。したがって、ドメイン内のリンクされた属性をすべて特定するのは、次のように PowerShell を使って、LinkID が設定されているオブジェクトをスキーマから検索するだけです:
Get-ADObject -SearchBase (Get-ADRootDSE).SchemaNamingContext -LDAPFilter "(LinkID=*)"
リンクされた属性(linked attributes)は一般的に 2 つで 1 組になって存在し、前方リンク(forward link)と後方リンク(back link)の組み合わせになります。これは LinkID 属性の値によって定義されます:
- 前方リンク(forward link)— LinkID の値は常に正の 偶数 の整数です。
- 後方リンク(back link)— LinkID の値は常に正の 奇数 の整数です。実際には、対応する前方リンク(forward link)の LinkID に 1 を足した値になっています。
LinkID 値が最も小さい属性は、Member 属性と MemberOf 属性です。これらは Active Directory のグループ メンバーシップを追跡するために使用されます。そこで、PowerShell スクリプトを変更して、出力をこの 2 つの属性に限定しましょう:
出力結果から、この 2 つの属性についていくつかの重要な事実が分かります:
- Member 属性の LinkID 値は 2 で、これは偶数です。つまり Member 属性は順方向リンク(forward link)です。
- MemberOf 属性の LinkID 値は 3 で、これは奇数です。つまり MemberOf 属性は逆方向リンク(back link)です。
- 逆方向リンク(back link)の MemberOf の LinkID 値は、順方向リンク(forward link)の Member 属性の LinkID 値に 1 を加えたものです(3 = 2 + 1)。つまり、Member 属性と MemberOf 属性は関連付けられたリンク属性(associated linked attributes)です。
少し異なる PowerShell スクリプトを使うことで、リンクされた属性に関連付けられたフォワードリンクまたはバックリンクの名前を直接取得できます。ただし、その属性がフォワードリンクなのかバックリンクなのかは明示的には分かりません。LinkID の値を確認し、自分で判断する必要があります。
Active Directory のリンクされた属性はどのように動作しますか?
リンクされた属性が何であり、どのように識別するのかが分かったところで、次はそれらの挙動を見ていく時です。
リンクされた属性は、2つのオブジェクト間の関係に関する情報を保持します。これに対して従来の Active Directory 属性は、オブジェクトに関する情報を保持します。この機能上の違いは、Active Directory がリンクされた属性の値を、他の属性の値とは異なる方法で保存することに表れています。
リンクされた属性はどのように保存されるか
Active Directory のデータは ntds.dit データベース ファイルに保存されます。通常の属性の値は datatable と呼ばれるテーブルに保存されます。リンクされた属性には、それぞれ専用のテーブルがあり、その名前は適切に link_table です。私のラボの ntds.dit データベース ファイルのスナップショットをのぞいてみると、Active Directory がリンクされた属性値をどのように保存しているかを確認できます:
link_table におけるオブジェクト参照では、オブジェクトの distinguished name タグ(DNT)を使用します。DNT は実際には ntds.dit datatable 内のレコードの内部プライマリ キーです。これにより、オブジェクトの distinguished name が変更された場合でも、関連する link_table エントリをすべて更新する必要がなくなります。
このスクリーンショットでは、link_table 内の 3 つの重要なフィールドが強調表示されています:
- link_DNT — 前方リンク オブジェクトへの参照です。
- backlink_DN — 関連するバックリンク オブジェクトへの参照です。
- link_base — 先のリンク属性の LinkID への参照です。このフィールドでは、2 つのオブジェクト間で追跡されている関係を識別するために、前方リンクの LinkID 値を使用します(ただし、スクリーンショットにあるとおり、表中の値は実際には LinkID 値を 2 で割ったものです)。
リンクされた属性を保存するこのアプローチによる実用上の影響
この保存アプローチは少し変に見えるかもしれませんが、いくつかの重要な実用上の結果につながる、本当にすばらしい設計です:
- 前方リンクの値は保存されますが、後方リンクの値は構築されます。 これは、この議論から持ち帰るべき最も重要な概念です: バックリンクは実際には情報を保存しません。 2 つのオブジェクト間の関連(association)は 1 つの実体であるため、Active Directory は関連を 1 つ以上のコピーとして保存する必要はありません。前方リンクがクエリされる場合、Active Directory は単に、クエリ対象のオブジェクトの DNT が link_DNT フィールドの値と一致し、かつ前方リンクの LinkID が link_base フィールドの値と一致する link_table エントリを返すだけで済みます。後方リンクがクエリされる場合、Active Directory は、クエリ対象のオブジェクトの DNT が backlink_DNT フィールドの値と一致し、さらに関連付けられた前方リンクの LinkID(後方リンクの LinkID から 1 を引いて計算されます)が link_base フィールドの値と一致する link_table エントリを返すことで、その値を計算できます。
- 前方リンクの値は書き込み可能であり、後方リンクの値は読み取り専用です。 一度、Active Directory が前方リンクの値だけを保存することを知ってしまえば、これはおそらく当然に見えるでしょう。しかし重要な結果があります。つまり、リンクされた属性が変更されると、Active Directory は前方リンクを更新し、その結果そのリンクを保持しているオブジェクトが変更されます。構築された読み取り専用の値を持つ後方リンクは、決して変更できないため、後方リンクを保持しているオブジェクト を保持している オブジェクトも変更されません。
なぜこれが重要なのかを説明するために、ユーザーをグループに追加するケースを考えてみましょう。この更新では、グループの Member 属性だけが変更されます。ユーザーの MemberOf 属性は変更されません。グループ オブジェクトに実質的な変更があったため、その変更を反映するメタデータ フィールド(例:“ModifyTimeStamp” と “WhenChanged” 属性)が更新されます。同じメタデータ フィールドは 更新されません。ユーザー オブジェクトでは、たとえ MemberOf 属性が今後は別の値を返すようになっても、MemberOf 属性そのものが変更されていないためです。 - フォワード リンクは必須であり、バック リンクは任意です。 リンク属性(linked attributes)に関する一部の記事では、リンク属性には常にフォワード リンクとバック リンクの両方があると述べられています。これは多くの場合当てはまりますが、バック リンクの存在が厳密に必要というわけではありません。実際に、PowerShell を使ってリンク属性のペアを取得してみると、私のラボ環境ではすべてのフォワード リンクに対応するバック リンクがあるわけではないことがわかります:
リンク属性の保存方法としてこのアプローチの利点
リンク属性がどのように保存されるかについて、かなり見事なやり方だと私が言っていたのを覚えていますか?Active Directory がリンク属性の値を保存するアプローチは、実際にはとても重要な2つのメリットをもたらします。
まず、フォワード リンクの値だけを保存し、それらを使って関連するバック リンクの値を計算することで、 Active Directory database のサイズを減らせます。
もう1つの主要な利点(やや分かりにくいもの)は、Active Directory がそれぞれの関連(association)を個別に保存しているという事実に由来します。フォワード リンク(forward link)の各 association は link_table 内にそれぞれ独自のエントリを持つため、各エントリは独自の更新シーケンス番号(Update Sequence Number:USN)を維持できます。この動作は Linked Value Replication(LVR)と呼ばれ、Active Directory が各個別の association を独立してレプリケート(複製)できるようにします。たとえば、既存メンバーが 100 人のグループにユーザーを追加する場合、新しく追加されたユーザーのエントリだけがレプリケートされます。これにより、リンク属性(linked attributes)への変更を伝播するために必要なレプリケーション量を大幅に減らせます。
ボーナス情報
ここまでまとめる前に、もう1つ触れておく価値のある挙動があります:AD Recycle Bin が有効になっていない限り、リンクされた属性の値は削除されたオブジェクトから削除されます。リンクされた属性を持つオブジェクトを削除すると、Active Directory がそのオブジェクト自体を一定期間 tombstone として維持する一方で、そのオブジェクトに関連付けられた link_table エントリも削除されます。Active Directory Recycle Bin を有効にするとこの動作が変わり、削除されたオブジェクトの tombstone 期間が続く間、関連する link_table エントリが保持されます。
まとめ
Active Directory のリンクされた属性は、他の Active Directory 属性とは異なる方法で保存されるため、挙動も異なります。これは特に back link 属性に当てはまります。この記事から持ち帰るべきことを1つだけ挙げるなら、back link は構成属性(constructed attributes)だという点です。つまりそれらの値は直接保存されないため、その結果として、特に更新に関しては、他の属性とはまったく同じように振る舞いません。Active Directory は一貫したユーザー体験のためにバックエンドの動作をうまく隠すことが多いものの、属性の根本的な違いとその影響を理解しておけば、問題を防ぐことができます。
Netwrix はどのように支援できるか
Active Directoryをエンドツーエンドで安全に保つには、 Netwrix Active Directory security solution 。これにより、次のことが可能になります:
- Active Directory 内のセキュリティリスクを特定し、対策の優先順位を決めましょう。
- ITインフラ全体のセキュリティ設定を強化します。
- DCSyncのような高度な脅威も含めて、迅速に検知して封じ込めます。たとえば、DCSync および Golden Ticket 攻撃です。
- 自動化された応答オプションで、既知の脅威に即座に対応します。
迅速な Active Directory 復旧で、業務の中断を最小限に抑えます。
共有する
もっと詳しく
著者について
Joe Dibley
セキュリティリサーチャー
Netwrix のセキュリティリサーチャーであり、Netwrix Security Research Team のメンバーです。Joe は Active Directory、Windows、およびさまざまなエンタープライズソフトウェアのプラットフォームとテクノロジーの専門家であり、新たなセキュリティリスク、複雑な攻撃手法、そしてそれに関連する緩和策と検知について研究しています。