#前提
CentOS Linux release 7.5.1804 (Core)
#パッケージのインストール
yum -y install openldap openldap-clients openldap-servers
#サービス起動
systemctl status slapd
● slapd.service - OpenLDAP Server Daemon
Loaded: loaded (/usr/lib/systemd/system/slapd.service; disabled; vendor preset: disabled)
*初歩的だが、このとき前ステップではopenldapパッケージのインストールだったが、
起動するサービスはslapdであることに注意
#試しに現状のDBがどうなってるか確認してみる
まっさらな状態で現在のLDAPデータベースの内容をldapdb.ldifファイルに書き出そうとしてみる。
すると、どうやら初期状態ではなにも存在していないらしい。
/var/lib/ldapという場所にDBが保存されるらしいことはここでわかる。
slapcat > ldapdb.ldif
61164aeb The first database does not allow slapcat; using the first available one (2)
61164aeb hdb_db_open: warning - no DB_CONFIG file found in directory /var/lib/ldap: (2).
Expect poor performance for suffix "dc=my-domain,dc=com".
#DBの作成
もともとパッケージの中にDB_CONFIG.exampleというDBサンプルが存在するため、これをベースに
DBサンプルを作る。
# cd /usr/share/openldap-servers/
# ls -l
total 8
-rw-r--r--. 1 root root 845 Apr 28 09:32 DB_CONFIG.example
-rw-r--r--. 1 root root 3717 Apr 28 09:32 slapd.ldif
# cp -p DB_CONFIG.example /var/lib/ldap/DB_CONFIG
コピーしただけだと所有ユーザがコピーしたものだけなので、所有者変更する。
# ls -l
total 324
-rw-r--r--. 1 ldap ldap 4096 Aug 13 06:35 alock
-rw-------. 1 ldap ldap 262144 Aug 13 06:35 __db.001
-rw-------. 1 ldap ldap 32768 Aug 13 06:35 __db.002
-rw-------. 1 ldap ldap 49152 Aug 13 06:35 __db.003
-rw-r--r--. 1 root root 845 Apr 28 09:32 DB_CONFIG
-rw-------. 1 ldap ldap 8192 Aug 8 10:26 dn2id.bdb
-rw-------. 1 ldap ldap 32768 Aug 8 10:26 id2entry.bdb
-rw-------. 1 ldap ldap 10485760 Aug 8 10:26 log.0000000001
# chown ldap:ldap DB_CONFIG
# ls -l
total 324
-rw-r--r--. 1 ldap ldap 4096 Aug 13 06:35 alock
-rw-------. 1 ldap ldap 262144 Aug 13 06:35 __db.001
-rw-------. 1 ldap ldap 32768 Aug 13 06:35 __db.002
-rw-------. 1 ldap ldap 49152 Aug 13 06:35 __db.003
-rw-r--r--. 1 ldap ldap 845 Apr 28 09:32 DB_CONFIG
-rw-------. 1 ldap ldap 8192 Aug 8 10:26 dn2id.bdb
-rw-------. 1 ldap ldap 32768 Aug 8 10:26 id2entry.bdb
-rw-------. 1 ldap ldap 10485760 Aug 8 10:26 log.0000000001
#DBをいじるための管理者作成
管理ユーザを定義する。
ステップは
⓵slappasswdコマンドで文字列を暗号化
⓶管理者作成用のLDIFファイルの作成
⓷LDIFファイル内にて⓵で出力されたパスワードを記載
⓸ldapaddにてDBに登録
# slappasswd
New password:
Re-enter new password:
{SSHA}WyqBCqwPHnBbT+XcsK0LV1O7jHClvYc/ #<-これが暗号化されたパスワード文字列
# cat rootdn.ldif
dn: olcDatabase={0}config,cn=config #olcDatabaseがconfigのエントリとして以下を登録
changetype: modify
add: olcRootDN #管理者(RootDN)を追加
olcRootDN: cn=admin,cn=config
-
add:olcRootPW #管理者のPWを追加。先ほど出力した暗号化されたPWを入力
olcRootPW:{SSHA}dcP1qo0XUjL272DMezm79cwds8zQLa2b #⓷
*1dn:olcDatabase (OpenLdap Configuration Databaseの略のよう)の値にはconfigのほかにhdbなどが入るみたいだが、今回のように管理者のPWを設定するのはconfigエントリみたいだ。
olcdatabaseの値の例
hdb :ユーザデータなど、様々なデータを追加、管理する
monitor:モニタの管理者DNと管理者パスワード、アクセス制御
*2 olcDatabase={0}configのような”{数字}”はDB内での順序を示すよう。DBなので順序を意識する必要はほとんどないが、olcDatabaseについては順序が大事なのかもしれない。
ldapmodify -Y EXTERNAL -H ldapi:/// -f /root/ldif/rootdn.ldif
-Y はSASL(認証機能を提供するサービス)の中でどれを使うか 引数にKerberos,GSSAPI,DIGEST-MD5などが入る。
今回は認証機能を使わないので、EXTERNALとする。
-HはLDAPサーバをURIで指定する。ローカルサーバの場合,ldapi///と宣言する。
ldapiとは、接続プロトコルのこと。ほかにも以下のように違うプロトコルでの接続も可能
URL | Protocol | Transport |
---|---|---|
ldap:/// | LDAP | TCP port 389 |
ldaps:/// | LDAP over SSL | TCP port 636 |
ldapi:/// | LDAP | IPC (Unix-domain socket) |
ソース(https://www.openldap.org/doc/admin24/runningslapd.html) |
#設定変更確認
ldapsearch -Y EXTERNAL -H ldapi:/// -b "olcDatabase={0}config,cn=config"
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
# extended LDIF
#
# LDAPv3
# base <olcDatabase={0}config,cn=config> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# {0}config, config
dn: olcDatabase={0}config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: {0}config
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external
,cn=auth" manage by * none
olcRootDN: cn=admin,cn=config
olcRootPW: {SSHA}dcP1qo0XUjL272DMezm79cwds8zQLa2b
# search result
search: 2
result: 0 Success
さきほど設定したolcRootDNとolcRootPWが入っていることを確認できる
#ディレクトリマネージャの作成
先ほどの管理者はあくまでLDAPの設定変更管理者であって実際のDBの管理者ではない。
DBの管理者のことをディレクトリマネージャーと呼ぶ。
ソース(https://qiita.com/y-araki-qiita/items/0c954c3ae25d4ed9dbb8)
まずLDAPデータベースツリーのDN(olcsuffix)やDB作成用のディレクトリマネージャを作成するためのLDIFを作成。
# cat domain.ldif
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=example,dc=com #dc=example,dc=comを頂点としたツリーを作る。
-
replace: olcRootDN
olcRootDN: cn=admin,dc=example,dc=com #admin=管理者
-
add: olcRootPW
olcRootPW:{SSHA}dcP1qo0XUjL272DMezm79cwds8zQLa2b #ldappasswdで暗号化したPWを記載。先ほどのPWと同じでも可。
objectclass:エントリの必須属性やoptional属性が何かを定義するもの。ユーザというObjectclassであれば「氏名」「年齢」「メールアドレス」などの属性は必須となるなど。
ouとcnとdcがごっちゃになるので、整理。
ou : DITの階層コンポーネントだが、OrganizationUnitということもあり、組織単位を表す場合に使われる。
dc : DITの階層コンポーネントであり、Domain ComponentというだけあってなんでもOK。
cn : Common name。名前なので、人とかモノとかを表すことが多そう。
* LDAPではこれ以外にも「C=国/地域」「O=組織」といった属性もあるが、Active Directoryではこれらは利用されない。
どうやらcn=configを頂点としたツリーにおいてはcn=schemaとかcnを使ってるが、
dc=comを頂点としてる場合、dcまたはouを使って、ユーザ名とかだけcnを使ってる気がする。
dcとcnの使い分けが何の意味をなしてるのか今は不明。
# 設定変更
ldapmodify -x -W -D cn=admin,cn=config -f /root/ldif/domain.ldif
#スキーマの追加
属性やオブジェクトクラスなど定義をセットにしたのがスキーマ。
スキーマがないとオブジェクトクラスや属性をもった管理ができない。
標準的なものは以下。
core.schema OpenLDAPで必須のスキーマ
cosine.schema ディレクトリサービスのX.500規格で規定された属性が定義されたスキーマ
inetorgperson.schema アドレス帳など個人情報を扱うためのスキーマ
nis.schema UNIX/Linuxのユーザーやグループ情報を扱うためのスキーマ
なので、ひとまずスキーマを使えるようにしておく。
ldapadd -D cn=admin,cn=config -f /etc/openldap/schema/cosine.ldif -W
Enter LDAP Password:
adding new entry "cn=cosine,cn=schema,cn=config"
インストールした中に標準スキーマが準備されてるので、自分のDBに追加しておく。
上記だとcn=cosineが追加されてる。
ldapsearch -D cn=schema,cn=config -W #追加されたcn=schema,cn=configにはアクセスできない
Enter LDAP Password:
ldap_bind: Invalid credentials (49)
ldapsearch -D cn=admin,cn=config -W #cn=admin,cn=configとした場合、きちんと表示される。
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# search result
search: 2
result: 32 No such object
# numResponses: 1
cn=schema,cn=configに実際設定は格納されてるけど、設定管理はcn=admin,cn=configで行うということのよう。
オプションの-DはBindDNと呼ばれ、どの管理者で検索するかを記述する。
LDAPサービスへのログインのことをバインドと呼ぶらしく、それが由来。
どのツリーを調べるかは-b (=baseDN)で定義する。
ldapsearch -W -D cn=admin,cn=config -b cn=schema,cn=config ObjectClass=*
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <cn=schema,cn=config> with scope subtree
# filter: ObjectClass=*
# requesting: ALL
#
# schema, config
dn: cn=schema,cn=config
objectClass: olcSchemaConfig
cn: schema
olcObjectIdentifier: OLcfg 1.3.6.1.4.1.4203.1.12.2
olcObjectIdentifier: OLcfgAt OLcfg:3
olcObjectIdentifier: OLcfgGlAt OLcfgAt:0
olcObjectIdentifier: OLcfgBkAt OLcfgAt:1
...
確かにschemaがあることを確認できる。
#DBの更新
DBを更新するためにinit.ldifを作成する。
init.ldifについては大いにこちら(https://qiita.com/y-araki-qiita/items/6b2dcbf1a39a969d8024)
を参考にしてる。てか丸写しくらい。
dn: dc=example,dc=com
objectClass: top #topというのはオブジェクトクラスの最上位クラス。すべてのオブジェクトクラスはこれを継承してる。
objectClass: dcObject
objectClass: organization
o: Infra
dc: example
dn: ou=group,dc=example,dc=com
objectclass:organizationalUnit #organizationalUnitというオブジェクトクラスもtopを継承してるが、topを書かなくてもいいよう。
ou:group
dn:ou=user,dc=example,dc=com
objectclass:organizationalUnit
ou:user
dn: cn=infra,ou=group,dc=example,dc=com
objectclass:posixGroup
gidNumber:10001
cn:users
init.ldifをDBに追加する。
# ldapadd -x -W -D cn=admin,dc=example,dc=com -f /root/ldif/init.ldif
Enter LDAP Password:
adding new entry "dc=example,dc=com"
adding new entry "ou=group,dc=example,dc=com"
adding new entry "ou=user,dc=example,dc=com"
adding new entry "cn=infra,ou=group,dc=example,dc=com"
確認
ldapsearch -W -D cn=admin,dc=example,dc=com -b dc=example,dc=com
ということで、とりあえずDBとその管理の手順は一通りできたよう。
次に、LDAPを用いたユーザ認証をするところまで行いたい。