前回はLDAPの実用性を分かっていただくため、各パラメータの意味などは一切省略してUNIXアカウントを統合するためのLDAPサーバを構築してみたわけですが、今回はそれぞれの設定パラメータについて解説していきたいと思います。
サーバ設定のパラメータ
それでは、まずはOpenLDAPサーバの設定から見ていきましょう。前回はリスト1 の内容を用いていました。
リスト1 /etc/openldap/slapd.conf(第1回と同じもの)
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema
pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args
database bdb
suffix "dc=example,dc=com"
rootdn "cn=Manager,dc=example,dc=com"
rootpw secret
directory /var/lib/ldap
このリスト1は、あくまでも基本的な設定のみを列挙したものです。本格的な設定を行う場合は、OpenLDAPのマニュアルや日本LDAPユーザ会 スタッフ 稲地さん のOpenLDAP情報 などをご覧ください。
各パラメータの意味は次の通りです。
include スキーマファイル名
スキーマファイルを指定します。LDAPサーバはデータ格納用のサーバとなりますが、何でも好きなデータを格納できるわけではありません。自分が好きなデータを使用するには、あらかじめその内容をスキーマファイルという定義ファイルに定めておく必要があるのです。OpenLDAPをインストールすればさまざまなスキーマファイルがインストールされますので、住所や電話番号、メールアドレスなど標準的なスキーマは整っています。
pidfile PIDファイル
slapdのPIDが保存されます
argsfile argsファイル名
slapd起動時のコマンドラインオプションが保存されます
database
バックエンドデータベースの形式を定義します。bdb(Berkeley DB形式)を用いるのが一般的ですが、ldbmなどその他の形式を用いることが可能です。
suffix
日本語訳では「接尾辞」となりますが、データツリーのベース部分とでも覚えておけば良いでしょう。今回の場合dc=example,dc=com という値を定義することで、以降のすべてのデータはこのツリーの下に保存されることになります。
rootdn
管理者DNを定義します。この言葉は聞き慣れないものだと思いますので、管理者IDと考えても差し支えないでしょう。
rootpw
上記管理者のパスワードを定義します。ここでは平文で定義していますが、SSHA形式などエンコードされた値を用いるのが一般的です。
directory
データの実体を保存するディレクトリです。
LDAPとツリー
ツリー という言葉が出てきましたね。LDAPではデータをツリーで表現します。たとえばデータは次のような場所に格納されます。
uid=nakamitsu,ou=PreSales,o=F5Networks
nakamitsuというデータはF5Networks組織のPreSales部にあることがわかります。ここで用いられるuid やou などの値は「属性 」と呼ばれ、uidはユーザIDを示す、ouは組織単位を表す、などと決められています。
データをツリーで表現することのメリットは何でしょうか? たとえば日本全国民の個人データベースがあり、そこから筆者の情報を引き出すことを考えてみましょう。データが1冊の電話帳のような形式であった場合、1件1件順番に検索していたのでは、非常に効率が悪いことがわかります。
それでは電話帳が1冊ではなく、都道府県別に用意されていた場合はどうでしょうか? 筆者は東京在住ですので、東京都の電話帳のみから検索を行えば良いことがわかります。さらにその東京都の電話帳が区別に記載されていれば新宿区のみから検索を行えばさらにターゲットを絞ることができます。この例をLDAP的に表現すると、次のような形となります。
氏名=中満英生,町=高田馬場,区=新宿区,都道府県=東京都,国=日本
このように、データがどのツリーの下に所属しているのかが判明していた場合、つまり私の住所が新宿区高田馬場にあるとあらかじめわかっていた場合には、全国のデータベースから検索を行う必要がなく、限られた高田馬場データベースから検索を行えば良いことになり、当然検索速度も全国からの検索に比べると圧倒的に速いことがわかります。
LDIFとは?
次にLDIF(LDAP Data Interchange Format) 形式のファイルについて説明します。LDAPサーバ内の実データはBDB形式などのバイナリファイルで管理されている場合が多く、これらのデータベースを操作してデータの追加や削除を行うのは容易なことではありません。LDIF形式のファイルやエントリを編集することで、簡単にデータを操作することができます。LDIF形式とはテキストデータであり、データを
属性: 値
または
属性:: Base64エンコードされた値
という形で示します。注意点としては、日本語などのマルチバイト文字を含むデータはUTF-8 で定義してください。前回用いたUNIXアカウントはリスト2 のLDIFで定義されていました。
リスト2 UNIXアカウントのLDIFファイルの例
dn: uid=ldapuser,ou=People,dc=example,dc=com
objectClass: account
objectClass: posixAccount
uid: ldapuser
cn: ldapuser
userPassword: ldapuser
loginShell: /bin/bash
uidNumber: 1000
gidNumber: 1000
homeDirectory: /home/ldapuser
1行目のdnからはじまる行は少し特殊で、このエントリが定義される位置を示します。つまりリスト2の例ではldapuser というユーザのエントリがou=People, dc=example, dc=com というツリーの直下にあることを意味しています。
ldapaddやldapdelete
LDIFで作成したデータをLDAPサーバに登録したり、また特定のデータを削除したりするにはLDAPクライアントコマンドを使用します。よく使用されるのは次のコマンドです。
ldapadd
ldapdelete
ldapmodify
これらのコマンドに関しては以降の連載でも使用する機会が出てきますので、必要に応じて解説していきます。
スキーマとは?
さて、リスト2のLDIFを見ると、属性名としてuid やcn といった値が使用されています。見た目からuidはユーザIDを表す、uidNumberはUID番号、homeDirectoryはユーザのホームディレクトリを表すことが予想できますが、アカウントエントリを初めて追加する場合は、どのような属性を使用すれば良いかわからないはずです。
ここで必要となるのがスキーマ の概念です。冒頭で簡単に触れたように、データを操作するためには適切なスキーマの定義が必要になります。試しに/etc/openldap/schemaにあるcore.schema とnis.schema の中身を見てみましょう。
リスト3 core.schemaの一部
attributetype ( 0.9.2342.19200300.100.1.1
NAME ( 'uid' 'userid' )
DESC 'RFC1274: user identifier'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
リスト4 nis.schemaの一部
attributetype ( 1.3.6.1.1.1.1.0 NAME 'uidNumber'
DESC 'An integer uniquely identifying a user in an administrative domain'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount' SUP top AUXILIARY
DESC 'Abstraction of an account with POSIX attributes'
MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
MAY ( userPassword $ loginShell $ gecos $ description ) )
まず忘れてはならないのは、あるデータをLDAP内に格納するためには、適切なオブジェクトクラス を必ず定義する必要がある点です。
再びUNIXアカウントを登録したい場合を考えてみましょう。
まずは「UNIXアカウントを登録したい。最初にオブジェクトクラスを定義しなければならないんだったな。どのオブジェクトクラスを選べばよいのだろう?」と考えるはずです。
すでにLDAPスキーマに精通している人であれば、「 UNIXアカウントであればposixAccountオブジェクトクラス」と一発でひらめくかも知れませんが、そうでない場合はGoogleなどで検索したり、すべてのスキーマファイルを参照し、パスワードやホームディレクトリなどが含まれているオブジェクトクラスを見つければ良いでしょう。
見つけ方の例としては、
UNIXアカウントにはホームディレクトリ(homeDirectory)が必要
homeDirectory属性はどのスキーマで定義されている?(grep homeDirectory *)
objectClass: posixAccountに定義されているようだ。
さらにobjectClass: posixAccountを用いる場合、cnやuid属性も必須らしい
という感じの流れでしょうか。
いずれにせよ、LDAPに触れていれば、自然と「○○のデータを登録する場合には□□というobjectClassを使用する」ということがわかってくるはずです。
LDAPサーバを参照するためのLinuxサーバの設定
前回はauthconfigコマンド でLDAP参照・認証用の設定を行いましたが、このコマンドを用いることで、サーバには後述の変化が発生します。authconfigコマンドの実行時に、次の2つのLDAP設定項目が出てきましたが、皆さんは覚えていらっしゃいますか?
User InformationのUse LDAPオプション
AuthenticationのUse LDAP Authenticationオプション
前者は文字通りユーザ情報をLDAP上から拾ってくるための設定であり、ネームサービススイッチ設定ファイルである/etc/nsswitch.conf を更新します。従来、ユーザやグループの情報は/etc/passwdや/etc/group ファイルに蓄積されていますが、nsswitch.confの一部をリスト5 のように更新することで、LDAP上のユーザ情報が参照されるようになります。
リスト5 nsswitch.confの変更ポイント
設定前
passwd: files
shadow: files
group: files
protocols: files
services: files
netgroup: files
automount: files
設定後
passwd: files ldap
shadow: files ldap
group: files ldap
protocols: files ldap
services: files ldap
netgroup: files ldap
automount: files ldap
また、これだけではLDAPサーバの場所がわかりませんので/etc/ldap.confに接続先の情報などを定義しておく必要がありますが、authconfigコマンドはそれを自動的に行ってくれます。
さて、nsswitch.confの設定を行うことで「ユーザ情報はLDAP上にある」という設定を実現することができるのですが、認証時の設定はまた別です。認証のために用いられる仕組み、そうPAM です。PAMの設定は/etc/pam.d以下のファイルを編集することで実現できますが、PAMは奥が深く、ページの都合上詳しく解説することができません。PAMに限らず、本連載ではさまざまな項目の解説が不十分であることは承知しています。が、それらの解説に分量を使ってしまうと、とくにお伝えしたいLDAPの機能が紹介できないのが実情です。ご了承ください。(^^;
ここではauthconfigの実行前後のdiffのみを紹介します(リスト6 ) 。pam_ldapが追加されていることがわかりますね?
リスト6 /etc/pam.d/system-authの更新内容
diff -ur etc.orig/pam.d/system-auth etc/pam.d/system-auth
--- etc.orig/pam.d/system-auth 2007-04-07 23:41:15.000000000 +0900
+++ etc/pam.d/system-auth 2007-07-08 22:58:26.000000000 +0900
@@ -3,15 +3,19 @@
# User changes will be destroyed the next time authconfig is run.
auth required /lib/security/$ISA/pam_env.so
auth sufficient /lib/security/$ISA/pam_unix.so likeauth nullok
+auth sufficient /lib/security/$ISA/pam_ldap.so use_first_pass
auth required /lib/security/$ISA/pam_deny.so
-account required /lib/security/$ISA/pam_unix.so
+account required /lib/security/$ISA/pam_unix.so broken_shadow
account sufficient /lib/security/$ISA/pam_succeed_if.so uid
今回もかなり駆け足でしたが、OpenLDAPの基本的な部分をお伝えしたつもりです。本連載は「いろいろなソフトウェアとLDAPを連携させる」ということに主眼を置いています。次回以降はそういった部分に少しでも触れていければ幸いです。