【OpenLDAP基本講座 第1回】LDAPの基礎理論。DIT、スキーマ、オブジェクトクラスの完全理解

なぜ、データベース(RDBMS)ではなく「ディレクトリ」なのか?

こんにちは!「LINUX工房」管理人の「リナックス先生」です。
今日から全8回にわたり、Linux認証基盤のデファクトスタンダード「OpenLDAP」を基礎から徹底的に学ぶ講座を始めます。

第1回はいきなり構築……ではなく、「理論」の話です。
「えー、早くコマンド叩きたいよ」と思いましたか?
しかし、断言します。LDAPで挫折する人の99%は、この「データ構造の理解」をおろそかにした結果、意味不明なエラー(Object Class Violationなど)に悩まされ、嫌になってしまうのです。

コウ君

先生、僕もまさにそれです!
MySQLならテーブル作ってINSERTするだけなのに、LDAPは「DN」とか「cn」とか「objectClass」とか、呪文みたいな用語が多すぎて……。
そもそも、ユーザー管理ならMySQLでやっちゃダメなんですか?
なんでわざわざ、こんな取っつきにくい仕組みを使うんですか?

リナックス先生

コウ君、いい質問ね。
LDAP(Lightweight Directory Access Protocol)は、「読み取り速度」に特化した階層型データベースなの。
ログイン認証のように「書き込みは滅多にないけど、毎秒何千回も検索される」用途では、RDBMSよりも圧倒的に高速なのよ。
それに、世界中のシステムが「ユーザー情報はLDAPで取る」ことを前提に作られているから、これを避けて通ることはできないの。

本記事では、LDAPを理解するための3つの柱「DIT(木構造)」「オブジェクトクラス(型)」「スキーマ(ルール)」について、プロの視点を交えながら、どこよりも分かりやすく解説します。

🐬 OpenLDAP 基本講座 カリキュラム

  • 【第1回】LDAPの基礎理論。DIT、スキーマ、オブジェクトクラスとは?
  • 【第2回】インストールと初期設定。slapdの起動と動作確認
  • 【第3回】cn=configの正体。slapd.conf世代からの脱却
  • 【第4回】データ管理の作法。LDIFファイルとldapコマンド群
  • 【第5回】アクセス制御 (ACL)。olcAcessの読み方・書き方
  • 【第6回】セキュリティ強化。TLS/SSL化と証明書管理
  • 【第7回】レプリケーション。Syncreplによる冗長化構成
  • 【第8回】クライアント連携と運用。SSSD設定とバックアップ

第1章:世界地図を描く。DIT(ディレクトリ情報ツリー)

RDBMS(MySQLやPostgreSQL)は、エクセル表のような「テーブル」でデータを管理します。
対して、LDAPは、Linuxのファイルシステムのような「ツリー構造(木構造)」でデータを管理します。
この構造全体を DIT (Directory Information Tree) と呼びます。

ルート(根っこ)の決め方

ツリーの一番上(ルート)をどうするか。
昔は国別コード(c=JP)や組織名(o=Hitachi)を使っていましたが、インターネットが普及した現在は、DNSドメイン名を使うのが一般的です。

例えば、linuxkoubou.com というドメインを持つ組織なら、以下のように分解してルートにします。
dc=linuxkoubou,dc=com

  • dc (Domain Component): ドメインの構成要素

コンテナ(枝)の役割

ルートの下に、データを分類するための「フォルダ」のようなものを作ります。
一般的には OU (Organizational Unit: 組織単位) が使われます。

  • ou=People (または ou=Users): ユーザーを入れる場所
  • ou=Groups: グループを入れる場所
  • ou=Computers: サーバーやPCの情報を入れる場所

リーフ(葉)

末端にあるのが、実際のデータ(エントリ)です。
例えば、ユーザー「Taro Yamada」の情報などがこれに当たります。

💡 プロの視点:dc=local は使うな
社内LANだからといって dc=example,dc=local のように .local ドメインを使うのは推奨されません(mDNSとの競合などのため)。
実在するドメインか、社内専用のサブドメイン(int.linuxkoubou.com など)を使うのがベストプラクティスです。


第2章:エントリーを特定する住所。DNとRDN

LDAPで最も重要な概念が DN (Distinguished Name: 識別名) です。
これは、ツリー上のエントリを一意に特定するための「絶対パス」です。

DNの構造

Linuxのファイルパスは /home/taro/docs/file.txt のように「親から子へ」書きますが、LDAPのDNは「子から親へ(逆順)」に書きます。住所の書き方に似ています。

例: linuxkoubou.comPeople 部署にいる taro さんのDN

uid=taro,ou=People,dc=linuxkoubou,dc=com
  • uid=taro: その階層内での名前。これを RDN (Relative Distinguished Name: 相対識別名) と呼びます。
  • ou=People: 親のRDN。
  • dc=linuxkoubou,dc=com: 親の親(ベースDN)。

RDNの選び方

RDNは、兄弟姉妹の中で「重複してはいけない」というルールがあります。
ou=People の下に uid=taro が2人いることは許されません。

  • uid (User ID): ユーザー名。一意性が高いのでRDNによく使われます。
  • cn (Common Name): 一般名(フルネーム)。同姓同名がいると重複するので、RDNにする場合は注意が必要です(cn=Taro Yamada 2 のように連番を振るなど)。

第3章:データの「型」を決める。オブジェクトクラス

LDAPでは、エントリを適当に作ることはできません。
「このエントリは人間です」「このエントリはサーバーです」という宣言が必要です。
この「型」のことを オブジェクトクラス (Object Class) と呼びます。

オブジェクトクラスの種類

オブジェクトクラスには3つの種類があります。

  1. ABSTRACT(抽象型): 基礎となる型。直接は使えません。すべてのエントリは top という抽象クラスを継承します。
  2. STRUCTURAL(構造型): エントリの実体を表す型。1つのエントリに必ず1つ以上必要です(例: inetOrgPerson)。
  3. AUXILIARY(補助型): 構造型に機能を追加するためのオプション型(例: posixAccount)。

代表的なオブジェクトクラス

Linux認証基盤を作る上で、必ず使う組み合わせを紹介します。

クラス名 種類 役割 主な属性
inetOrgPerson STRUCTURAL 一般的な「人間」を表す。 cn, sn, mail, mobile, employeeNumber
posixAccount AUXILIARY Linuxユーザーとしての情報を付与。 uidNumber, gidNumber, homeDirectory, loginShell
shadowAccount AUXILIARY パスワードの有効期限などを管理。 shadowLastChange, shadowExpire
organizationalUnit STRUCTURAL 「部署」や「コンテナ」を表す。 ou

つまり、Linuxにログインできるユーザーを作りたい場合、そのエントリには inetOrgPersonposixAccountshadowAccount の3つのクラスを付与することになります。


第4章:厳格なルールブック。スキーマと属性

オブジェクトクラスが決まると、そのエントリで「使える属性(Attribute)」と「必須の属性」が決まります。
この定義書のことを スキーマ (Schema) と呼びます。

MUST と MAY

スキーマには、各オブジェクトクラスに対して以下の定義がされています。

  • MUST (必須属性): これがないとエラーになり、エントリを作成できません。
    例:inetOrgPerson なら cn (Common Name) と sn (Surname: 姓) が必須です。
  • MAY (任意属性): あってもなくても良い属性。
    例:mail, telephoneNumber, description など。

属性の「構文 (Syntax)」と「照合規則 (Matching Rule)」

各属性には、データの型(文字列、数値、バイナリ)や、検索時の挙動が定義されています。

  • Case Ignore String (CIS): 大文字と小文字を区別しない。
    例:uid=Tarouid=taro は同じとみなされる。
  • Case Exact String (CES): 大文字と小文字を厳密に区別する。
    例:Linuxのパスワードなど。
  • Telephone Number Syntax: 電話番号用。スペースやハイフンを無視して照合するルールがある場合も。

💡 現場の知恵:独自スキーマを作るな
「社員ランクを表す myRank という属性が欲しい」と思った時、初心者はすぐに my-schema.schema を自作しようとします。
しかし、これは茨の道です。OID(オブジェクト識別子)の管理が必要になり、将来の移行やツール互換性で泣きを見ます。
プロの解決策: 既存の標準属性で、使っていないもの(例えば description, carLicense, roomNumber, labeledURI など)を流用するか、LDAPの拡張属性(extensionAttribute1 など)を使います。


第5章:共通言語。LDIFフォーマットの読み書き

LDAPのデータをインポートしたり、エクスポートしたり、変更したりする際は、すべて LDIF (LDAP Data Interchange Format) というテキスト形式を使います。
これの書き方を間違えると、OpenLDAPは容赦なくエラーを吐きます。

基本ルール

  1. dnで始める: 最初の行は必ず dn: ... で、対象のエントリを指定します。
  2. 属性: 値: 属性名: 値 の形式で書きます。コロンの後は半角スペースが1つ必須です。
  3. 空行で区切る: 複数のエントリを書く場合、間には必ず空行を入れます。
  4. 継続行: 行が長すぎる場合、次の行の先頭にスペースを1つ入れて続けます。

日本語の扱い (Base64)

値に日本語(マルチバイト文字)や制御文字が含まれる場合、Base64エンコードして記述し、コロンを2つ(::)にします。

例:「山田 太郎」をBase64エンコードすると 5bGx55SwIOWkqumDjg==

dn: uid=taro,ou=People,dc=linuxkoubou,dc=com
objectClass: inetOrgPerson
cn:: 5bGx55SwIOWkqumDjg==
sn:: 5bGx55Sw

※最近の ldapadd コマンドなどはUTF-8を直接扱える場合もありますが、互換性のためにBase64を使うのが確実です。

変更用LDIF (changetype)

データの追加だけでなく、修正(modify)もLDIFで行います。

dn: uid=taro,ou=People,dc=linuxkoubou,dc=com
changetype: modify
replace: mail
mail: new-email@linuxkoubou.com
-
add: telephoneNumber
telephoneNumber: 090-1234-5678

ハイフン - は、「同じエントリに対する複数の操作の区切り」です。これを忘れるとエラーになります。


第6章:プロの設計論。階層は「浅く、広く」

LDAPのツリー構造(DIT)は、一度作って運用を始めると、後から変更するのが非常に大変です(全ユーザーのDNが変わるため)。
そのため、最初の設計が命です。

悪い例:組織構造をそのまま反映する

ou=Sales,ou=Tokyo,dc=... のように、部署や拠点で深く階層化するのはお勧めしません。

  • 理由1: 組織変更のたびに、ユーザーを別のOUに移動(ModDN)させる必要がある。
  • 理由2: アプリケーション側で「営業部の人はログインOK」のような設定をする際、ベースDNの指定が複雑になる。

良い例:フラットデザイン

すべてのユーザーを ou=People 直下にフラットに配置します。

  • uid=taro,ou=People,dc=...
  • uid=hanako,ou=People,dc=...

所属部署や拠点は、OU(階層)ではなく、ユーザーの属性ou, departmentNumber, l (Locality) など)として持たせます。
これなら、組織変更があっても属性値を書き換えるだけで済み、DN(住所)は変わりません。

「営業部の人だけ検索したい」場合は、フィルタ (&(objectClass=inetOrgPerson)(ou=Sales)) を使えば一瞬です。
LDAPは「階層を辿る」よりも「属性で検索する」方が得意なデータベースなのです。


まとめ:LDAP脳に切り替えよう

お疲れ様でした!
第1回は、コマンドを一切叩かずに、ひたすら理論と設計の話をしました。
しかし、これを知っているかどうかで、今後の構築のスムーズさが段違いになります。

今回の重要ポイント:

  • LDAPは読み取り特化のツリー型データベースである。
  • エントリはDN(絶対パス)で特定され、オブジェクトクラス(型)によって構造が決まる。
  • スキーマは厳格であり、安易な独自拡張は避けるべき。
  • DIT設計は「フラット」が正義。組織構造を階層に持ち込まない。
ウィンドウズ先生

Active Directoryも、内部的にはLDAPそのものです。
今回学んだ「CN」「DN」「オブジェクトクラス」といった概念は、ADをPowerShellで操作する際にもそのまま役立ちます。
基礎理論は裏切りませんよ。

さて、理論武装は完了しました。
次回はいよいよ、実際にサーバーに触れていきます。

次回、第2回は「インストールと初期設定。slapdの起動と動作確認」です。
RHEL/AlmaLinux環境にOpenLDAPをインストールし、管理者パスワードを設定して、最初の検索クエリを投げるところまでを解説します。お楽しみに!

▼ OpenLDAPを構築してみる ▼

学習用サーバーを立てる
「おすすめVPS」

おすすめVPSを見る

インフラエンジニアとして活躍
「ITエンジニア転職」

転職エージェントを見る

コメント