CentOS7 に OpenLDAP をインストールし LDAPS を有効化する
CentOS7 に OpenLDAP をインストールし、SSL/TLS サーバ証明書を設定して LDAPS を設定する手順をメモしておきます。
テスト環境
今回は CentOS 7.4.1708 にインストールしました。
 | $ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
  | 
 
OpenLDAP 関連パッケージは標準リポジトリから以下のバージョンをインストールしました。
- openldap-clients-2.4.44-5.el7.x86_64
 
- openldap-servers-2.4.44-5.el7.x86_64
 
- openldap-2.4.44-5.el7.x86_64
 
OpenLDAP サーバのインストール
OpenLDAP 関連のパッケージは標準リポジトリから yum でインストールします。
 | yum -y install openldap-clients openldap-servers
  | 
 
設定ファイルをコピーします。 OpenLDAP の設定には動的データベースを使います。
 | cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
chown ldap. /var/lib/ldap/DB_CONFIG
  | 
 
OpenLDAP サーバを起動します。 併せて自動起動設定も実施しておきます。
 | systemctl start slapd
systemctl enable slapd
  | 
 
OpenLDAP サーバは標準で 389/TCP を Listen します。
 | # lsof -i:389
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
slapd   16494 ldap    8u  IPv4 778840      0t0  TCP *:ldap (LISTEN)
slapd   16494 ldap    9u  IPv6 778841      0t0  TCP *:ldap (LISTEN)
  | 
 
管理者パスワードを設定する
管理者パスワードを設定します。 まず、slappasswd で管理者用パスワードを生成します。
実際の実行例は以下の通りです。
 | # slappasswd
New password:
Re-enter new password:
{SSHA}xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  | 
 
管理者パスワードを変更する為に change-root-password.ldif という LDIF ファイルを作成します。 olcRootPW の値は slappasswd で生成したハッシュ値を指定します。
 | dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  | 
 
ldapadd で動的データベースに反映します。
 | ldapadd -Y EXTERNAL -H ldapi:/// -f change-root-password.ldif
  | 
 
基本的なスキーマの読み込み
基本的なスキーマを読み込んでおきます。
 | ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
  | 
 
ドメインの設定
次はドメインの設定を行います。 まず、ドメインマネージャ用のパスワードを slappasswd で生成します。
管理者パスワードを生成した時と同様、実行例は以下の通りです。
 | # slappasswd
New password:
Re-enter new password:
{SSHA}xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  | 
 
ドメインの設定を実施する為に change-domain.ldif という LDIF ファイルを作成します。 dc=example,dc=com の部分は OpenLDAP で管理したいドメイン名に併せて修正します。 olcRootPW の値は slappasswd で生成したハッシュ値を指定します。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28  | dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth"
  read by dn.base="cn=Manager,dc=example,dc=com" read by * none
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=example,dc=com
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=Manager,dc=example,dc=com
dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by
  dn="cn=Manager,dc=example,dc=com" write by anonymous auth by self write by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by dn="cn=Manager,dc=example,dc=com" write by * read
  | 
 
ldapmodify で動的データベースに反映します。
 | ldapmodify -Y EXTERNAL -H ldapi:/// -f change-domain.ldif
  | 
 
ベースドメインと OU の設定
ベースドメインを設定し、その中に OU を作成していきます。 以下の内容で set-base-domain.ldif というファイルを新規作成します。 dc=example,dc=com と o=EXAMPLE-NET、dc: EXAMPLE の部分は自身の環境に併せて変更します。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19  | dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectclass: organization
o: EXAMPLE-NET
dc: EXAMPLE
dn: cn=Manager,dc=example,dc=com
objectClass: organizationalRole
cn: Manager
description: Directory Manager
dn: ou=People,dc=example,dc=com
objectClass: organizationalUnit
ou: People
dn: ou=Groups,dc=example,dc=com
objectClass: organizationalUnit
ou: Groups
  | 
 
ldapadd で動的データベースに反映します。 dc=example,dc=com の部分は自身の環境に併せて変更します。
 | ldapadd -x -D cn=Manager,dc=example,dc=com -W -f set-base-domain.ldif
  | 
 
LDAPS を有効化する
LDAP 通信を保護する為、SSL/TLS サーバ証明を用いて LDAPS の設定を行います。 証明書は以下、いずれかの方法を用いて用意します。
- 自己証明書を用意する
 
- Let's Encrypt で証明書を取得する
 
自己証明書を利用する
ここでは自己証明書を作成します。 まず、秘密鍵を作成します。 秘密鍵の新規作成時は必ず、パスフレーズを設定する必要がありますが、以降の手順でパスフレーズは削除します。
 | cd /etc/pki/tls/certs
make server.key
  | 
 
パスフレーズを削除します。
 | openssl rsa -in server.key -out server.key
  | 
 
CSR を作成します。 Common Name は LDAPS で公開したい FQDN を指定します。
実際の実行例は以下の通りです。 自身の環境に併せて値は変更します。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22  | # make server.csr
umask 77 ; \
/usr/bin/openssl req -utf8 -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:Tokyo
Locality Name (eg, city) [Default City]:Chiyoda-ku
Organization Name (eg, company) [Default Company Ltd]:Default Company Ltd
Organizational Unit Name (eg, section) []:Server Division
Common Name (eg, your name or your server's hostname) []:LDAP.EXAMPLE.COM
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
  | 
 
作成した秘密鍵 / CSR を使って証明書を発行します。 証明書の有効期間は 10 年(3,650 日)としました。
 | openssl x509 -in server.csr -out server.crt -req -signkey server.key -days 3650
  | 
 
作成した証明書は OpenLDAP サーバからアクセス出来る位置にコピーし、所有者も ldap ユーザへ変更します。
 | cp /etc/pki/tls/certs/server.key \
   /etc/pki/tls/certs/server.crt \
   /etc/pki/tls/certs/ca-bundle.crt \
   /etc/openldap/certs/
chown ldap. \
   /etc/openldap/certs/server.key \
   /etc/openldap/certs/server.crt \
   /etc/openldap/certs/ca-bundle.crt
  | 
 
以下の内容で enable-ldaps.ldif という、証明書関連の設定を行う LDIF ファイルを作成します。
 | dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/openldap/certs/ca-bundle.crt
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/openldap/certs/server.crt
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/openldap/certs/server.key
  | 
 
ldapmodify で動的データベースに反映します。
 | ldapmodify -Y EXTERNAL -H ldapi:/// -f enable-ldaps.ldif
  | 
 
OpenLDAP 自体が LDAPS を Listen 出来るよう、設定ファイルを修正します。 設定ファイルは /etc/sysconfig/slapd です。
|   | 
設定 | 
| 変更前 | 
SLAPD_URLS="ldapi:/// ldap:///" | 
| 変更後 | 
SLAPD_URLS="ldapi:/// ldap:/// ldaps:///" | 
今回は sed で設定変更します。
 | sed -i -e "s/^SLAPD_URLS=\"ldapi:\/\/\/ ldap:\/\/\/\"/SLAPD_URLS=\"ldapi:\/\/\/ ldap:\/\/\/ ldaps:\/\/\/\"/g" /etc/sysconfig/slapd
  | 
 
設定変更が完了したら OpenLDAP サーバを再起動し、LDAPS の設定は完了です。
Let's Encrypt で取得した証明書を利用する
Let's Encrypt で取得した証明書を利用することも可能です。 Let's Encrypt で証明書を取得するには Web 認証を用いることも可能ですが、サーバを OpenLDAP のディレクトリサービスとしてしか利用せず、Web サーバは有効化しない場合、DNS 認証で証明書を取得した方が余計なソフトウェアを追加せずに済みます。 以前に Let's Encrypt で DNS 認証を使って証明書を発行するというエントリーを書きましたが、DNS 認証で証明書を取得するには、まず certbot-auto をインストールします。 curl で certbot-auto を取得し、実行権限を付与しておきます。
 | curl https://dl.eff.org/certbot-auto -o /usr/bin/certbot-auto
chmod 700 /usr/bin/certbot-auto
  | 
 
必要なオプションを指定して certbot-auto を実行します。 自身の環境に併せて --email や --domain を修正します。 以下を実行すると途中で該当の DNS ゾーンに TXT レコードを作成するように要求されますので、指定の値で TXT レコードを作成し、証明書を取得します。
 | certbot-auto certonly \
  --debug \
  --manual \
  --email mail@example.com \
  --agree-tos \
  --manual-public-ip-logging-ok \
  --preferred-challenges dns \
  --domain LDAP.EXAMPLE.COM
  | 
 
以下の内容で enable-ldaps.ldif という、証明書関連の設定を行う LDIF ファイルを作成します。 証明書関連のパスは(実体である /etc/letsencrypt/archive では無く)シンボリックリンクである /etc/letsencrypt/live/ を指定しておきます。
 | dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/letsencrypt/live/LDAP.EXAMPLE.COM/chain.pem
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/letsencrypt/live/LDAP.EXAMPLE.COM/cert.pem
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/letsencrypt/live/LDAP.EXAMPLE.COM/privkey.pem
  | 
 
ldapmodify で動的データベースに反映します。
 | ldapmodify -Y EXTERNAL -H ldapi:/// -f enable-ldaps.ldif
  | 
 
但し、このままでは OpenLDAP から証明書を参照出来ず、LDAPS 接続が出来ません。 但し、OpenLDAP サーバとしては起動し、LDAP 接続は出来てしまいます… 個人的には「秘密鍵や証明書の読み込みに失敗したのであれば、エラーとなり、サーバは起動に失敗すべき」と思うのですが、OpenLDAP はこのような動きをせず、起動出来てしまうようです…
OpenLDAP は ldap というユーザで動作する為、Let's Encrypt で取得した証明書のディレクトリを chown ldap. ~ しても良いのですが、こうしてしまうと以下の問題について考慮する必要が出て来ると思われます。
- 本来とは異なる所有者に変更した状態で Let's Encrypt の証明書更新処理を行った際、何がしかの不都合が出ないか?(※ 「問題がある」と断定出来るわけでは無いが、「試したことが無い」為に不安)
 
- OpenLDAP 以外のアプリケーションからも同じ証明書を参照させる必要が出てきた場合、所有者を 
ldap に変更したことによって「他のアプリケーション」から証明書を参照出来なくなってしまう 
そこで今回はファイルシステムの ACL を利用して所有者は root のまま、ldap ユーザからも証明書にアクセス出来るようにします。 ACL を利用する前に、現状を getfacl で確認しておきます。 /etc/letsencrypt/{archive,live} いずれのディレクトリも所有者は root になっており、その他、特別に追加されたユーザやグループはありません。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15  | $ getfacl /etc/letsencrypt/{archive,live}
getfacl: Removing leading '/' from absolute path names
# file: etc/letsencrypt/archive
# owner: root
# group: root
user::rwx
group::---
other::---
# file: etc/letsencrypt/live
# owner: root
# group: root
user::rwx
group::---
other::---
  | 
 
setfacl を使って /etc/letsencrypt/{archive,live} に ldap ユーザに「読み取り と 実行」権限を付与します。
 | setfacl -m u:ldap:rx /etc/letsencrypt/{archive,live}
  | 
 
改めて getfacl で ACL の設定を確認します。 ldap ユーザに「読み取り と 実行」(r-x)権限が追加されていることが分かります。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19  | $ getfacl /etc/letsencrypt/{archive,live}
getfacl: Removing leading '/' from absolute path names
# file: etc/letsencrypt/archive
# owner: root
# group: root
user::rwx
user:ldap:r-x
group::---
mask::r-x
other::---
# file: etc/letsencrypt/live
# owner: root
# group: root
user::rwx
user:ldap:r-x
group::---
mask::r-x
other::---
  | 
 
自己証明書を利用する場合と同様、OpenLDAP 自体が LDAPS を Listen 出来るよう、設定ファイルを修正します。 設定ファイルは /etc/sysconfig/slapd です。
|   | 
設定 | 
| 変更前 | 
SLAPD_URLS="ldapi:/// ldap:///" | 
| 変更後 | 
SLAPD_URLS="ldapi:/// ldap:/// ldaps:///" | 
今回は sed で設定変更します。
 | sed -i -e "s/^SLAPD_URLS=\"ldapi:\/\/\/ ldap:\/\/\/\"/SLAPD_URLS=\"ldapi:\/\/\/ ldap:\/\/\/ ldaps:\/\/\/\"/g" /etc/sysconfig/slapd
  | 
 
設定変更が完了したら OpenLDAP サーバを再起動し、LDAPS の設定は完了です。
参考
/etc/sysconfig/slapd
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15  | # OpenLDAP server configuration
# see 'man slapd' for additional information
# Where the server will run (-h option)
# - ldapi:/// is required for on-the-fly configuration using client tools
#   (use SASL with EXTERNAL mechanism for authentication)
# - default: ldapi:/// ldap:///
# - example: ldapi:/// ldap://127.0.0.1/ ldap://10.0.0.1:1389/ ldaps:///
SLAPD_URLS="ldapi:/// ldap:///"
# Any custom options
#SLAPD_OPTIONS=""
# Keytab location for GSSAPI Kerberos authentication
#KRB5_KTNAME="FILE:/etc/openldap/ldap.keytab"
  |