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
実際の実行例は以下の通りです。
# 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
管理者パスワードを生成した時と同様、実行例は以下の通りです。
# slappasswd New password: Re-enter new password: {SSHA}xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ドメインの設定を実施する為に change-domain.ldif
という LDIF ファイルを作成します。 dc=example,dc=com
の部分は OpenLDAP で管理したいドメイン名に併せて修正します。 olcRootPW
の値は slappasswd
で生成したハッシュ値を指定します。
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
の部分は自身の環境に併せて変更します。
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 を指定します。
make server.csr
実際の実行例は以下の通りです。 自身の環境に併せて値は変更します。
# 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 の設定は完了です。
systemctl restart slapd
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
になっており、その他、特別に追加されたユーザやグループはありません。
$ 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
)権限が追加されていることが分かります。
$ 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 の設定は完了です。
systemctl restart slapd
参考
/etc/sysconfig/slapd
# 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"