なぜ、データベース(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.com の People 部署にいる 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つの種類があります。
- ABSTRACT(抽象型): 基礎となる型。直接は使えません。すべてのエントリは
topという抽象クラスを継承します。 - STRUCTURAL(構造型): エントリの実体を表す型。1つのエントリに必ず1つ以上必要です(例:
inetOrgPerson)。 - 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にログインできるユーザーを作りたい場合、そのエントリには inetOrgPerson と posixAccount と shadowAccount の3つのクラスを付与することになります。
第4章:厳格なルールブック。スキーマと属性
オブジェクトクラスが決まると、そのエントリで「使える属性(Attribute)」と「必須の属性」が決まります。
この定義書のことを スキーマ (Schema) と呼びます。
MUST と MAY
スキーマには、各オブジェクトクラスに対して以下の定義がされています。
![]() |
[試して理解]Linuxのしくみ ―実験と図解で学ぶOS、仮想マシン、コンテナの基礎知識【増補改訂版】 新品価格 |
- MUST (必須属性): これがないとエラーになり、エントリを作成できません。
例:inetOrgPersonならcn(Common Name) とsn(Surname: 姓) が必須です。 - MAY (任意属性): あってもなくても良い属性。
例:mail,telephoneNumber,descriptionなど。
属性の「構文 (Syntax)」と「照合規則 (Matching Rule)」
各属性には、データの型(文字列、数値、バイナリ)や、検索時の挙動が定義されています。
- Case Ignore String (CIS): 大文字と小文字を区別しない。
例:uid=Taroとuid=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は容赦なくエラーを吐きます。
基本ルール
- dnで始める: 最初の行は必ず
dn: ...で、対象のエントリを指定します。 - 属性: 値:
属性名: 値の形式で書きます。コロンの後は半角スペースが1つ必須です。 - 空行で区切る: 複数のエントリを書く場合、間には必ず空行を入れます。
- 継続行: 行が長すぎる場合、次の行の先頭にスペースを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」
インフラエンジニアとして活躍
「ITエンジニア転職」


コメント