LDAPプロトコル、データ階層、およびエントリコンポーネントを理解する
序章
LDAP(Lightweight Directory Access Protocol)は、階層ディレクトリ構造からデータを格納および取得するために使用されるオープンプロトコルです。 LDAPは、組織とその資産およびユーザーに関する情報を格納するために一般的に使用され、あらゆるタイプのエンティティとその品質を定義するための柔軟なソリューションです。
多くのユーザーにとって、LDAPは特別な用語に依存し、いくつかの珍しい略語を使用し、相互作用するパーツのより大きなシステムのコンポーネントとして実装されることが多いため、理解するのが難しいように思われる場合があります。 このガイドでは、LDAPの基本のいくつかを紹介し、テクノロジを操作するための優れた基盤を構築します。
ディレクトリサービスとは何ですか?
ディレクトリサービスは、キー値タイプの形式でデータを格納、整理、および表示するために使用されます。 通常、ディレクトリは、書き込み操作よりもルックアップ、検索、および読み取り操作用に最適化されているため、頻繁に参照されるが変更頻度が低いデータに対しては非常にうまく機能します。
ディレクトリサービスに保存されるデータは、多くの場合、本質的に記述的であり、エンティティの品質を定義するために使用されます。 ディレクトリサービスで適切に表現される物理オブジェクトの例は、名簿です。 各人は、連絡先情報、事業所などを説明するキーと値のペアを使用して、ディレクトリ内のエントリで表すことができます。 ディレクトリサービスは、定性的で説明的な情報にアクセスできるようにする多くのシナリオで役立ちます。
LDAPとは何ですか?
LDAP(Lightweight Directory Access Protocol)は、ディレクトリサービスにアクセスできる方法を定義する通信プロトコルです。 より大まかに言えば、LDAPは、ディレクトリサービス内のデータをユーザーに表示する方法を形作り、ディレクトリサービス内にデータエントリを作成するために使用されるコンポーネントの要件を定義し、さまざまなプリミティブ要素を使用してエントリを構成する方法の概要を示します。
LDAPはオープンプロトコルであるため、さまざまな実装を利用できます。 OpenLDAPプロジェクトは、最もよくサポートされているオープンソースの亜種の1つです。
基本的なLDAPデータコンポーネント
LDAPが、ディレクトリデータベースと通信して情報を照会、追加、または変更するために使用されるプロトコルである方法については、上記で説明しました。 ただし、この単純な定義は、このプロトコルをサポートするシステムの複雑さを誤って表現しています。 LDAPがユーザーにデータを表示する方法は、いくつかの定義された構造コンポーネントの相互作用と関係に大きく依存します。
属性
LDAPシステムのデータ自体は、主に属性と呼ばれる要素に格納されます。 属性は基本的にキーと値のペアです。 他のいくつかのシステムとは異なり、キーには事前定義された名前があり、エントリ用に選択されたobjectClassesによって指定されます(これについては後で説明します)。 さらに、属性のデータは、属性の初期定義で定義されたタイプと一致する必要があります。
属性の値の設定は、属性名と属性値をコロンとスペースで区切って行います。 電子メールアドレスを定義するmail
という属性の例は、次のようになります。
mail: [email protected]
属性とそのデータを参照する場合(設定しない場合)、代わりに2つの辺が等号で結合されます。
mail=example.com
属性値には、LDAPシステムに保存してアクセスする実際のデータのほとんどが含まれています。 LDAP内の他の要素は、構造、編成などに使用されます。
エントリー
属性自体はあまり役に立ちません。 意味を持つためには、それらは何かと関連付けられている必要があります。 LDAP内では、エントリ内の属性を使用します。 エントリは基本的に、何かを説明するために使用される名前の下の属性のコレクションです。
たとえば、システム内のユーザーまたは在庫内の各アイテムのエントリを作成できます。 これは、リレーショナルデータベースシステムの行またはアドレスブック内の単一のページにほぼ類似しています(ここでの属性は、これらの各モデルのさまざまなフィールドを表します)。 属性は何かの品質または特性を定義しますが、エントリは、名前の下でこれらの属性を収集するだけで、アイテム自体を説明します。
LDIF(LDAPデータ交換フォーマット)に表示されるエントリの例は、次のようになります。
dn: sn=Ellingwood,ou=people,dc=digitalocean,dc=com
objectclass: person
sn: Ellingwood
cn: Justin Ellingwood
上記の例は、LDAPシステム内の有効なエントリである可能性があります。
DIT
LDAPに慣れてくると、属性によって定義されたデータがオブジェクトに関する利用可能な情報の一部のみを表していることを容易に認識できます。 残りは、LDAPシステム内のエントリの配置とこれが意味する関係にあります。
たとえば、ユーザーと在庫アイテムの両方のエントリを持つことができる場合、誰かがそれらをどのように区別できるでしょうか。 異なるタイプのエントリを区別する1つの方法は、関係とグループを確立することです。 これは主に、エントリが作成されたときにエントリが配置される場所の関数です。 エントリはすべて、データ情報ツリーまたはDITと呼ばれるツリーのブランチとしてLDAPシステムに追加されます。
DITは、ファイルシステムに似た組織構造を表し、各エントリ(最上位エントリを除く)には親エントリが1つだけあり、その下に子エントリをいくつでも含めることができます。 LDAPツリーのエントリはほぼすべてを表すことができるため、ファイルシステム内のディレクトリと同様に、一部のエントリは主に組織的な目的で使用されます。
このようにして、「people」のエントリと「inventoryItems」のエントリを作成できます。 実際のデータエントリは、これらの子として作成して、タイプをより適切に区別することができます。 組織のエントリは、データを最もよく表すように任意に定義できます。
前のセクションのエントリ例では、dn
行にDITの1つの表示があります。
dn: sn=Ellingwood,ou=people,dc=digitalocean,dc=com
この行はエントリの識別名と呼ばれ(これについては後で詳しく説明します)、エントリを識別するために使用されます。 これは、DITのルートに戻るフルパスのように機能します。 この例では、作成しているsn=Ellingwood
というエントリがあります。 直接の親はou=people
と呼ばれるエントリであり、おそらく人を説明するエントリのコンテナとして使用されています。 このエントリの親は、DITのルートとして機能するdigitalocean.com
ドメイン名から派生しています。
LDAPデータコンポーネントの定義
前のセクションでは、LDAPシステム内でデータがどのように表されるかについて説明しました。 ただし、データを格納するコンポーネントがどのように定義されているかについても説明する必要があります。 たとえば、データは各属性に定義されたタイプと一致する必要があると述べました。 これらの定義はどこから来ていますか? 複雑さの観点からもう一度下から始めて、上に向かって進んでいきましょう。
属性の定義
属性は、かなり複雑な構文を使用して定義されます。 これらは、属性の名前、属性を参照するために使用できるその他の名前、入力できるデータのタイプ、およびその他のさまざまなメタデータを示す必要があります。 このメタデータは、属性を記述し、LDAPに属性の値をソートまたは比較する方法を指示し、属性が他の属性とどのように関連しているかを指示できます。
たとえば、これはname
属性の定義です。
attributetype ( 2.5.4.41 NAME 'name' DESC 'RFC4519: common supertype of name attributes'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
'name'
は属性の名前です。 最初の行の番号は、他のすべての属性と区別するために属性に割り当てられたグローバルに一意のOID(オブジェクトID)です。 エントリの残りの部分は、検索中にエントリを比較する方法を定義し、属性のデータ型要件の情報を見つける場所を示すポインタを持っています。
属性定義の重要な部分の1つは、属性がエントリ内で複数回定義される可能性があるかどうかです。 たとえば、定義では、名前をエントリごとに1回だけ定義できると定義できますが、「姪」の属性を使用すると、その属性を1つのエントリで複数回定義できます。 属性はデフォルトで複数値であり、エントリごとに1回しか設定できない場合は、SINGLE-VALUE
フラグを含める必要があります。
属性の定義は、属性の使用と設定よりもはるかに複雑です。 幸い、ほとんどの場合、最も一般的な属性はほとんどのLDAP実装に含まれており、他の属性は簡単にインポートできるため、独自の属性を定義する必要はありません。
ObjectClassの定義
属性は、objectClassesと呼ばれるエンティティ内に収集されます。 ObjectClassesは、特定のことを説明するのに役立つ、関連付けられた属性の単なるグループです。 たとえば、「person」はobjectClassです。
エントリは、objectClass
という特別な属性を設定し、使用するobjectClassに名前を付けることで、objectClassの属性を使用できるようになります。 実際、objectClass
は、さらにobjectClassを指定せずにエントリに設定できる唯一の属性です。
したがって、objectClass person
(またはpersonから派生したより具体的なperson objectClassesのいずれか-これについては後で説明します)を含む、人物を説明するエントリを作成する場合、そのobjectClass内のすべての属性を使用できます。 :
dn: . . .
objectClass: person
次に、エントリ内でこれらの属性を設定することができます。
- cn :一般名
- description :人間が読める形式のエントリの説明
- seeAlso :関連エントリへの参照
- sn :名前
- telephoneNumber :電話番号
- userPassword :ユーザーのパスワード
objectClass
属性は、異なるobjectClassesの属性が必要な場合に複数回使用できますが、許容できるものを指定するルールがあります。 ObjectClassesは、いくつかの「タイプ」の1つとして定義されています。
ObjectClassesの2つの主なタイプは、structureまたはauxiliaryです。 エントリmustには、構造クラスが1つだけ含まれている必要がありますが、クラスで使用可能な属性を拡張するために使用される補助クラスが0個以上ある場合があります。 構造オブジェクトクラスはエントリの作成と定義に使用され、補助オブジェクトクラスは追加の属性を介して追加機能を追加します。
ObjectClass定義は、それらが提供する属性が必須(MUST
仕様で示される)かオプション(MAY
仕様で示される)かを決定します。 複数のobjectClassesが同じ属性を提供でき、属性のMAY
またはMUST
の分類はobjectClassごとに異なる場合があります。
例として、person
objectClassは次のように定義されます。
objectclass ( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top STRUCTURAL
MUST ( sn $ cn )
MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )
これは構造的なobjectClassとして定義されており、エントリの作成に使用できることを意味します。 作成されたエントリsurname
およびcommonname
属性を設定する必要があり、userPassword
、telephoneNumber
、seeAlso
、またはdescription
属性。
スキーマ
ObjectClass定義と属性定義は、schemaと呼ばれる構造にグループ化されます。 従来のリレーショナルデータベースとは異なり、LDAPのスキーマは、関連するobjectClassesと属性の単なるコレクションです。 単一のDITは、必要なエントリと属性を作成できるように、多くの異なるスキーマを持つことができます。
スキーマには多くの場合、追加の属性定義が含まれ、他のスキーマで定義された属性が必要になる場合があります。 たとえば、上記で説明したperson
objectClassでは、person
objectClassを使用するすべてのエントリにsurname
またはsn
属性を設定する必要があります。 これらがLDAPサーバー自体で定義されていない場合は、これらの定義を含むスキーマを使用して、これらの定義をサーバーの語彙に追加できます。
スキーマの形式は、基本的に次のように上記のエントリの組み合わせにすぎません。
. . .
objectclass ( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top STRUCTURAL
MUST ( sn $ cn )
MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )
attributetype ( 2.5.4.4 NAME ( 'sn' 'surname' )
DESC 'RFC2256: last (family) name(s) for which the entity is known by' SUP name )
attributetype ( 2.5.4.4 NAME ( 'cn' 'commonName' )
DESC 'RFC4519: common name(s) for which the entity is known by' SUP name )
. . .
データ編成
LDAPシステム内でエントリを構築するために使用される一般的な要素について説明し、これらのビルディングブロックがシステム内でどのように定義されるかについて説明しました。 ただし、LDAP DIT内で情報自体がどのように編成および構造化されているかについては、まだあまり説明していません。
DIT内にエントリを配置する
DITは、単に既存のエントリの関係を記述する階層です。 作成時に、新しいエントリはそれぞれ、既存のエントリの子として自分自身を配置することにより、既存のDITに「フック」する必要があります。 これにより、関係を定義し、意味を割り当てるために使用されるツリーのような構造が作成されます。
DITの最上位は、後続の各ノードが何らかの形で子孫である最も広い分類です。 通常、一番上のエントリは、DITが使用されている組織を示すラベルとして使用されます。 これらのエントリは、任意のobjectClassesにすることができますが、通常、ドメインコンポーネント(example.com
に関連付けられた情報を管理するLDAPの場合はdc=example,dc=com
)、組織の場合は場所(l=new_york,c=us
)を使用して構築されます。またはNYのセグメント)、または組織セグメント(ou=marketing,o=Example_Co
)。
編成に使用されるエントリ(フォルダーのように使用される)は、多くの場合、ou=
と呼ばれる単純な説明属性ラベルの使用を可能にするorganizationalUnitobjectClassを使用します。 これらは、トップレベルのDITエントリの下の一般的なカテゴリによく使用されます(ou=people
、ou=groups
、ou=inventory
などが一般的です)。 LDAPは、ツリー内で上下にではなく、ツリーに沿って横方向に情報を検索するように最適化されているため、DIT階層をかなり浅くして、一般的な組織のブランチと特定の属性の割り当てによってさらに細分化することがよくあります。
DIT内のエントリの命名と参照
エントリは属性で参照されます。 つまり、各エントリには、DIT階層のレベルで明確な属性または属性のグループが必要です。 この属性または属性のグループは、エントリの相対識別名または RDN と呼ばれ、ファイル名のように機能します。
エントリを明確に参照するには、エントリのRDNをそのすべての親エントリのRDNと組み合わせて使用します。 このRDNのチェーンは、DIT階層の最上位に戻り、問題のエントリへの明確なパスを提供します。 このRDNのチェーンを、エントリの識別名またはDNと呼びます。 LDAPシステムが新しいエントリを配置する場所を認識し、エントリのRDNが別のエントリによってまだ使用されていないことを確認できるように、作成中にエントリのDNを指定する必要があります。
例えとして、RDNは、ファイルシステムで見られるように、相対的なファイル名またはディレクトリ名と考えることができます。 一方、DNは、絶対パスにより類似しています。 重要な違いは、LDAP DNには左側側に最も具体的な値が含まれ、ファイルパスには右側側に最も具体的な情報が含まれることです。 DNは、RDN値をコンマで区切ります。
たとえば、John Smithという名前の人のエントリは、example.com
の下の組織の「People」エントリの下に配置される場合があります。 組織内に複数のJohnSmithがいる可能性があるため、エントリのRDNにはユーザーIDの方が適している場合があります。 エントリは次のように指定できます。
dn: uid=jsmith1,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
cn: John Smith
sn: Smith
uid: jsmith1
このインスタンスでuid
属性にアクセスするには、inetOrgPerson
objectClassを使用する必要がありました(person
objectClassで定義されたすべての属性に引き続きアクセスできます。次のセクションを参照してください)。
LDAP継承
結局のところ、LDAPシステム内のデータが相互に関連する方法の多くは、階層、継承、およびネストの問題です。 LDAPは、その設計にオブジェクト指向の概念を実装しているため、最初は多くの人にとって珍しいように見えます。 これは主に、前に説明したようにクラスを使用することと、これから説明する継承の可用性に起因します。
ObjectClassの継承
各objectClassは、そのタイプのオブジェクトの特性を記述するクラスです。
ただし、単純な継承とは異なり、LDAPのオブジェクトは複数のクラスのインスタンスである可能性があり、多くの場合、複数のクラスのインスタンスです(一部のプログラミング言語は、複数の継承を通じて同様の機能を提供します)。 これが可能なのは、LDAPのクラスの概念が、MUSTまたはMAYが持つ必要のある属性のコレクションにすぎないためです。 これにより、エントリに複数のクラスを指定できます(ただし、1つのSTRUCTURAL
objectClassのみが存在でき、存在する必要があります)。その結果、オブジェクトは、最も厳密なMUSTまたはMAY宣言が優先される、マージされた属性のコレクションにアクセスできるようになります。 。
その定義では、objectClassは、その属性を継承する親objectClassを識別できます。 これは、SUP
に続いて、継承元のobjectClassを使用して行われます。 たとえば、organizationalPerson
objectClassは次のように始まります。
objectclass ( 2.5.6.7 NAME 'organizationalPerson' SUP person STRUCTURAL
. . .
SUP
識別子に続くobjectClassは、親objectClassです。 親は、定義されているobjectClassのobjectClassタイプを共有する必要があります(たとえば、STRUCTURAL
またはAUXILIARY
)。 子objectClassは、親の属性と属性要件を自動的に継承します。
エントリでobjectClassを割り当てる場合、属性にアクセスできるようにするには、継承チェーンの最も具体的な子孫を指定するだけで済みます。 前のセクションでは、これを使用して、person
およびorganizationalPerson
objectClassesで定義された属性にアクセスしながら、JohnSmithエントリの唯一のobjectClassとしてinetOrgPerson
を指定しました。 inetOrgPerson
継承階層は次のようになります。
inetOrgPerson -> organizationalPerson -> person -> top
ほとんどすべてのobjectClass継承ツリーは、「top」と呼ばれる特別なobjectClassで終わります。 これは抽象objectClassであり、その唯一の目的はobjectClass自体を設定することを要求することです。 継承チェーンの最上位を示すために使用されます。
属性の継承
同様に、属性自体は、定義中に親属性をリストできます。 この属性は、親属性で設定されたプロパティを継承します。
これは、一般的な属性のより具体的なバージョンを作成するためによく使用されます。 たとえば、名前は名前の一種であり、同じ方法をすべて使用して、同等性を比較およびチェックできます。 これらの品質を継承して、「名前」属性の一般的な形式を取得できます。 実際、実際の名前の定義には、親属性へのポインタしか含まれていない可能性があります。
これは、要素の一般的な形式が変更されていない場合でも、要素を解釈する人々に役立つ特定の属性を作成できるため便利です。 ここで説明したsurname
属性の継承は、名前とより一般的な名前を区別するのに役立ちますが、値の意味を除いて、LDAPシステムの名前と名前にはほとんど違いがありません。
LDAPプロトコルのバリエーション
LDAPは、実際にはディレクトリサービスを操作するための通信インターフェイスを定義するプロトコルにすぎないことを最初に説明しました。 これは通常、LDAPまたはLDAPプロトコルとして知られています。
通常の形式でいくつかのバリエーションが表示される可能性があることに注意してください。
- ldap:// :これは、ディレクトリサービスへの構造化されたアクセスを可能にする基本的なLDAPプロトコルです。
- ldaps:// :このバリアントは、LDAP over SSL/TLSを示すために使用されます。 通常のLDAPトラフィックは暗号化されていませんが、ほとんどのLDAP実装はこれをサポートしています。 LDAP接続を暗号化するこの方法は実際には非推奨であり、代わりにSTARTTLS暗号化の使用をお勧めします。 安全でないネットワーク上でLDAPを操作している場合は、暗号化を強くお勧めします。
- ldapi:// :これはIPCを介したLDAPを示すために使用されます。 これは、管理目的でローカルLDAPシステムに安全に接続するためによく使用されます。 公開されたネットワークポートを使用する代わりに、内部ソケットを介して通信します。
3つの形式はすべてLDAPプロトコルを利用しますが、最後の2つは、LDAPプロトコルがどのように使用されているかに関する追加情報を示しています。
結論
LDAPプロトコルと、LDAPの実装がユーザーにデータを表す方法をかなりよく理解している必要があります。 システムの要素が互いにどのように関連しているか、およびそれらがプロパティを取得する場所を理解することで、LDAPシステムの管理と使用がより簡単で予測可能になります。