LDAP連携とは関係ないのだが、せっかく検証したので TLS (Transport Layer Security) でメール通信を保護する方法についてもまとめておく。SSL と TLS との違いや TLS の概要について知りたければ、Dovecot の下記のドキュメントが簡潔にまとまっている。
なるべくリアルな検証とするため、自前の CA (認証局) を作り、サーバ証明書はその CA によって署名することにした。証明書関係の作業では、一部 OpenSSL も使うが、多少なりとも作業を楽にするため主として GnuTLS ユーティリティ (※) を使用する。CentOS/RHEL では gnutls-utils という名前で標準パッケージがあり、yum 等でインストールできる。certtool コマンドのオプションとテンプレートファイルのフォーマットについては GnuTLS オフィシャルマニュアルの "Invoking certtool" を参照。
証明書関係のファイル配置を下図に示す。サーバ秘密鍵/公開鍵は、Dovecot と Postfix で共用する。
/etc/pki/ \_ CA/ \_ cacert.pem <- 自前CAの自己署名公開鍵 root:root 444か644 \_ private/ \_ ca.info <- 自前CA自己署名用テンプレート root:root 600 cakey.pem <- 自前CAの秘密鍵 root:root 400 \_ tls/ \_ private/ \_ mailcert.info <- サーバ公開鍵用テンプレート root:root 600 mailkey.pem <- サーバ秘密鍵 root:root 400 \_ certs/ \_ mailcert.pem <- CA署名済みサーバ公開鍵 root:root 444か644 \_ cacert.pem <- 自前CAの自己署名公開鍵のコピー root:root 444か644
※ GnuTLS は、GNUライセンスでないため他のGNUソフトウェアと一緒には配布しにくいOpenSSLに代わって、新たに書かれGPL及びLGPL下で配布されているSSLライブラリ。GnuTLSユーティリティはOpenSSLを使いやすくするラッパーかと思っていたのだがそうではなかった。
自前の認証局を作る。もちろん、本物の CA (Verisign等) に署名してもらう場合や既に自前の 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
まず、CA証明書(公開鍵)生成のためのテンプレートファイル /etc/pki/CA/private/ca.info を作成する。内容は下記の要領。`serial=xxxx' の指定をしないと証明書のシリアルナンバーが `00' になり、Thunderbird で使う時に文句を言われた。有効期限は極端に長くしておけばいいだろう (例では10年)。
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/ にコピーしておく。このファイルは公開鍵なので誰でも読めるようにして構わない。
ここで作成する秘密鍵と公開鍵(証明書)は Postfix でも使う。
Dovecot のソースに付属する mkcert.sh スクリプト(※) を利用する手もあるが、サーバ証明書を CA で署名する場合にはかえって面倒。Dovecot インストール時に生成されたプライベートキー /etc/pki/dovecot/private/dovecot.pem をコピーして利用するか、openssl で単純に生成したほうがいい。生成するなら、
root# cd /etc/pki/tls/private root# openssl genrsa -out mailkey.pem 1024 root# chmod 400 mailkey.pem
※ CentOS/RHEL 5.x では /usr/share/doc/dovecot-*.*/examples/ にインストールされる。
Dovecot のインストールの際に /etc/pki/dovecot/certs/dovecot.pem が生成されるが、それは自己署名証明書なので使わない。
まず、テンプレートファイル /etc/pki/tls/private/mailcert.info を作成する。証明書タイプ (下記最後の3行) には tls_www_server, encryption_key が必要。signing_key は不明。
cn=mail.hoge.cxm organization="Hoge Net" unit="IT Development" state="Aichi" locality="Nagoya" country=JP expiration_days=730 serial=1001 tls_www_server encryption_key signing_key
CA署名済みのサーバ証明書 (公開鍵) を作成する。本物の CA に署名してもらう場合は下記参照(※)。
root# cd /etc/pki/tls/private root# certtool -c \ --load-privkey mailkey.pem \ --load-ca-certificate /etc/pki/CA/cacert.pem \ --load-ca-privkey /etc/pki/CA/private/cakey.pem \ --template mailcert.info \ --outfile ../certs/mailcert.pem
内容を確認するには、
root# certtool -i --infile ../certs/mailcert.pem
※ 本物の CA に署名を依頼する場合は、上記の代わりに CSR を作る。
root# certtool -q \ --load-privkey mailkey.pem \ --template mailcert.info \ --outfile mailcert.csr
内容を確認するには、
root# openssl req -noout -text -in mailcert.csr
下記のパラメータを調整する。Dovecot Wiki の "Dovecot SSL configuration" に解説あり。
#disable_plaintext_auth = yes <- [補足参照] ssl_disable = no <- SSL/TLS機能を有効にする ssl_cert_file = /etc/pki/tls/certs/mailcert.pem <- 公開鍵(証明書)のパス ssl_key_file = /etc/pki/tls/private/mailkey.pem <- 秘密鍵のパス ssl_parameters_regenerate = 0 <- Diffie Hellmanパラメータの定期的な再生成を行わない[補足参照] ssl_cipher_list = ALL:!LOW:!SSLv2 <- 暗号強度の規制 [補足参照]
[補足]
設定したら、反映させるために Dovecot デーモンを再起動する。
準備として、メールサーバの公開ホスト名 (サーバ公開鍵を作る時に cn に指定したもの) が名前解決できるよう、クライアント上の hosts ファイルまたは DNSサーバにレコードを登録しておかなければならない。
hoshu$ telnet mail.hoge.cxm 110 Escape character is '^]'. +OK ready capa +OK CAPA TOP UIDL RESP-CODES PIPELINING STLS <- リストの中にこれが出ればOK USER SASL PLAIN . stls +OK Begin TLS negotiation now. <- こういったメッセージが返ってくればOK quit quit
/etc/pki/CA/cacert.pem を一般ユーザで読める場所 (例えば /tmp) へコピーしておいてから、
hoshu$ openssl s_client -starttls pop3 -crlf -CAfile /tmp/cacert.pem \ -connect mail.hoge.cxm:110 CONNECTED(00000003) depth=1 /C=JP/O=Hoge Net/OU=Hoge Net Certificate Authority/CN=Hoge Net CA verify return:1 depth=0 /C=JP/O=Hoge Net/OU=IT Development/L=Nagoya/ST=Aichi/CN=mail.hoge.cxm verify return:1 --- Certificate chain 0 s:/C=JP/O=Hoge Net/OU=IT Development/L=Nagoya/ST=Aichi/CN=mail.hoge.cxm i:/C=JP/O=Hoge Net/OU=Hoge Net Certificate Authority/CN=Hoge Net CA --- <- 中略 -> --- SSL handshake has read 1523 bytes and written 354 bytes --- New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA Server public key is 1024 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : DHE-RSA-AES256-SHA Session-ID: ********************** Session-ID-ctx: Master-Key: ******************************* Key-Arg : None Krb5 Principal: None Start Time: 1303996441 Timeout : 300 (sec) Verify return code: 0 (ok) --- +OK ready user ****** +OK pass ****** +OK Logged in. quit +OK Logging out. read:errno=0
あとは、実際のメールクライアントで試験。メールサーバ証明書を自前CA でサインした場合は、自前CAの証明書をクライアントメーラーでインポートしてからテストする。
サーバ証明書は Dovecot の TLS設定で作成したものを共用する。Postfix だけ設定したい人は、そちらを見て作成しておいていただきたい。
main.cf に以下のパラメータを加える。設定のガイドラインは Postfix.org の "Postfix TLS Support" を参照するといい。
smtpd_tls_security_level = may #smtpd_tls_auth_only = no smtpd_tls_cert_file = /etc/pki/tls/certs/mailcert.pem smtpd_tls_key_file = /etc/pki/tls/private/mailkey.pem smtpd_tls_session_cache_database = btree:/var/run/postfix/smtpd_tls_session #smtpd_tls_session_cache_timeout = 3600s smtpd_tls_dh1024_param_file = /etc/postfix/dh_1024.pem smtpd_tls_dh512_param_file = /etc/postfix/dh_512.pem #tls_random_source = dev:/dev/urandom #tls_random_bytes = 32 #tls_random_reseed_period = 3600s #smtpd_tls_loglevel = 1
設定したら、反映のため Postfix をリロードまたは再起動する。
前提として、メールサーバの公開ホスト名 (サーバ公開鍵を作る時に cn に指定したもの) が名前解決できなければならない。まだやってなければ、クライアント上の hosts ファイルまたは DNSサーバにレコードを登録しておこう。
hoshu$ telnet mail.hoge.cxm 25 Trying 192.168.0.1... Connected to mail.hoge.cxm (192.168.0.1). Escape character is '^]'. 220 mail.hoge.cxm ESMTP Postfix ehlo localhost 250-mail.hoge.cxm 250-PIPELINING 250-SIZE 512000000 250-VRFY 250-ETRN 250-STARTTLS <- STARTTLSが出ていればOK 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN starttls 220 2.0.0 Ready to start TLS <- こういったメッセージが返ってくればOK quit quit
/etc/pki/CA/cacert.pem を一般ユーザで読める場所 (例えば /tmp) へコピーしておいてから、
hoshu$ openssl s_client -starttls smtp -crlf -CAfile /tmp/cacert.pem \ -connect mail.hoge.cxm:25 CONNECTED(00000003) depth=1 /C=JP/O=Hoge Net/OU=Hoge Net Certificate Authority/CN=Hoge Net CA verify return:1 depth=0 /C=JP/O=Hoge Net/OU=IT Development/L=Nagoya/ST=Aichi/CN=mail.hoge.cxm verify return:1 --- Certificate chain 0 s:/C=JP/O=Hoge Net/OU=IT Development/L=Nagoya/ST=Aichi/CN=mail.hoge.cxm i:/C=JP/O=Hoge Net/OU=Hoge Net Certificate Authority/CN=Hoge Net CA --- <- 中略 -> --- 250 DSN auth plain ************************** 235 2.0.0 Authentication successful <- こういったメッセージが返ってくればOK quit 221 2.0.0 Bye read:errno=0
あとは、実際のメールクライアントで試験。メールサーバ証明書を自前CA でサインした場合は、自前CAの証明書をクライアントメーラーでインポートしてからテストする。