【OpenLDAP基本講座 第4回】データ管理の作法。LDIFを制する者はLDAPを制す(登録・検索・更新・削除)

SQLが使えない世界で、データを自在に操るために。

こんにちは!「LINUX工房」管理人の「リナックス先生」です。
前回は、OpenLDAPの設定をつかさどる cn=config の仕組みと変更方法について学びました。
サーバーの「枠組み」は完成しました。いよいよ、その中に「魂(ユーザーデータ)」を吹き込む時です。

しかし、ここで多くのRDBMS(MySQLなど)経験者が混乱します。
SELECT * FROM users ってどうやるの?」
「データを1行書き換えるだけなのに、なんでこんなに行数の多いテキストファイルを書かないといけないの?」

コウ君

先生、まさにそれです!
ユーザーのメールアドレスを変えたいだけなのに、changetype: modify とか replace: mail とか書いて、さらにハイフン - で区切って……。
書き方を間違えて「Syntax Error」って言われるのがトラウマになりそうです。
もっと簡単な方法はないんですか?

リナックス先生

コウ君、その「面倒くささ」には理由があるの。
LDAPは「階層型」かつ「マルチバリュー(1つの属性に複数の値が入る)」なデータベースだから、SQLのような単純な更新ができないのよ。
でも、LDIF (LDAP Data Interchange Format) のルールさえ理解してしまえば、どんな複雑なデータ操作も思いのままよ。
今回は、プロのエンジニアが息をするように使いこなしているコマンド群と、LDIFの書き方を徹底的にマスターしましょう!

ウィンドウズ先生

はい、ウィンドウズ先生です。
Active Directoryの世界ではGUIやPowerShellを使いますが、裏側では同じLDAPプロトコルが動いています。
今回学ぶ ldapsearch のフィルタ構文などは、ADを操作する際にもそのまま使える共通スキルです。
「Linuxだから」と身構えず、ディレクトリサービスの共通言語として習得してください。

本記事では、LDIFフォーマットの詳細なルール、ldapadd によるデータ登録、ldapsearch による高度な検索、そして最も難易度が高い ldapmodify によるデータ更新・削除の手順を、実例を交えて解説します。

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


第1章:LDIFフォーマットの厳格なルール

OpenLDAPにおいて、データのやり取りはすべて LDIF (LDAP Data Interchange Format) というテキスト形式で行われます。
人間が読み書きできるシンプルな形式ですが、ルールは厳格です。
まずは「エラーにならない書き方」を覚えましょう。

LDIFの基本構造

dn: uid=taro,ou=People,dc=linuxkoubou,dc=com
objectClass: inetOrgPerson
cn: Taro Yamada
sn: Yamada
mail: taro@linuxkoubou.com

守るべき5つの鉄則

  1. コロンの後は必ず半角スペース:
    cn:Taro はエラーです。cn: Taro と書く必要があります。
  2. DNは必ず先頭:
    すべてのエントリ記述は、その識別名を示す dn: から始まらなければなりません。
  3. 継続行は行頭スペース:
    行が長すぎて改行したい場合、次の行の先頭に半角スペースを入れます。

    description: This is a very long description that spans
     multiple lines in the LDIF file.
  4. バイナリ/マルチバイトはBase64:
    日本語を含む値や、画像データなどはBase64エンコードし、コロンを2つ (::) にします。
    例:cn:: 5bGx55SwIOWkqumDjg== (山田 太郎)
  5. エントリ間は空行で区切る:
    複数のユーザーを1つのファイルに書く場合、必ず空行を入れて区切ります。

💡 プロのTips:日本語の扱い
最近の ldapadd コマンドはUTF-8を直接扱える場合もありますが、環境によっては文字化けします。
確実に登録するためには、Linuxコマンドで echo -n "山田 太郎" | base64 を実行し、その結果を cn:: ... として貼り付けるのが最も安全です。


第2章:データの登録 (ldapadd)。まずは土台作りから

それでは、空っぽのディレクトリにデータを入れていきましょう。
まずはユーザーやグループを格納する「箱(Organizational Unit)」を作ります。

1. ベースOUの作成

base.ldif を作成します。

dn: ou=People,dc=linuxkoubou,dc=com
objectClass: organizationalUnit
ou: People

dn: ou=Groups,dc=linuxkoubou,dc=com
objectClass: organizationalUnit
ou: Groups

コマンドで投入します。

ldapadd -x -D "cn=Manager,dc=linuxkoubou,dc=com" -W -f base.ldif
  • -x: 簡易認証(SASLを使わず、パスワード認証を行う)。
  • -D: バインドDN(管理者ユーザーのDN)。第2回で設定したものです。
  • -W: パスワードをインタラクティブに入力する(履歴に残さないため)。
  • -f: 読み込むLDIFファイル。

2. グループの作成

Linuxの /etc/group に相当するエントリです。
group.ldif を作成します。

dn: cn=developers,ou=Groups,dc=linuxkoubou,dc=com
objectClass: posixGroup
cn: developers
gidNumber: 1001

同様に ldapadd で投入します。

3. ユーザーの作成

Linuxユーザーとしてログイン可能なエントリを作成します。
user.ldif を作成します。

dn: uid=taro,ou=People,dc=linuxkoubou,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: taro
cn: Taro Yamada
sn: Yamada
uidNumber: 1001
gidNumber: 1001
homeDirectory: /home/taro
loginShell: /bin/bash
userPassword: {SSHA}Gu5... (slappasswdで生成したハッシュ)

投入コマンドは同じです。
これで、最初のユーザー「taro」が誕生しました。

💡 プロのノウハウ:slapadd vs ldapadd
ldapadd は稼働中のLDAPサーバーに対してネットワーク経由でデータを送ります。
一方、slapadd はサーバーを停止した状態で、データベースファイルに直接書き込みます。
数万件のデータを初期ロードする場合は、slapadd の方が圧倒的に高速です(インデックス生成などをまとめて行うため)。日常的な追加は ldapadd を使いましょう。


第3章:データの検索 (ldapsearch)。欲しい情報を1秒で見つける

データが入ったら、正しく入っているか確認します。
ldapsearch はLDAP管理者にとっての「目」です。

基本の検索コマンド

ldapsearch -x -b "dc=linuxkoubou,dc=com" "(uid=taro)"
  • -b: 検索を開始するベースDN。ここから下を検索します。
  • "(uid=taro)": 検索フィルタ。SQLのWHERE句に相当します。

検索フィルタの書き方

LDAPのフィルタは、ポーランド記法(前置記法)のような独特な書き方をします。

条件 書き方
一致 (属性=値) (uid=taro)
ワイルドカード (属性=*値*) (cn=*Yamada*)
AND (かつ) (&(条件1)(条件2)) (&(objectClass=posixAccount)(uid=taro))
OR (または) (|(条件1)(条件2)) (|(uid=taro)(uid=hanako))
NOT (否定) (!(条件)) (!(uid=root))

出力を見やすくするオプション (-LLL)

デフォルトの出力はコメント行などが多くて見づらいです。
-LLL オプションを付けると、純粋なLDIF形式のみが表示されます。

ldapsearch -x -LLL -b "dc=linuxkoubou,dc=com" "(uid=taro)" cn mail

末尾に属性名(cn mail)を指定すると、その属性だけを表示します(SELECT句に相当)。

運用管理用の隠し属性を見る (+)

通常は見えない「作成日時」や「更新者」などの運用属性を見たい場合は、属性指定に + を使います。

ldapsearch -x -LLL -b ... "(uid=taro)" +

createTimestampmodifiersName が表示され、トラブルシューティング時に「誰がいつ変更したか」を知るのに役立ちます。


第4章:データの更新 (ldapmodify)。最大の難所を攻略する

ここがOpenLDAPの最難関です。
データの追加(Add)は簡単ですが、変更(Modify)には changetype という概念が必要になります。

modifyの基本構造

dn: uid=taro,ou=People,dc=linuxkoubou,dc=com
changetype: modify
[操作タイプ]: [属性名]
[属性値]
-
[次の操作...]

操作タイプ:add, replace, delete

この3つの違いを明確に理解していないと、データを壊します。

  1. add: 属性に値を追加する。
    LDAPは「マルチバリュー」なので、1つの属性に複数の値を持てます。
    例:メールアドレスをもう一つ追加する。
  2. replace: 属性の値を全置換する。
    既存の値はすべて消え、新しい値だけになります。
    例:メールアドレスを間違えたので修正する。
  3. delete: 属性の値を削除する。
    値を指定しないと属性ごと削除、値を指定するとその値だけを削除します。

実践例1:メールアドレスの修正

「taro@old.com」を「taro@new.com」に変更したい場合。

# modify_mail.ldif
dn: uid=taro,ou=People,dc=linuxkoubou,dc=com
changetype: modify
replace: mail
mail: taro@new.com

コマンド: ldapmodify -x -D "cn=Manager,..." -W -f modify_mail.ldif

実践例2:説明文の追加と、古い電話番号の削除(複合技)

一度の操作で複数の変更を行うには、ハイフン - で繋ぎます。

# modify_complex.ldif
dn: uid=taro,ou=People,dc=linuxkoubou,dc=com
changetype: modify
add: description
description: New Employee
-
delete: telephoneNumber
telephoneNumber: 03-0000-0000

💡 失敗談:replaceの罠
マルチバリュー属性(例:description に3つの値が入っている)に対して、1つだけ修正しようとして replace を使い、残り2つを書き忘れると……。
書き忘れた2つは消滅します。
部分的な修正を行う場合は、delete(古い値)と add(新しい値)を組み合わせて行うのが安全です。


第5章:データの削除と移動 (ldapdelete / ldapmodrdn)

エントリ自体を消す場合や、DNを変更する場合の操作です。

エントリの削除 (ldapdelete)

DNを指定して削除します。LDIFファイルでも可能ですが、引数で直接指定することも多いです。

ldapdelete -x -D "cn=Manager,..." -W "uid=taro,ou=People,dc=linuxkoubou,dc=com"

注意: 子エントリを持つエントリ(OUなど)は削除できません。先に子をすべて消す必要があります(-r オプションで再帰削除も可能ですが、危険なので推奨しません)。

エントリの移動・改名 (ldapmodrdn)

「ユーザー名を taro から tarou に変えたい(RDNの変更)」
「People OU から Contractors OU に移動させたい(親の変更)」
こういう時は ldapmodrdn を使います。

# ユーザー名変更 (taro -> tarou)
ldapmodrdn -x -D "cn=Manager,..." -W "uid=taro,ou=People,dc=..." "uid=tarou"
  • -r オプションを付けると、古いRDN値(uid=taro)を属性から削除します。付けないと、uid 属性に tarotarou の両方が残ります。

第6章:パスワード管理 (ldappasswd)。安全な変更手順

パスワード変更は ldapmodifyuserPassword 属性を置換することでも可能ですが、平文をファイルに残すのは危険です。
専用コマンド ldappasswd を使いましょう。

管理者による強制リセット

ldappasswd -x -D "cn=Manager,..." -W -S "uid=taro,ou=People,dc=..."
  • -S: 新しいパスワードの入力を求めるプロンプトを表示します。

ユーザー自身による変更

ユーザーが自分自身のパスワードを変更する場合、-D には自分自身のDNを指定します。

ldappasswd -x -D "uid=taro,ou=People,dc=..." -W -S

※これを許可するには、適切な ACL (Access Control List) の設定が必要です(第5回で解説します)。


第7章:バックアップとリストア (slapcat / slapadd)

データ管理の最後は、バックアップです。
LDAPのバックアップは、DBファイルをコピーするのではなく、LDIF形式でエクスポートするのが鉄則です。

バックアップ (slapcat)

OpenLDAPが稼働中でも実行可能です。

# データバックアップ
slapcat -n 2 -l backup_data.ldif

# 設定バックアップ (cn=config)
slapcat -n 0 -l backup_config.ldif

-n 2 はバックエンドデータベース番号です。環境によって異なるので確認してください。

リストア (slapadd)

リストア時は、必ずサービスを停止し、既存のDBファイルを削除(または退避)してから行います。

systemctl stop slapd
rm -rf /var/lib/ldap/* # DBディレクトリをクリア
slapadd -n 2 -l backup_data.ldif
chown -R ldap:ldap /var/lib/ldap
systemctl start slapd

まとめ:LDIFはエンジニアへの手紙である

お疲れ様でした!
第4回は、OpenLDAPの運用で最も重要な「データ操作」について徹底解説しました。

今回の重要ポイント:

  • LDIFはルールが命。コロン後のスペースと改行ルールを厳守する。
  • 検索フィルタ(AND, OR, NOT)を使いこなせば、欲しいデータは一瞬で取れる。
  • 更新 (modify) は replaceadd の違いを意識し、ハイフンで区切る。
  • 大量データの投入は slapadd、日常の更新は ldapadd/modify
ウィンドウズ先生

LDIFを書くのは最初は苦痛かもしれませんが、慣れると「システムに対する手紙」のように思えてきます。
「このユーザーのメールアドレスを、こう書き換えてください」という指示書なのです。
これをスクリプト化できるようになれば、あなたはもうLDAPマスターへの道を半分以上進んでいますよ。

さて、データは入りましたが、今の状態だと「誰でも全データを検索し放題」というセキュリティ上の問題があります。
次回は、LDAPサーバーを守るための「アクセス制御」について学びます。

次回、第5回は「アクセス制御 (ACL)。olcAcessの読み方・書き方」です。
「自分のパスワードは自分で変更できるけど、他人のパスワードは見えない」といったルールをどのように記述するのか、プロの設計論を解説します。お楽しみに!

▼ データ操作を練習する ▼

自由に壊せるLDAPサーバーを
「おすすめVPS」

おすすめVPSを見る

ミドルウェア運用を極める
「ITエンジニア転職」

転職エージェントを見る

コメント