SSL/TLS接続の整備

LDAPクライアントと 389 DS との通信を暗号化するための設定についてまとめる。また、同設定は、389 DS 間でのレプリケーション通信を暗号化する際にも利用できる。ここでは、プライベートCA (認証局) を作り、各サーバ証明書はそれによって署名することにする。

プライベートCAの作成

手近な Linux マシン上に自前の CA を作成する。いずれかの LDAPサーバ機を流用してもいい。もちろん、既に CA があるなら作成は不要。

キーの生成や署名作業には、一部 OpenSSL も使うが、多少なりとも作業を楽にするため主として GnuTLS ユーティリティを使用する。CentOS/RHEL では gnutls-utils という名前で標準パッケージがあり、yum 等でインストールできる。certtool コマンドのオプションとテンプレートファイルのフォーマットについては GnuTLS オフィシャルマニュアルの "Invoking certtool" を参照。

1. CAのプライベートキーの作成

この生成には openssl を使う。現状の certtool では RSAキーの生成に異常に時間がかかるからだ (乱数生成デバイスファイルの扱いに問題があるらしい)。

root# cd /etc/pki/CA/private
root# openssl genrsa -out cakey.pem 1024
root# chmod 400 cakey.pem 

内容を確認したければ、

root# certtool -k --infile cakey.pem

cakey.pem のファイルパーミッションは root:root 400 が適当。

2. 自己署名済みCA証明書の作成

まず、CA証明書(公開鍵)生成のためのテンプレートファイル /etc/pki/CA/private/ca.info を作成する。内容は下記の要領。`serial=xxxx' の指定をしないと証明書のシリアルナンバーが `00' になり、配布しても受け入れてもらえない場合がある。有効期限は極端に長くしておけばいいだろう (例では10年)。ファイルパーミッションは root:root 600 にしておくことを勧める。

cn="Hoge Net CA"
organization="Hoge Net"
unit="Hoge Net Certificate Authority"
country=JP
expiration_days=3650
serial=1001
ca
cert_signing_key
crl_signing_key

自己署名済みCA証明書を作る。

root# cd /etc/pki/CA/private
root# certtool -s \
      --load-privkey cakey.pem \
      --template ca.info \
      --outfile ../cacert.pem

内容を確認したければ、

root# certtool -i --infile ../cacert.pem

問題がなければ、利便性のため cacert.pem/etc/pki/tls/certs/ にコピーしておく。このファイルは公開鍵なので誰でも読めるようにして構わない。ファイルパーミッションは、本物/複製とも root:root 444 もしくは 644 が適当。

389DSのサーバCSR作成

389 Management Console (Java版) を使って、ディレクトリサーバの CSR (証明書署名要求) を生成する。CSR はインスタンス毎に生成する必要がある。

対象インスタンスの Tasks タブで Manage Certificates を開く。初めて開いた時には、左図のようにパスワードを設定するよう促される。これはプライベートキーを格納するセキュリティデバイスというもの(※)を保護するためのパスワード。後で変更することも可能。

※ デフォルトのセキュリティデバイスはバークレイDB をバックエンドとしたビルトインのソフトウェアセキュリティデバイスで、定義上では "Internal (Software)" というニックネームで呼ばれる。
Server Certs タブの Request ボタンを押すと、Certificate Request Wizard ウィンドウが開く。第1画面は何もさわるところはない。
第2画面で、CSR 生成に必要な情報を入力する。Server name は、このディレクトリインスタンスへクライアントがアクセスする時に名指しするこのLDAPサーバのDNS名。その他は自分の環境に合わせて適当なものを入力。
ここで、セキュリティデバイスに格納されたプライベートキーを読む必要があるため、セキュリティデバイスの設定済みパスワードの入力が求められる。
生成した CSR をクリップボードにコピーするかファイルとして直接保存するかを訊かれる。都合のいいほうを選択すればよい。説明の都合上、ここでは 389ds-hoge.csr というファイル名で保存したことにする。

CA署名済みサーバ証明書の作成

まず、CA マシン上で、テンプレートファイル /etc/pki/tls/private/389ds-hogecert.info を作成する。内容は下記の要領。証明書タイプ (下記最後の3行) には tls_www_server, encryption_key, signing_key の 3つを指定する。

cn=centos5u.hoge.com
organization="Hoge Net"
unit="IT Development"
state="Aichi"
locality="Nagoya"
country=JP
expiration_days=730
serial=1001
tls_www_server
encryption_key
signing_key

次に、前項で生成した CSR ファイル 389ds-hoge.csr を、CA マシン上の /etc/pki/tls/private/ にコピーする。

そして、CA署名済みのサーバ証明書 (公開鍵) を作成する。

root# cd /etc/pki/tls/private
root# certtool -c \
      --load-request 389ds-hoge.csr \
      --load-ca-certificate /etc/pki/CA/cacert.pem \
      --load-ca-privkey /etc/pki/CA/private/cakey.pem \
      --template 389ds-hogecert.info \
      --outfile ../certs/389ds-hogecert.pem

完成したサーバ証明書の内容を確認するには、

root# certtool -i --infile ../certs/389ds-hogecert.pem

389ds-hogecert.pem ファイルはここに置きっぱなしにしておく必要はないが、置いたままにするなら root:root 444 あるいは 644 のパーミッションにしておくのが適当。

389DSへの証明書のインストール

389 Management Console (Java版) を使い、インスタンスにサーバ証明書と CA証明書をインストールする。どちらの証明書を先にインストールするのが正解なのかよく分からないのだが、CA証明書をインストールしなおすとそれに絡んだインストール済みのサーバ証明書も消えてしまうことから、もしかすると CA証明書を先に入れる方が正しいのかもしれない。

サーバ証明書

インスタンスの Tasks タブで Manage Certificates を開き、Server Certs タブの Install ボタンを押すと、Certificate Install Wizard が始まる。

第1画面では、前項で作成したCA署名済みサーバ証明書を読み込ませる。389ds-hogecert.pemcat するなりしてからクリップボードにコピーし、左図の Paste from Clipboard ボタンで貼り付ける方法が確実だ。同画面にはファイルを選択して読み込ませる選択肢も見られるが、その方法ではうまくいった試しがない。
第2画面で左図のようにサーバ証明書のパラメータが表示されれば正常。
第3の画面で、389 DS のセキュリティデバイス上でのこの証明書のニックネームを付ける。ディレクトリサーバインスタンス名か管轄ディレクトリルートツリーの DN を含めておくといいだろう。
最後に、セキュリティデバイスに設定してあるパスワードを入力。

CA証明書

Manage Certificates 画面の CA Certs タブで、前項同様に今度は CA証明書 cacert.pem の内容を貼り付ける。
第2画面に行くと、CA証明書の内容が表示されるはずだ。表示されない場合はうまく読み込めていない。一旦サーバ証明書を削除してから、CA証明書のほうを先にインストールするとうまくいった経験がある。
第3画面は確認のみ。The certificate will be named... の欄に某か表示されていて、Certificate type が CA Certificate になっていることを確認する。
第4画面はこの CA証明書の用途の指定。通常は両方とも有効にしおくのがいいだろう。後から変更することもできる。

証明書データベースファイルのパーミッション調整

Red Hat DS Administration Guide の "Configuring the Directory Server to Run in SSL/TLS" の推奨事項に従うのなら、/etc/dirsrv/slapd-<INSTANCE_NAME>/ にある cert8.dbkey3.db のファイルパーミッションを、インスタンス実行ユーザだけが読み書きできる状態にする。当ドキュメントの例だと dsadmin:dsadmin 0600 に設定することになる。

ディレクトリサーバインスタンスでSSL/TLSを有効にする

対象ディレクトリサーバインスタンスの Configuration タブを開き、ツリー上端のサーバ名 (左図でモザイクしてあるところ) を選択し、右ペインの Settings タブを開く。SSL 接続の待ち受けポートである Encrypted port 欄が想定通りのものになっていることを確認する。TLS 接続には通常ポート (389) を使う。デフォルトは、通常ポート 389、SSL 用ポート 636。
次に、Encryption タブを開き、
Enable SSL for this server にチェック、
Use this cipher family: RSA にチェック。
Security DeviceCertificateサーバ証明書のインストール時に指定したものに間違いないことを確認する。
"Client Authentication" 設定サブグループは、LDAPクライアントからサーバへの接続時に証明書による認証を行う場合のもので、通常はデフォルトの Allow client authentication (つまり認証は任意) のままでいい。
同グループの Use SSL in Console は、管理サーバインスタンスでも SSL/TLS を有効にするまでは、チェックを付けてはいけない。

設定を反映させるため、当該のディレクトリサーバインスタンスを再起動する。

root# service dirsrv restart centos5u

この時分かるように、インスタンスの起動の度にセキュリティデバイスのパスフレーズを人間がタイプしてやらなければならない。これでは 389 DS を自動起動できないし 389 Management Console からリモートで再起動するにも困る。そこで、パスワードファイルというものを作っておく。作成するファイルは /etc/dirsrv/slapd-<INSTANCE_NAME>/pin.txt。内容は下記。yourpassword のところは、当該ディレクトリサーバインスタンスのセキュリティデバイスに設定したパスワード。`:' とパスワードの間にスペースを挟んではならないのはもちろん、その前の固定句の大文字小文字やスペースの数も一字一句正確でなくてはならない。ファイルパーミッションは、ディレクトリサーバインスタンス実行ユーザの所有 (当ドキュメントの例だと dsadmin:dsadmin) で 0400 に設定すること。

Internal (Software) Token:yourpassword

もう一度サーバインスタンスを再起動して、パスフレーズを訊かれずエラーも出ないことを確認する。

接続テスト

mozldap 版の ldapsearch を使って TLS接続と SSL接続で検索を掛けてみる。

TLS接続のテスト

CA公開鍵 (証明書) を読み込む必要があるため -P オプションで証明書データベースを指定する必要がある。ただし、ldapsearch はカレントディレクトリから証明書データベースを探すようにできているので、先に /etc/dirsrv/slapd-centos5u/cd しておけば -P オプションは必要ない。

root# ldapsearch -h centos5u.hoge.com -p 389 \
    -ZZZ -P /etc/dirsrv/slapd-centos5u/cert8.db \
    -D "cn=usermanager,dc=hoge,dc=com" -w - \
    -b "ou=People,dc=hoge,dc=com" '(objectClass=person)'
SSL接続のテスト

TLSの時と違うのはポートと -Z オプションだけ。

root# ldapsearch -h centos5u.hoge.com -p 636 \
    -Z -P /etc/dirsrv/slapd-centos5u/cert8.db \
    -D "cn=usermanager,dc=hoge,dc=com" -w - \
    -b "ou=People,dc=hoge,dc=com" '(objectClass=person)'