コンテンツにスキップ

Linuxユーザー認証の設定(StartTLS)

LDAP サーバーに登録したユーザーを NSS / PAM 経由で使い、認証クライアントと LDAP サーバー間の Simple Bind を StartTLS で保護する手順。

StartTLS は、TCP 389 の ldap:// 接続を開始した後、同じ接続を TLS へ昇格する。TLS を使用しない構成は Linuxユーザー認証の設定(TLSなし) を参照する。


項目 例
LDAP サーバー ldap.example.com
認証クライアント auth-client.example.com
Base DN dc=example,dc=com
LDAP 管理者 DN cn=admin,dc=example,dc=com
接続 URI ldap://ldap.example.com/
TLS 方式 StartTLS
サーバー証明書の SAN DNS:ldap.example.com

LDAP サーバー名 ldap.example.com が DNS または /etc/hosts で正しい IP アドレスへ解決できるようにする。認証クライアントが URI に指定する名前と、証明書の Subject Alternative Name(SAN)を一致させる。


1. LDAPサーバーとユーザーを作成する

Section titled “1. LDAPサーバーとユーザーを作成する”

次の作業は TLSなし版 と共通である。

  1. LDAPサーバーを初期設定する
  2. Base DNを確認する
  3. ou=peopleとou=groupsを作る
  4. グループとユーザーを作る
  5. 認証クライアントへパッケージを入れる

ここまでの LDAP 管理操作は LDAP サーバー上で行い、TLS の設定後に認証クライアントから接続確認する。


2. CA証明書とサーバー証明書を用意する

Section titled “2. CA証明書とサーバー証明書を用意する”

プライベート CA とサーバー証明書を作る場合は、次の手順を利用する。

  1. Root CAの構築
  2. Intermediate CAの構築
  3. サーバー証明書の発行

サーバー証明書には、認証クライアントが接続に使う名前を SAN として指定する。

subjectAltName=DNS:ldap.example.com

既存クライアントとの互換性も考慮する場合は、証明書の Common Name(CN)にも ldap.example.com を指定する。名前検証では SAN を必須として扱う。

以降の例では、次のファイルが手元にあるものとする。

ファイル 内容
../root/ca.crt 認証クライアントが信頼する Root CA 証明書
../intermediate/intermediate.crt Intermediate CA 証明書
server.crt ldap.example.com 用サーバー証明書
server.key サーバー証明書に対応する秘密鍵
privkey.pem OpenSSL手順で作成するパスフレーズなしの配備用秘密鍵

パスは サーバー証明書の発行 で使うディレクトリ構成に合わせている。Intermediate CA を使わず Root CA から直接サーバー証明書を発行した場合、 ../intermediate/intermediate.crt は不要である。


3. LDAPサーバーへ証明書と秘密鍵を配置する

Section titled “3. LDAPサーバーへ証明書と秘密鍵を配置する”

OpenLDAP が読み取る TLS ファイルを /etc/ldap/tls に配置する。

Terminal window
sudo install -d \
-o root \
-g openldap \
-m 750 \
/etc/ldap/tls

Intermediate CA 証明書と Root CA 証明書を発行元から Root CA の順に連結し、OpenLDAP が使用する CA チェーンを作る。OpenLDAP の証明書検証では、CA 証明書の並び順は検証結果に影響しない。

Terminal window
cp ../intermediate/intermediate.crt ca-chain.crt
cat ../root/ca.crt >> ca-chain.crt
cp server.crt ldap-server.crt

Intermediate CA を使わない場合は、Root CA 証明書だけを CA ファイルとして配置する。

Terminal window
cp ../root/ca.crt ca-chain.crt
cp server.crt ldap-server.crt

OpenSSL の手順で作成した配備用の privkey.pem を、OpenLDAP 用の名前へコピーする。

Terminal window
cp privkey.pem ldap-server.key

privkey.pem をまだ作っていない場合は、パスフレーズ付きの server.key からサービス用のパスフレーズなし秘密鍵を作る。 slapd は起動時に秘密鍵のパスフレーズを対話入力できない。

Terminal window
openssl pkey \
-in server.key \
-out ldap-server.key

証明書と鍵を配置する。

Terminal window
sudo install \
-o root \
-g root \
-m 644 \
ca-chain.crt \
/etc/ldap/tls/ca-chain.crt
sudo install \
-o root \
-g root \
-m 644 \
ldap-server.crt \
/etc/ldap/tls/ldap-server.crt
sudo install \
-o root \
-g openldap \
-m 640 \
ldap-server.key \
/etc/ldap/tls/ldap-server.key

LDAP サーバーで、TLS ファイルのパスを cn=config に登録する。

tls.ldif
dn: cn=config
changetype: modify
replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ldap/tls/ca-chain.crt
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/tls/ldap-server.crt
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/tls/ldap-server.key

ldapi:/// と SASL EXTERNAL を使って設定を反映する。

Terminal window
sudo ldapmodify \
-Y EXTERNAL \
-H ldapi:/// \
-f tls.ldif

設定値を確認する。

Terminal window
sudo slapcat -n 0

成功の目安は、 cn=config に次の属性が表示されることである。

olcTLSCACertificateFile: /etc/ldap/tls/ca-chain.crt
olcTLSCertificateFile: /etc/ldap/tls/ldap-server.crt
olcTLSCertificateKeyFile: /etc/ldap/tls/ldap-server.key

slapd を再起動し、起動に失敗していないことを確認する。

Terminal window
sudo systemctl restart slapd
sudo systemctl status slapd --no-pager

起動に失敗した場合は、まず秘密鍵のパス、所有者、権限、パスフレーズの有無、サーバー証明書との組み合わせを確認する。


5. 認証クライアントへRoot CA証明書を配布する

Section titled “5. 認証クライアントへRoot CA証明書を配布する”

PKI 作業環境の ../root/ca.crt を認証クライアントへ ca.crt という名前でコピーし、OS の信頼ストアへ登録する。

Terminal window
sudo install \
-o root \
-g root \
-m 644 \
ca.crt \
/usr/local/share/ca-certificates/skills-ldap-ca.crt
sudo update-ca-certificates

名前解決も確認する。

Terminal window
getent hosts ldap.example.com

認証クライアントから、証明書チェーンと名前を検証する。

Terminal window
openssl s_client \
-connect ldap.example.com:389 \
-starttls ldap \
-CAfile /etc/ssl/certs/ca-certificates.crt \
-verify_return_error \
-verify_hostname ldap.example.com \
< /dev/null

成功の目安は、最後に次が表示されることである。

Verify return code: 0 (ok)

続いて、LDAP の StartTLS と Simple Bind を確認する。

Terminal window
LDAPTLS_CACERT=/etc/ssl/certs/ca-certificates.crt \
LDAPTLS_REQCERT=demand \
LDAPTLS_REQSAN=demand \
ldapwhoami \
-x \
-ZZ \
-H ldap://ldap.example.com/ \
-D "uid=ldapuser,ou=people,dc=example,dc=com" \
-W

-ZZ は StartTLS が成立しなければ処理を続行しない指定である。成功の目安は、Bind した DN が表示されることである。

dn:uid=ldapuser,ou=people,dc=example,dc=com

7. 認証クライアントでnslcdを設定する

Section titled “7. 認証クライアントでnslcdを設定する”

認証クライアントの /etc/nslcd.conf に、接続先、Base DN、StartTLS、CA ファイルを設定する。

/etc/nslcd.conf
uid nslcd
gid nslcd
uri ldap://ldap.example.com/
base dc=example,dc=com
ssl start_tls
tls_reqcert demand
tls_reqsan demand
tls_cacertfile /etc/ssl/certs/ca-certificates.crt
filter passwd (objectClass=posixAccount)
filter group (objectClass=posixGroup)

匿名検索を許可しない場合は、NSS 検索用の読み取り専用 DN とパスワードを追加する。

/etc/nslcd.conf
binddn cn=readonly,dc=example,dc=com
bindpw read-only-password

bindpw を書く場合は、ファイルを nslcd 以外の一般ユーザーから読めないようにする。

Terminal window
sudo chown root:nslcd /etc/nslcd.conf
sudo chmod 640 /etc/nslcd.conf
sudo systemctl restart nslcd
sudo systemctl status nslcd --no-pager

NSS と PAM の設定は TLS なし版と共通である。

  1. NSSを設定する
  2. PAMを設定する

PAM の確認が終わるまで、既存の root 権限セッションを閉じない。


最初に NSS の検索を確認する。

Terminal window
getent passwd ldapuser
id ldapuser
getent group developers

続いて、一般ユーザーからの su、SSH、コンソールログインなど、パスワード入力が実際に発生する経路で LDAP ユーザーのログインを確認する。

Terminal window
su - ldapuser

StartTLS の証明書検証で失敗した場合は、それぞれのマシンでログを確認する。

Terminal window
# LDAPサーバー
sudo journalctl -u slapd --no-pager
# 認証クライアント
sudo journalctl -u nslcd --no-pager

主な確認箇所は次のとおり。

症状 確認箇所
CAを信頼できない Root CA の配布、 update-ca-certificates、 tls_cacertfile
名前が一致しない URI のホスト名とサーバー証明書の SAN
チェーンを構築できない ca-chain.crt に Intermediate CA と Root CA の証明書が含まれるか
slapdが起動しない 秘密鍵のパス、権限、パスフレーズ、証明書との対応
NSS検索だけ失敗する 匿名検索または読み取り専用DNのACL、nslcdのログ


  • nslcd.conf(5) ssl start_tls、 tls_reqcert、 tls_reqsan、 tls_cacertfile の設定。