OpenLDAPをいまさらやってみる

何の脈絡もなく(自分の中では文脈があっての話ですが)、OpenLDAPをやってみようと思い立ち、やってみました。

portsから入れました。コンパイルは順調だったのですが、インストール時にコンフリクトする、と怒られる。sambaとの関係で非SASLクライアントでないといけないのにSASL付きでコンフィギュア、ビルドして、インストールしようとしたためでした。Makefileを見て、make WITUHOUT_SASL=true とするとOKそうなので、これでコンパイル、インストールができました。
インストールすると、例によって /usr/local/etc/rc.d に起動スクリプトが入り、コメントに/etc/rc.confに書くべきことが書いてあるので、/etc/rc.conf に次の行を追加。(最後のslapd_ownerを入れた理由は後述)

slapd_enable="YES"
slapd_flags='-h "ldapi://%2fvar%2frun%2fopenldap%2fldapi/ ldap://0.0.0.0/"'
slapd_sockets="/var/run/openldap/ldapi"
slapd_owner="DEFAULT"

次に、OpenLDAPの設定。http://www.leafgreen.jp/freebsd/openldap.html を参考にというかそのまま引き写しで /usr/local/etc/openldap/slapd.conf を編集。あと、cp /usr/local/etc/openldap/DB_CONFIG.example /var/db/openldap-data/DB_CONFIG で、DB_CONFIGを何も考えずに複製。

この時点で、slapdを起動。 /usr/local/etc/rc.d/slapd start とします。

ここからはアカウントの追加までをやってみます。http://unix-study.com/unix/install/openldap/ , http://unix-study.com/unix/install/openldap/login/ あたりも参照。
まず、トップツリーを作成。

% cat top.ldif
dn: dc=(host),dc=(domain1),dc=(domain2)...,dc=(domainn)
objectClass: dcObject
objectClass: organization
o: (host)
dc: (host)

% ldapadd -x -D "cn=Manager,dc=(domain2)...,dc=(domainn)" -w secret -f top.ldif 

ここで、"-w secret" というのは、「パスワードは "secret" とする」という意味です。後でパスワード変更しといた方がいいかな。

次に、グループツリー、アカウントツリー、グループエントリ、アカウントエントリをどんどんと追加。

% cat groups.ldif
dn: ou=groups,dc=(domain1),dc=(domain2)...,dc=(domainn)
ou: groups
objectclass: organizationalUnit

% ldapadd -x -D "cn=Manager,dc=(domain1),dc=(domain2)...,dc=(domainn)" -w secret -f groups.ldif
% cat account.ldif
dn: ou=accounts,dc=(domain1),dc=(domain2)...,dc=(domainn)
ou: accounts
objectclass: organizationalUnit

% ldapadd -x -D "cn=Manager,dc=(domain1),dc=(domain2)...,dc=(domainn)" -w secret -f account.ldif
% cat group_test.ldif
dn: cn=test,ou=groups,dc=(domain1),dc=(domain2)...,dc=(domainn)
objectClass: posixGroup
cn: test
gidNumber: 10000

% ldapadd -x -D "cn=Manager,dc=(domain1),dc=(domain2)...,dc=(domainn)" -w secret -f group_test.ldif
% cat account_test.ldif
dn: uid=test,ou=accounts,dc=(domain1),dc=(domain2)...,dc=(domainn)
objectclass: account
objectclass: posixAccount
objectclass: shadowAccount
uid: test
cn: test
uidNumber: 10000
gidNumber: 10000
homeDirectory: /home/test
userPassword: {MD5}CY9rzUYh03PK3k6DJie09g==
loginShell: /bin/tcsh
gecos: test
description: test account

% ldapadd -x -D "cn=Manager,dc=(domain1),dc=(domain2)...,dc=(domainn)" -w secret -f account_test.ldif

パスワード設定はこんなかんじ

% ldappasswd -x -D "cn=Manager,dc=(domain1),dc=(domain2)...,dc=(domainn)" -w secret -S "uid=test,ou=accounts,dc=(domain1),dc=(domain2)...,dc=(domainn)"

特定のユーザを検索するのはこんなかんじ

% ldapsearch -b "ou=accounts,dc=(domain1),dc=(domain2)...,dc=(domainn)" "(uidNumber=10000)"

ユーザエントリを消すときはこんなかんじ。

% ldapdelete -x -D "cn=Manager,dc=(domain1),dc=(domain2)...,dc=(domainn)" -w secret "uid=(uidで指定した文字列),ou=accounts,dc=(domain1),dc=(domain2)...,dc=(domainn)"

次に、suでtestが認証できるところまでやってみました。
http://www.abk.nu/~nabe/document/openldap.htm (閲覧できない→googleのキャッシュに残ってました)を参照しました。

まず、portsから net/nss_ldap security/pam_ldap をインストール。特に問題は出ません。

次に、設定ファイルを用意。ldap.confとnss_ldap.confはシンボリックリンクで良いようです。

cd /usr/local/etc
cp ldap.conf.dist ldap.conf
ln -s ldap.conf nss_ldap.conf

ldap.confを編集します。base dc=adl,dc=com となっているのを base=dc=(domain1),dc=(domain2)...,dc=(domainn) とします。
次いで /etc/nsswitch.conf を編集して、"group_compat: ldap"と"passwd_compat: ldap"とします。
次はvipwを動かして、パスワードファイルの末尾に "+:*::::::::" の行を追加。
さらに、/etc/group の末尾に "+:*::" を追加。

ここで、/etc/rc.conf に slapd_owner="DEFAULT" を追加していなかったら、おかしなことになります。このオプション指定が無いと、slapdはldapというアカウントで実行しようとして、その認証のためにslapdにアクセスしようとします。まだslapdは立ち上がっていないので、じーっと待ってしまいます。これがブート時に発生した時には、もうこれでログインできなくなるのかと心配になりました。コンソールから^Cを送ると止まりますが、他のデーモンで、ユーザをwwwとかnobodyとかに変更するものは、軒並みアウトになります。

su に対応してみるため、/etc/pam.d/su を編集。次のような順序で、真ん中の行を挿入します。

auth		requisite	pam_group.so		no_warn group=wheel root_only fail_safe
auth		sufficient	/usr/local/lib/pam_ldap.so		no_warn try_first_pass
auth		include		system

なお、挿入される行の3番目の要素で、単に"pam_ldap.so"とすると"no pam_ldap.so found" とエラーが出ました(/var/log/messageで確認できます)。
これで、root以外の(rootだとパスワードなしで別アカウントになれるから)アカウントで、"su test"を実行して、成功することを確認してました。
sshdについては、次の順序となるように1番目の行を挿入します。

auth		sufficient	/usr/local/lib/pam_ldap.so		no_warn try_first_pass
auth		required	pam_unix.so		no_warn try_first_pass

終いに、ルートパスワードを変更。
slappasswd -s (新しいパスワード)
で、
{SSHA}...
とか出るので、これを/usr/local/etc/openldap/slapd.conf に入れます。"rootpw secret"となっているところ、の"secret"に挿入します。

# rootpw secret
rootpw {SSHA}...

デフォルト状態で有効になっている "rootpw secret"の"secret"は、本当の生パスワードです。上で "-w secret" と出ているところがありますが、引数にパスワードを生で書いていました。
生パスワードを引数に与えるのが、ヒストリの関係とかでイヤでしたら、"-w secret" の代わりに "-W"と指定します。これで、コマンドを実行する際にパスワードをエコーなしで答えられるようにできます。