前書き

LDAP(Lightweight Directory Access Protocol)は、階層ディレクトリ構造からデータを保存および取得するために使用されるオープンプロトコルです。 組織とその資産およびユーザーに関する情報を保存するために一般的に使用されるLDAPは、あらゆるタイプのエンティティとその品質を定義するための柔軟なソリューションです。

多くのユーザーにとって、LDAPは特別な用語に依存し、いくつかの珍しい略語を使用し、多くの場合、相互作用するパーツのより大きなシステムのコンポーネントとして実装されるため、理解が難しいように思われます。 このガイドでは、LDAPの基本の一部を紹介し、テクノロジーを使用するための優れた基盤を提供します。

ディレクトリサービスとは何ですか?

ディレクトリサービスは、キーと値のタイプの形式でデータを保存、整理、表示するために使用されます。 通常、ディレクトリは、ルックアップ、検索、および書き込み操作よりも読み取り操作に対して最適化されているため、頻繁に参照されるが頻繁に変更されないデータに対して非常に適切に機能します。

多くの場合、ディレクトリサービスに格納されるデータは本質的に記述的であり、エンティティの品質を定義するために使用されます。 ディレクトリサービスで適切に表現される物理オブジェクトの例は、アドレス帳です。 各人物は、連絡先情報、事業所などを説明するキーと値のペアを使用して、ディレクトリ内のエントリで表すことができます。 ディレクトリサービスは、定性的で説明的な情報にアクセスできるようにする多くのシナリオで役立ちます。

LDAPとは

LDAP(軽量ディレクトリアクセスプロトコル)は、ディレクトリサービスにアクセスできる方法を定義する通信プロトコルです。 より大まかに言えば、LDAPは、ディレクトリサービス内のデータをユーザーに表示する方法を形成し、ディレクトリサービス内でデータエントリを作成するために使用されるコンポーネントの要件を定義し、エントリを作成するためにさまざまなプリミティブ要素を使用する方法を概説します。

LDAPはオープンプロトコルであるため、さまざまな実装が利用可能です。 OpenLDAPプロジェクトは、最もよくサポートされているオープンソースのバリアントの1つです。

基本的なLDAPデータコンポーネント

上記では、LDAPがディレクトリデータベースと通信して情報を照会、追加、または変更するために使用されるプロトコルである方法について説明しました。 ただし、この単純な定義は、このプロトコルをサポートするシステムの複雑さを誤って表しています。 LDAPがユーザーにデータを表示する方法は、いくつかの定義された構造コンポーネント間の相互作用と関係に大きく依存します。

属性

LDAPシステムのデータ自体は、主に* attributes *と呼ばれる要素に保存されます。 属性は基本的にキーと値のペアです。 他の一部のシステムとは異なり、キーには、エントリ用に選択されたobjectClassesによって決定される定義済みの名前があります(これについては後で説明します)。 さらに、属性のデータは、属性の初期定義で定義されたタイプと一致する必要があります。

属性の値の設定は、属性名と属性値をコロンとスペースで区切って行います。 メールアドレスを定義する「+ mail +」という属性の例は次のようになります。

属性とそのデータを参照する場合(設定しない場合)、代わりに等号で2つの側面が結合されます。

mail=example.com

属性値には、LDAPシステムに保存してアクセスする実際のデータのほとんどが含まれています。 LDAP内の他の要素は、構造、組織などに使用されます。

エントリー

属性自体はあまり有用ではありません。 意味を持たせるには、何かと「関連する」必要があります。 LDAP内では、* entry *内の属性を使用します。 エントリは、基本的に何かを記述するために使用される名前の下の属性のコレクションです。

たとえば、システム内のユーザーまたはインベントリ内の各アイテムに対してエントリを作成できます。 これは、リレーショナルデータベースシステムの行またはアドレス帳内の単一ページにほぼ類似しています(ここでの属性は、これらの各モデルのさまざまなフィールドを表します)。 属性は何かの品質または特性を定義しますが、エントリは単に名前の下でこれらの属性を収集することによってアイテム自体を説明します。

LDIF(LDAP Data Interchange Format)に表示されるエントリの例は次のようになります。

dn: sn=Ellingwood,ou=people,dc=digitalocean,dc=com
objectclass: person
sn: Ellingwood
cn: Justin Ellingwood

上記の例は、LDAPシステム内の有効なエントリです。

DIT

LDAPに慣れ始めると、属性によって定義されたデータがオブジェクトに関する利用可能な情報の一部のみを表していることを簡単に認識できます。 残りは、LDAPシステム内でのエントリの配置と、これが意味する関係にあります。

たとえば、ユーザーとインベントリアイテムの両方のエントリを持つことができる場合、誰かがそれらを区別する方法を教えてください。 異なるタイプのエントリを区別する1つの方法は、関係とグループを確立することです。 これは主に、エントリが作成されたときに配置される場所の機能です。 エントリはすべて、* Data Information Trees または DITs *と呼ばれるツリー上のブランチとしてLDAPシステムに追加されます。

DITは、各エントリ(最上位エントリ以外)に1つの親エントリがあり、その下に任意の数の子エントリがあるファイルシステムに似た組織構造を表します。 LDAPツリーのエントリはほぼ何でも表すことができるため、ファイルシステム内のディレクトリと同様に、いくつかのエントリは主に組織的な目的で使用されます。

このようにして、「人」のエントリと「在庫アイテム」のエントリを作成できます。 実際のデータエントリをこれらの子として作成して、タイプをより適切に区別できます。 組織のエントリは、データを最もよく表すように任意に定義できます。

最後のセクションのエントリ例では、 `+ 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回しか定義できないと定義できますが、「niece」の属性を使用すると、1つのエントリでその属性を複数回定義できます。 属性はデフォルトで複数値であり、エントリごとに1回だけ設定できる場合は、 `+ SINGLE-VALUE +`フラグを含める必要があります。

属性の定義は、属性の使用と設定よりもはるかに複雑です。 幸いなことに、ほとんどのLDAP実装には最も一般的な属性が含まれており、他の属性は簡単にインポートできるため、ほとんどの場合、独自の属性を定義する必要はありません。

ObjectClassの定義

属性は、* objectClasses *と呼ばれるエンティティ内で収集されます。 ObjectClassesは、特定の事柄を記述するのに役立つ関連属性の単純なグループ化です。 たとえば、「person」はobjectClassです。

エントリは、 `+ objectClass `という特別な属性を設定して、使用するobjectClassに名前を付けることにより、objectClassの属性を使用する機能を獲得します。 実際、 ` objectClass +`は、追加のobjectClassを指定せずにエントリに設定できる唯一の属性です。

したがって、 + objectClass person +(またはpersonから派生したより具体的な人物objectClasses-これについては後で説明します)を含む、人物を記述するエントリを作成する場合、そのobjectClass内のすべての属性を使用できます。

dn: . . .
objectClass: person

その後、エントリ内でこれらの属性を設定できます。

  • * cn *:共通名

  • * description *:人間が読めるエントリの説明

  • * seeAlso *:関連エントリへの参照

  • * sn *:姓

  • * telephoneNumber *:電話番号

  • * userPassword *:ユーザーのパスワード

異なるobjectClassesの属性が必要な場合は、 `+ objectClass +`属性を複数回使用できますが、受け入れられるものを決定するルールがあります。 ObjectClassesは、いくつかの「タイプ」の1つとして定義されています。

ObjectClassの2つの主なタイプは、* structural または auxiliary *です。 エントリは、構造クラスを1つだけ持つ必要がありますが、クラスで使用できる属性を拡張するために使用される補助クラスが0個以上ある場合があります。 構造objectClassは、エントリの作成と定義に使用されますが、補助objectClassesは、追加の属性を通じて機能を追加します。

ObjectClass定義は、提供する属性が必須( `+ MUST `仕様で示される)かオプション( ` MAY `仕様で示される)かを決定します。 複数のobjectClassが同じ属性を提供でき、属性の ` 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定義と属性定義は、順番に*スキーマ*と呼ばれる構造にグループ化されます。 従来のリレーショナルデータベースとは異なり、LDAPのスキーマは、関連するobjectClassと属性の単なるコレクションです。 単一の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 + `)。

(フォルダーのように使用される)組織に使用されるエントリは、しばしばorganizationUnit objectClassを使用します。これにより、 `+ ou = `と呼ばれる単純な説明的な属性ラベルを使用できます。 これらは、トップレベルの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には_left-hand_側の最も具体的な値が含まれ、ファイルパスには_right-hand_側の最も具体的な情報が含まれていることです。 DNは、コンマでRDN値を区切ります。

たとえば、John Smithという名前の人のエントリは、「+ example.com +」の下の組織の「People」エントリの下に配置される場合があります。 組織には複数のJohn Smithが存在する可能性があるため、エントリの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を持つ属性の単なるコレクションであるためです。 これにより、エントリに対して複数のクラスを指定できます(ただし、 + STRUCTURAL + objectClassは1つしか存在できず、存在する必要があります)。その結果、オブジェクトは、最も厳格なMUSTまたはMAY宣言が優先されるマージされた属性コレクションにアクセスできます。

その定義では、objectClassは、属性を継承する親objectClassを識別できます。 これは、継承するobjectClassが後に続く + SUP +`を使用して行われます。 たとえば、 `+ organizationalPerson + objectClassは次のように始まります:

objectclass ( 2.5.6.7 NAME 'organizationalPerson' SUP  STRUCTURAL
. . .

+ SUP +`識別子に続くobjectClassは親objectClassです。 親は、定義されているobjectClassのobjectClassタイプを共有する必要があります(たとえば、 `+ STRUCTURAL +`または `+ AUXILIARY +)。 子objectClassは、親の属性と属性要件を自動的に継承します。

エントリでobjectClassを割り当てる場合、継承チェーンの最も具体的な子孫を指定するだけで、属性に完全にアクセスできます。 最後のセクションでは、これを使用して、 + person +`および `+ organizationalPerson + objectClassesで定義された属性にアクセスしながら、John Smithエントリの唯一の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システムの管理と使用がより簡単で予測可能になります。