2005/8/14

openldapでBecky!のアドレス帳管理(FreeBSD, Internet)

自宅サーバにopenldap 2.2.27を入れ、 WindowsのメーラからLDAPサーバ上のアドレス帳を検索できるように設定しました。

実はLDAPの設定は今回が始めてて勉強がてら設定したものをメモとして公開します。

今回のポリシーは以下の通り。

  • 世間ではsambaや各種MTAのアカウント管理にLDAPを使う話題満載だが、うちの環境ではユーザは二人しかいないため、 完全に不要
  • それでも何かLDAPで管理してみたい!
  • そうだ、会社の人のメールアドレス一覧を管理して、自宅と会社の両方のメーラで参照できたら便利かも
  • 他の社員の方にも使って貰いたいけど、全然関係ないanonymousな人は全くアクセスできない設定が必要だ

普段はBecky!を愛用していますが、一応Outlook Expressでもそれなりに情報が検索できるような最低限のデータを登録しました。

■openldapのインストール

FreeBSDのportsを見てみると、net/openldap23というディレクトリがあったので、どうせなら最新を… と思ってmake installしたら、openldap-clientに既に2.2.27が入っていました。どうやら、 samba3を入れると勝手にopenldap22-clientがインストールされる模様。

別にこだわりはないので、サクっとnet/openldap22-serverをインストールしました。 databases/db42も一緒にインストールされます。

■設定を始めに決めましょう

LDAPではDN(Distinghished Name)という一意となる名前でその中の属性(Attribute)にアクセスします。DNの中でも根っことなる部分のDNを決めます。 DNはサーバ内で一意となれば良く、ドメイン名の様に全世界でユニークになる必要はないのでなんでも良いのですが、 もし自分が独自ドメインを持っていたらそれを指定しましょう。

具体的には私のサーバだったら「dc=hijiki,dc=net」となります。別に「dc=test,dc=com」でも、 「dc=hogehoge」でも構いません。dc=???は幾つでも書けます。今回は「dc=test」で説明します。

また、今回は以下の二つのカテゴリをdc=test配下に作ります。 カテゴリといっても実際はou(organizationalUnit)という組織単位を作成します。

  • People
    LDAPユーザ認証を行うためのユーザを管理するou
  • AddressBooks
    クライアントのメーラから参照できるアドレス帳を管理するou

アクセスポリシーとしては、 People内のユーザで認証したユーザのみがAddressBooks配下のDNにアクセスできる様に設定するため。 People=誰でも読める。AddressBooks=認証を受けた人だけが読める。という設定にします。

■設定ファイルを書き換えましょう

前述の事を全部openldapの設定ファイルである/usr/local/etc/openldap/slapd.confに設定します。また、 デフォルトのslapd.confでは使用できるobjectClass(テンプレートみたいなもの)が限られているので、適宜追加します。

rootdnのcn(管理者)の名前は「Manager」にします。rootpwに指定するパスワードは「slappasswd -s hogehoge」等を実行し、 出力された結果をコピペします。

[/usr/local/etc/openldap/slapd.conf]
include /usr/local/etc/openldap/schema/core.schema
# 標準的なスキーマを追加する
include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/inetorgperson.schema
include /usr/local/etc/openldap/schema/nis.schema

pidfile /var/run/openldap/slapd.pid argsfile /var/run/openldap/slapd.args

# ou=People配下は誰でも読み込み可能
access to dn.children="ou=People,dc=test"
    by * read

# 認証を受けた人以外は読み込み不可。オマケに管理者以外は設定変更も不可
access to * by dn="cn=Manager,dc=test"
    read by self
    read by users
    read by * none

database bdb

# ルートオブジェクト及びrootdnで管理者をcn(Common Name)=Managerに設定
suffix "dc=test"
rootdn "cn=Manager,dc=test"
rootpw {SSHA}O1pmjDEul8MHY/50djtr0vK3/yIlXEjN

directory /var/db/openldap-data
index objectClass eq

# cn(CommonName)は含む・部分一致・完全一致でインデックスを作成
index cn eq,pres,sub

■slapdを起動しましょう

それでは起動しましょう。先ずは/etc/rc.confに以下の行を追加します。

[/etc/rc.conf]
slurpd_enable="NO"
slapd_enable="YES"

slurpdはLDAPのデータベースを他のサーバと同期を取るためのデーモンです。今回は設定しません。

後は再起動するか、以下のコマンドを打ち込んでldapサーバを起動します。

# /usr/local/etc/rc.d/slapd.sh start

自動的にルートオブジェクトが作成される筈です。以下のコマンドで確認してみましょう。

#slapcat
dn: dc=test
structuralObjectClass: organization
entryUUID: 0123962c-9eba-1029-8b49-cf50ad9366e7
creatorsName: cn=Manager,dc=test
createTimestamp: 20050811134604Z
objectClass: dcObject
objectClass: organization
dc: test
entryCSN: 20050813102237Z#000001#00#000000
modifiersName: cn=Manager,dc=test
modifyTimestamp: 20050813102237Z

…とりあえず何か出れば大丈夫だと思います(笑)

■ouの作成とアクセス用ユーザの作成

それでは前の方の章で決めたAddressBooksとPeopleのouを作成します。更にPeopleのouの中に「guest」というアカウントも設定しましょう。

guestアカウントのパスワードを先に作ります。また「slappasswd -s hogehoge」を実行して、結果をどこかに取っておきます。ちなみに本当にパスワードに「hogehoge」を指定すると「{SSHA}VJ1VYMn4DSLKwQv/aMTqPqvs7GdliZnW」となります。

以下のファイルを作成しましょう。細かいことは割愛しますが、guestユーザ登録時に指定しているuidNumber,gidNumber,homeDirectory,cnは適当でいいです。

今回はこのDNではuidとuserPasswordしか使用しませんが、このオブジェクトで指定しているposixAccount,accountではこれらが必須項目となっているので何かしら指定しなければなりません。

[/tmp/first.ldif]
dn: ou=AddressBooks,dc=test
ou: AddressBooks
objectClass: organizationalUnit

dn: ou=People,dc=test
ou: People
objectClass: organizationalUnit

dn: uid=guest,ou=People,dc=test
objectClass: posixAccount
objectClass: account
uidNumber: 100
gidNumber: 100
homeDirectory: /
uid: guest
cn: guest
userPassword: {SSHA}Vsb2fbGxsKkcJEWE5iTYSgoaCTMUfWdi

では登録しましょう。以下のコマンドを打ち込んで結果を確認します。

# ldapadd -D "cn=Manager,dc=test" -w hogehoge -f /tmp/first.ldif
adding new entry "ou=AddressBooks,dc=test"

adding new entry "ou=People,dc=test"

adding new entry "uid=guest,ou=People,dc=test"
# 

それでは本当にguestアカウントが登録されているか確認してみましょう。コマンドはldapsearchを使います。

# ldapsearch -x -D 'cn=Manager,dc=test' -w hogehoge \
  -b 'ou=People,dc=test' -s one '(uid=guest)' uid userPassword
# extended LDIF
#
# LDAPv3
# base <ou=People,dc=test> with scope one
# filter: (uid=guest)
# requesting: uid userPassword
#

# guest, People, test
dn: uid=guest,ou=People,dc=test
uid: guest
userPassword:: e1NIQX1XMzdPMzJnNW1wMGtzVG1qL01yczNMZXlhTFU9

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1
# 

上記例ではManager権限でDN:People,dc=test配下でuidがguestと一致するオブジェクトのuidとuserPasswordを表示するという指定です。
userPasswordが最初に入力した値と異なりますが、よく見るとコロンが二つついています。これはその行は各種方式でエンコードされている行という意味で、この場合はバイナリ形式で保存されている意味になります。

■ou=AddressBooks内を登録する前に…

実はLDAPで登録するオブジェクトの各種属性(Attribute)は使用するメーラによって、どの属性をどの項目に設定するかが、まちまちで統一されていません。

今回はメールアドレスを管理するobjectClassにinetOrgPersonというものを使います。inetOrgPersonはorganizationalPersonを継承し、更にorganizationalPersonはpersonを継承してしますが、必須項目はこのpersonにあるsn(SurName(姓))とcn(CommonName(識別子))だけとなっています。

つまり、sn,cn以外は好きな物を登録すればいいのですが、今回はメールアドレスを管理したい訳ですから、以下の物を登録します。

Becky!とOutlook Expressでどの項目に設定されるかも併せて表にしてみました。

Attribute 説明 Becky! Outlook Express
cn(commonName) フルネーム Yoshimasa Katakura 宛先名(検索可) 表示名(検索可)
sn(surname) Katakura - 姓(検索可)
gn(givenName) Yoshimasa - 名(検索可)
mail(rfc822Mailbox) メールアドレス yotan@hijiki.net メールアドレス(検索可) 電子メールアドレス(検索可)
ou(organizationalUnitName) 部署名 MyHome 所属組織(左) 部署名
o(organization) 所属 ひじき 所属組織(右) 会社名
description 備考 備考欄です 設定により備考に表示(検索可) -

つまり、どうせsnは必須項目だったら、Becky!しか使わなくてもgnも登録してしまいましょう。あとついでにdescriptionに日本語表記の名前でも入れておけばBecky!で検索一覧に表示できるので嬉しいです。

というわけで上記Attributeを持ったオブジェクトをou=AddressBooks,dc=test配下に沢山登録しましょう。

■ldifファイルの準備

登録したい情報をldif形式のファイルを作成して、一括登録します。前の方の章でAddressBooks,Peopleを登録したときと同じ要領なのですが、一つ注意して頂きたいのが「日本語はUTF-8形式で登録」という事です。
まあ、これを読んでいる人はFreeBSDなりLinuxを使っているので文字コード変換は大丈夫ですよね?とりあえずSJISでもEUCでもいいから、以下の感じでファイルを準備します。

一つのファイルに複数のオブジェクトが登録できます。途中に空の行を一つ以上入れるのを忘れないように。

[/tmp/mail.euc.ldif]
dn:cn=Yoshimasa Katakura,ou=AddressBooks,dc=test
o:ひじき
gn:Yoshimasa
sn:Katakura
ou:MyHome
mail:yotan@hijiki.net
objectClass:inetOrgPerson
cn:Yoshimasa Katakura
description:備考

dn:cn=foo bar,ou=AddressBooks,dc=test
o:でたらめ
gn:foo
sn:bar
ou:MyHome
mail:foo.bar@example.net
objectClass:inetOrgPerson
cn:foo bar
description:名無しさん

…こんなファイルを一つ一つ手で入れるのはお猿さんのやる仕事ですね。私は以下の手順で変換しました。

  • 社内向けWebサイトから社員メールアドレス一覧を取得
  • メールアドレスが「名.姓@ドメイン名」なので、gawkを使ってgn,snを取得
  • 出来たテキストをExcelにコピー
  • o,ou,descriptionを手で編集
  • csv形式で出力してFreeBSDマシンに転送→とりあえずEUCに変換
  • ちょっとしたperlスクリプトを書いて、csvファイルから上記ldifファイルを出力
  • nkf -wでUTF-8に変換>/tmp/mail.utf-8.ldifの完成

手作業ももちろん必要ですが、Excelで編集すれば楽ちんですね。手作業もありましたが、社員数50人程度の弱小企業なので、部署名の入力もそんなに時間がかかりませんでした。

さあファイルの準備ができたら、先にもやりましたが以下のコマンドで登録をしましょう。

# ldapadd -D "cn=Manager,dc=test" -w hogehoge -f /tmp/mail.utf-8.ldif
adding new entry "uid=Yoshimasa Katakura,ou=AddressBooks,dc=test"
       :                 :
       :                 :
#

■インデックス再作成

ou=AddressBooks,dc=testに沢山のオブジェクトが追加されましたので、インデックスの再作成を行います。

# slapindex -b "ou=AddressBooks,dc=test"

…多分これで大丈夫だと思います。slapd.confでindexにcnを設定したので、名前による検索が高速になった筈です。

■動作確認

最初に説明したとおり、今回のLDAPサーバはユーザ認証が出来たクライアントからしか読み込みを許可しない設定になっています。

まずは、ユーザ認証なしで検索してみて何も引っかからないパターンを確認します。

# ldapsearch -x -b 'ou=AddressBooks,dc=test' -s one '(cn=*taku*)' cn mail
# extended LDIF
#
# LDAPv3
# base <ou=AddressBooks,dc=test> with scope one
# filter: (cn=*taku*)
# requesting: cn mail
#

# search result
search: 2
result: 0 Success

# numResponses: 1

ハイ、ユーザ認証しないと何も出ませんね。
それでは-Dと-wオプションを使ってguestアカウントで認証した後に検索してみましょう。

# ldapsearch -x -D 'uid=guest,ou=People,dc=test' -w hogehoge \
  -b 'ou=AddressBooks,dc=test' -s one '(cn=*taku*)' cn mail
# extended LDIF
#
# LDAPv3
# base <ou=AddressBooks,dc=test> with scope one
# filter: (cn=*taku*)
# requesting: cn mail
#

# Yoshimasa Katakura, AddressBooks, test
dn: cn=Yoshimasa Katakura,ou=AddressBooks,dc=test
mail: yotan@hijiki.net
cn: Yoshimasa Katakura

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

はい。見つかりました。これでもうBecky!からもOutlook ExpressからもLDAPからの検索が可能になりました。

■Becky!での設定

アドレス帳から新規アドレス帳を開いて、LDAPの設定を以下のようにします。

サーバ名はもちろんFreeBSDのサーバ名。パスワードはhogehogeです。
下の「認証」を入れないと決して接続が出来ない訳ではなく、前の章で試したように何も検索ができなくなります。

あとはアドレスを呼び出すときにはアドレス帳から今回登録したLDAPのアドレス帳を選んで、検索フィールドで文字列を一部分でも入力して「検索」を押せば一覧に表示される筈です。

Becky!ではアドレスを呼び出すときには毎回LDAPサーバに繋いで検索しなければいけませんが、Outlook Expressでは検索した物をローカルのアドレス帳に登録してから利用する手順みたいです。
どちらが良いかは人それぞれですね。

■外部に公開してしまえ

もしLDAPサーバの入っているホストがインターネットの外からもアクセスできる場合は389/TCPポートを開いてあげればOKです。やり方は本エントリとは関係ないので割愛しますが、少なくとも今回の設定ではou=People,dc=test配下のオブジェクトしか参照できませんし、その中のパスワードは強固な暗号化がかけられているので大事なメールアドレス一覧が漏れてしまう心配は少ないでしょう。

但し通信自体は暗号化されていないので、Sniffされた場合にはその限りではありません。

■ToDo

まだ、書ききれない事、調べ切れていないことを列挙します。

  • 属性の追加・変更方法
  • 暗号化通信
  • LDAP Browser\Editorの使用方法
  • indexの使用方法についてもう少し調べる
投稿者 yotan : 2005年8月14日 02:18| トラックバック(0)
アンケート
このエントリは・・・
とても役に立った
役に立った
どちらとも言えない
あまり役に立たなかった
全く役に立たなかった
コメント
コメントする

※コメント内にURLを書くとSPAM扱いとなります。2ch風に表記はOKです










名前、アドレスを登録しますか?