PostfixでTLSサポートを有効にすることで、メールを暗号化したりクライアントや サーバの認証もできるようになるだけではありません。数千行にもおよぶ OpenSSL ライブラリコードも有効にしてしまうのです。OpenSSL が Wietse 自身のコードと 同じくらい注意深く書かれているとすると、1000行ごとに1つ、余分なバグをPostfixに 取り入れていることになります。
トランスポート層セキュリティ (Transport Layer Security/TLS、以前はSSLと 呼ばれていました) は証明書ベースの認証と暗号化セッションを提供します。 セッションの暗号化により、SMTPメールやSASL認証で伝送される情報が保護されます。
Postfixバージョン2.2は、RFC 3207に記述されているTLSサポートを組み込みました。古いバージョンの PostfixでのTLSサポートはアドオンパッチとして入手できます。以下の "Postfix < 2.2 TLSサポートの互換性" でこれらの実装の 違いを議論しています。
このドキュメントがカバーしているトピック:
大事なことを書き忘れたが、せっかちな人のために:
以下の図はPostfix TLSアーキテクチャの主な要素とその関係を表しています。 数字が付いた名前の書かれた色つきの箱はPostfixデーモンプログラムを表して います。他の色つきの箱はストレージ要素を示しています。
smtpd(8) サーバはSMTP over TLSのサーバ サイドを実装しています。
smtp(8) クライアントはSMTP over TLSの クライアントサイドを実装しています。
tlsmgr(8) サーバは smtpd(8) サーバおよび smtp(8) クライアントプロセスに種を与える擬似乱数生成器 (pseudo-random number generator, PRNG) を管理し、またTLSセッションキーキャッシュファイルも管理します。
ネットワーク-> | smtpd(8) |
<--シード-- <-セッション-> | tlsmgr(8) |
--シード--> <-セッション-> | smtp(8) | ->ネットワーク | ||||||||||
| | | |
| ||||||||||||||
smtpd セッション キーキャッシュ | PRNG 状態 ファイル | smtp セッション キーキャッシュ |
TLSサポートを付けてPostfixをビルドするには、まず必要な定義の書かれた make(1) ファイルを生成する必要があります。これはPostfixトップレベル ディレクトリで "make makefiles" コマンドに次に示す短い引数を付けて 呼び出すことで生成されます。
注意: Gnu TLSを使わないでください。Postfixは 1) maillogファイルに エラーを報告して、2) 適切な平文サービスを提供できず、Postfixデーモン プロセスは終了ステータスコード2で終了させられてしまいます。
OpenSSL インクルードファイル (ssl.h のような) が /usr/include/openssl ディレクトリにあり、(libssl.so や libcrypto.so) が /usr/lib ディレクトリにある場合:
% make tidy # 以前のビルドで残っているファイルがある場合 % make makefiles CCARGS="-DUSE_TLS" AUXLIBS="-lssl -lcrypto"
OpenSSL インクルードファイル (ssl.h のような) が /usr/local/include/openssl ディレクトリにあり、OpenSSL ライブラリ (libssl.so や libcrypto.so のような) が /usr/local/lib ディレクトリにある場合:
% make tidy # 以前のビルドで残っているファイルがある場合 % make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \ AUXLIBS="-L/usr/local/lib -lssl -lcrypto"
Solarisでは、以下に示すように -R オプションを指定します:
% make tidy # 以前のビルドで残っているファイルがある場合 % make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \ AUXLIBS="-R/usr/local/lib -L/usr/local/lib -lssl -lcrypto"
他のカスタマイズ (Berkeley DBデータベースや MySQL、PostgreSQL、LDAP、 SASLなど) を適用する必要があれば、それぞれのPostfix READMEドキュメントを 参照し、それらの "make makefiles" の指示と上の指示を組み合わせて ください:
% make tidy # 以前のビルドで残っているファイルがある場合 % make makefiles CCARGS="-DUSE_TLS \ (other -D or -I options)" \ AUXLIBS="-lssl -lcrypto \ (/usr/lib にある他のライブラリ用の -l オプション) \ (他のライブラリ用の -L/path/name + -l オプション)"
構築プロセスを完了するには、Postfix INSTALL の指示を参照してください。PostfixはデフォルトでTLSサポートが無効になって いるため、インストールしたらすぐにPostfixを使い始めることができます。
このセクションがカバーしている話題:
TLSを使用するために、Postfix SMTPサーバは証明書と秘密鍵を必要とします。 どちらも "pem" 形式でなければいけません。秘密鍵を暗号化してはいけません。 つまり: 鍵はパスワードなしでアクセスできなければいけません。証明書と秘密鍵が 両方とも同じファイルに入っているかもしれません。
RSAおよびDSA証明書の両者がサポートされています。たいていは商用CAによって 発行されたRSA証明書のみを持っていることでしょう。さらに、OpenSSLとともに 提供されるツールはデフォルトでRSA証明書を発行します。同時に両方とも持つことが でき、その場合には使われる暗号によってどちらの証明書が出されるかが決まります。 NetscapeおよびOpenSSLクライアントでは特に暗号を選ばない限り、RSA証明書が 優先されます。
リモートSMTPクライアントがPostfix SMTPサーバ証明書をチェックするには、 CA証明書 (証明書チェーンの場合はすべてのCA証明書) が入手可能でなければ いけません。これらの証明書をサーバ証明書に加えるとよいでしょう。その場合は サーバ証明書を最初にして、それから発行CAのものとします。
例: "server.dom.ain" の証明書は "intermediate CA" により発行され、 それ自身は "root CA" により発行された証明書を持っているとします。次のように server.pem ファイルを作成します:
% cat server_cert.pem intermediate_CA.pem > server.pem
ここで与えられるPostfix SMTPサーバ証明書はSSLサーバ証明書として使えなければ なりません。つまり "openssl verify -purpose sslserver ..." テストを通らなければ いけません。
ルートCAを信頼しているクライアントはルートCA証明書のローカルコピーを 持っているため、ここにルートCA証明書を含めておく必要はありません。 "server.pem" からそれを除いておくと、TLS交換のオーバーヘッドを減らせます。
これらのCAによって発行されたリモートSMTPクライアント証明書をPostfix SMTP サーバが受け付けるようにしたければ、ルート証明書を $smtpd_tls_CAfile に追記するか、 $smtpd_tls_CApath ディレクトリに インストールします。ルートCAの信頼を設定すると、$smtpd_tls_ccert_verifydepth が 注目するクライアントへの証明書チェーンにおけるCAの数よりも小さくなければ、 ルートCAによって署名された中間CAを明示的に信頼する必要はありません。検証の 深さを1とすると、信頼する CAによって直接署名された証明書のみを検証します。 深さが2であれば、ルートCAもしくは直接の中間CA によって署名されたクライアントを 検証できます (クライアントが中間CA証明書を提供するように正しく設定されている 限り)。
RSA鍵と証明書の例:
/etc/postfix/main.cf: smtpd_tls_cert_file = /etc/postfix/server.pem smtpd_tls_key_file = $smtpd_tls_cert_file
DSAで対応するもの:
/etc/postfix/main.cf: smtpd_tls_dcert_file = /etc/postfix/server-dsa.pem smtpd_tls_dkey_file = $smtpd_tls_dcert_file
リモートSMTPクライアント証明書を検証するには、Postfix SMTPサーバは発行証明 機関の証明書を信頼する必要があります。これらの "pem" 形式の証明書は単一 ファイルの $smtpd_tls_CAfile として保管するか、CA ごとに1ファイルとして複数ファイルを $smtpd_tls_CApath ディレクトリに 保存できます。ディレクトリを使うのであれば、以下のコマンドで "hash" リンクを 作成するのを忘れないでください:
# $OPENSSL_HOME/bin/c_rehash /path/to/directory
$smtpd_tls_CAfile は 1つ以上の信頼したCAのCA証明書を含んでいます。このファイルはPostfixが オプションのchroot監獄に入る前に (root権限で) 開かれるため、chroot監獄から アクセスできる必要はありません。
信頼された他のCAは $smtpd_tls_CApath ディレクトリを通して指定できますが、その場合証明書は $mail_owner 情報が必要なときにこの ディレクトリのファイルから読み込まれます。そのため、 $smtpd_tls_CApath ディレクトリは オプションのchroot監獄の内部でアクセスできる必要があります。
クライアント証明書を要求するようにPostfixを ($smtpd_tls_ask_ccert = yes を セットして) 設定する場合、あなたが信頼しているCAによって署名された証明書を 選べるように、$smtpd_tls_CAfile のあらゆる証明書がクライアントに送られます。 $smtpd_tls_CAfile が指定 されていないと、優先CAリストは送られず、クライアントはいずれかのCAによって 署名された証明書を自由に選びます。多くのクライアントは優先CAリストに関係なく 決まった証明書を送るので、クライアントCA証明書のほどんどもしくはすべてを $smtpd_tls_CApath に インストールすることで、TLSネゴシエーションのオーバーヘッドを減らすことが できるでしょう。後者の場合、$smtpd_tls_CAfile を指定する必要はありません。
注意: 多くのTLS認証されたクライアントがアクセスするのにクライアント証明書が 使えないのであれば、クライアント証明書を全く求めないのがよいでしょう。 オーバーヘッドが増えるのに加えて、クライアント証明書を要求されると TLSハンドシェイクを完了できないクライアント (特に一部のqmail) もあるためです。
例:
/etc/postfix/main.cf: smtpd_tls_CAfile = /etc/postfix/CAcert.pem smtpd_tls_CApath = /etc/postfix/certs
Postfix SMTPサーバのTLS行動に関してさらなる情報を得るために、ログレベルを 0から4まで増加させることができます。それぞれのログレベルは下位のログレベルで 記録される情報も含みます。
0 TLS行動に関するログ記録を無効にします。 1 TLSハンドシェイクと証明書の情報をログに記録します。 2 TLSネゴシエーションの間のレベルをログに記録します。 3 TLSネゴシエーションプロセスの16進数およびASCIIダンプを ログに記録します。 4 STARTTLS以降の通信の16進数およびASCIIダンプを完全に ログに記録します。
問題があったときのみログレベル3を使ってください。ログレベル4は使わない ことを強くおすすめします。
例:
/etc/postfix/main.cf: smtpd_tls_loglevel = 0
クライアントや発行者のCommonNameと同様に、使用されているプロトコルおよび 暗号に関する情報を "Received:" メッセージヘッダに含めるには、 smtpd_tls_received_header 変数を true にセットします。デフォルトは no で、 それは情報が必ずしも正しくないためです。ヘッダは中間サーバによって変更できて しまうため、最終配送先で記録された情報のみが信頼できます。
例:
/etc/postfix/main.cf: smtpd_tls_received_header = yes
デフォルトではPostfix SMTPサーバのTLSは無効になっており、見た目にはそのままの Postfixと違いはありません。明示的に "smtpd_use_tls = yes" を使って有効に切り替えてください。
例:
/etc/postfix/main.cf: smtpd_use_tls = yes
これを設定すると、Postfix SMTPサーバはSMTPクライアントにSTARTTLSサポートを 案内しますが、クライアントがTLS暗号化を使うことを要求するわけではありません。
注意: 権限のないユーザが "sendmail -bs" を呼び出した場合、サーバ秘密鍵に アクセスする権限がないため、STARTTLSは提供されません。これは意図した動作です。
"smtpd_enforce_tls = yes" を設定することでTLSの使用を「強制」することもでき、そうするとPostfix SMTP サーバはSTARTTLSを案内し、TLSで暗号化されていないメールは受け付けません。 RFC 2487に従うと、これは 公に参照される Postfix SMTPサーバには適用しては「いけません」。この オプションはデフォルトで無効になっており、ほとんど使われることはないでしょう。
例:
/etc/postfix/main.cf: smtpd_enforce_tls = yes
TLSは時々、STARTTLSサポートをアナウンスしてクライアントがTLSサービスを 要求するのではなく、サーバが常にTLSを使う、非標準 "ラッパー" モードで 使われることがあります。一部のクライアント、はっきり言うと Outlook [Express] は "ラッパー" モードを優先します。これは OE (ポート25以外で動くWin32 < 5.0 およびWin32 >=5.0) と OE (ポートに関係なく5.01 Mac) に当てはまります。
main.cf からこのモードを使うのは全くお勧めしません。このサービスをサポート したいのであれば、master.cf の特別なポートを有効にし、smtpd(8) のコマンドラインオプションとして "-o smtpd_tls_wrappermode = yes" を指定してください。この機能のためにポート465 (smtps) がかつて選ばれていました。
例:
/etc/postfix/master.cf: smtps inet n - n - - smtpd -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes
リモートのSMTPクライアント証明書を受け取るには、Postfix SMTPサーバは 明示的に証明書を要求しなければいけません (適切なCAから証明書を選ぶヒントとして $smtpd_tls_CAfile の内容も クライアントに送られます)。残念ながら、Netscapeクライアントはマッチする クライアント証明書が得られないと文句を言うか、ユーザクライアントに選択 するための証明書のリストを提示するかのどちらかです。さらに、一部のMTA (特に一部のバージョンのqmail) はクライアント証明書が要求されるとTLS ネゴシエーションを完了できず、SMTPセッションを中断してしまいます。そのため、 このオプションはデフォルトでは "off" になっています。しかし、例えば permit_tls_clientcerts 機能を使って証明書ベースの中継をさせたければ、証明書が必要となるでしょう。
例:
/etc/postfix/main.cf: smtpd_tls_ask_ccert = no
TLS接続を許可する前にリモートSMTPクライアント証明書を「要求する」と決める こともできます。この機能は完全を期すために含まれており、 "smtpd_tls_ask_ccert = yes" という意味も含みます。
これは正しいクライアント証明書なしでのTLS接続を禁止するということと、 非TLSの投函を無効にしている場合 (smtpd_enforce_tls = yes) にのみ意味をなすということに注意してください。そうしないと、クライアントは STARTTLSを全く使わなくするだけでこの制限を回避できてしまいます。
TLSが強制されていないと、接続は "smtpd_tls_ask_ccert = yes" だけが指定されているだけのように扱われ、警告がログに記録されます。
例:
/etc/postfix/main.cf: smtpd_tls_req_ccert = no
CAファイルに列挙されたCAによって直接発行された証明書の場合、クライアント 証明書の検証の深さは1で十分です。デフォルト値 (5) はより長いチェーンでも 十分な値です (ルートCAは実際に証明書を発行する特別なCAを発行して...)。
例:
/etc/postfix/main.cf: smtpd_tls_ccert_verifydepth = 5
AUTHデータを暗号化されていないチャネル越しに送ることはセキュリティリスクを もたらすことになります。TLSレイヤの暗号化が要求されると (smtpd_enforce_tls = yes)、 Postfix SMTPサーバはTLSレイヤがSTARTTLSで動き出してからのみAUTHを案内し、 また受け付けます。TLSレイヤの暗号化がオプションの場合 (smtpd_enforce_tls = no)で あっても、TLSが動作しているときのみAUTHを提供する方が便利です。非TLS クライアントとの互換性を維持するために、デフォルトでは暗号化なしでもAUTHを 受け付けます。この振る舞いを変更するには、 "smtpd_tls_auth_only = yes" を設定してください。
例:
/etc/postfix/main.cf: smtpd_tls_auth_only = no
Postfix SMTPサーバおよびリモートのSMTPクライアントがセッションの ネゴシエーションをおこなうと、いくらか計算時間とネットワークのバンド幅を 消費します。デフォルトでは、このセッションを実際に使っている smtpd(8) プロセスでセッション情報はキャッシュされ、 プロセスが終了するとセッション情報も失われます。セッション情報を複数の smtpd(8) プロセスで共有するために、永続性セッション キャッシュが使えます。数キロバイトのオブジェクトを保存できて連続操作を サポートしている、どんなデータベース形式でも指定することができます。 DBMデータベースは小さなオブジェクトしか保存できないため、これには適しません。 キャッシュは tlsmgr(8) プロセスによって管理される ため、並列アクセスでも問題ありません。TLSセッションキーを繰り返しやりとり するのは負荷が高いため、セッションをキャッシュすることを強く推奨します。
例:
/etc/postfix/main.cf: smtpd_tls_session_cache_database = btree:/etc/postfix/smtpd_scache
キャッシュされたPostfix SMTPサーバセッション情報は一定の時間が経過すると 失効します。Postfix/TLSはOpenSSLのデフォルトである300秒は使わず、もっと 長い時間の3600秒 (=1時間) を使います。RFC 2246 は最大の24時間を推奨しています。
例:
/etc/postfix/main.cf: smtpd_tls_session_cache_timeout = 3600s
Postfix TLSサポートによってPostfix SMTPサーバアクセス制御に3つの機能が 追加されました:
- permit_tls_clientcerts
クライアント 証明書が検証を通り、そのフィンガープリントがクライアント証明書のリストに リストアップされている場合に、リモートのSMTP クライアントがSMTP要求を 出すことを許可します (以下の relay_clientcerts の議論を参照)。
- permit_tls_all_clientcerts
クライアント 証明書が検証を通った場合に、リモートクライアントがSMTP 要求を出すことを 許可します。
- check_ccert_access type:table
クライアント証明書が検証を通った場合に、指定された access(5) テーブルのキーとしてそのフィンガー プリントを使います。
permit_tls_all_clientcerts 機能は注意して使わなければいけません。というのは、アクセス権限が多く なりすぎるかもしれないためです。ある特別なCAがクライアント証明書を発行し、 このCAが信頼されたCAとしてリストアップされている場合にのみ、この機能を 使ってください。他のCAが信頼されていると、有効なクライアント証明書の所有者は みんな認証されてしまいます。 permit_tls_all_clientcerts 機能は特別に作られたEメールリレーサーバには実用的かもしれません。
しかし、証明書が使われなくなったとき (例えば従業員の退職など) には permit_tls_clientcerts がいかなる制御も許可しないため、permit_tls_all_clientcerts 機能にとどまって $relay_clientcerts を通してすべての証明書をリストアップ するのがお勧めです。
例:
/etc/postfix/main.cf: smtpd_recipient_restrictions = ... permit_tls_clientcerts reject_unauth_destination ...
Postfixのリスト操作ルーチンは空白やその他一部の文字を特別扱いするため、 証明書名の使用は実用的ではありません。そこで代わりに偽造が困難で検索に 使いやすい、証明書のフィンガープリントを使います。Postfix検索テーブルは (キー, 値) ペアの形です。キーだけが必要なので、値は自由に選ぶことができます。 例えばユーザ名やホスト名など。
例:
/etc/postfix/main.cf: relay_clientcerts = hash:/etc/postfix/relay_clientcerts /etc/postfix/relay_clientcerts: D7:04:2F:A7:0B:8C:A5:21:FA:31:77:E1:41:8A:EE:80 lutzpc.at.home
Postfix SMTPサーバの暗号選択スキームに影響を与えるため、暗号化方式の リストを与えることができます。詳しい記述はここから遠いところにあります; OpenSSLのドキュメントを参照してください。ここでどうすればよいかわからなければ、 単にこれにはふれずに (opensslを) デフォルトでコンパイルしたままにしておいて ください!
文字列を括るのに " を「使わないで」、文字列だけを指定してください!!!
例:
/etc/postfix/main.cf: smtpd_tls_cipherlist = DEFAULT
EDH で暗号を利用したければ、DH パラメータが必要です。1024bitおよび 512bit用のビルトインDHパラメータを使う代わりに、"独自の" パラメータを 生成するのがよいでしょう。そうしないと、潜在的な攻撃者がみんなが使っている パラメータに対してブルートフォース攻撃を始めることに価値が出てしまいます。 そのため、選ばれているパラメータは、他のTLSパッケージで配布されるものとは すでに異なっています。
自分自身の DH パラメータのセットを生成するには次のコマンドを使います:
% openssl gendh -out /etc/postfix/dh_1024.pem -2 -rand /var/run/egd-pool 1024 % openssl gendh -out /etc/postfix/dh_512.pem -2 -rand /var/run/egd-pool 512
例:
/etc/postfix/main.cf: smtpd_tls_dh1024_param_file = /etc/postfix/dh_1024.pem smtpd_tls_dh512_param_file = /etc/postfix/dh_512.pem
smtpd_starttls_timeout パラメータはTLSのハンドシェイク手順の開始から終了までの間にPostfix SMTP サーバが読み書きできる時間を制限します。
例:
/etc/postfix/main.cf: smtpd_starttls_timeout = 300s
このセクションでカバーされる話題:
TLS起動ネゴシエーションの間に、Postfix SMTPクライアントは証明書を リモートのSMTPサーバに渡すことができます。ここでNetscapeクライアントは より賢く、モートのSMTPサーバから示されたCA証明書にマッチするクライアント 証明書だけの中からユーザに選択させます。Postfix SMTPクライアントはOpenSSL パッケージの "SSL_connect()" 関数を使うためそのような動作は不可能であり、 ただ一つの証明書を選ぶ必要があります。そのため、ここで明示的に指定されない 限り、今のところデフォルトでは証明書や鍵を_使いません_。
RSAおよびDSA証明書の両者がサポートされています。同時に両方持つことができ、 その場合には使われる暗号によってどちらの証明書が出されるかが決まります。
Postfix SMTPクライアントはPostfix SMTPサーバと同じ鍵/証明書ペアを使う ことができます。証明書を出す場合には、"pem" フォーマットである必要があります。 秘密鍵を暗号化してはいけません。つまり: パスワードなしでアクセスできなければ いけません。両方の部品 (証明書と秘密鍵) は同じファイルに入れることもできます。
リモートSMTPサーバがPostfix SMTPクライアント証明書を検証するために、 CA証明書 (証明書チェーンの場合はすべてのCA証明書) が入手可能でなければ いけません。これらの証明書をサーバ証明書に加えるとよいでしょう。その場合は クライアント証明書を最初にして、それから発行CAのものとします。
例: "client.example.com" の証明書がそれ自身 "ルートCA" である "intermediate CA" によって発行されました。次のように client.pem ファイルを 作ります:
% cat client_cert.pem intermediate_CA.pem > client.pem
ここで与えられるPostfix SMTPクライアント証明書はSSLクライアント証明書 として使えなければなりません。つまり "openssl verify -purpose sslclient ..." テストを通らなければいけません。
ルートCAを信頼しているサーバはルートCA証明書のローカルコピーを持って いるため、ここにルートCA証明書を含めておく必要はありません。"client.pem" からそれを除いておくと、TLS交換のオーバーヘッドを減らせます。
これらのCAによって発行されたリモートSMTPサーバ証明書をPostfix SMTP クライアントが受け付けるようにしたければ、ルート証明書を $smtp_tls_CAfile に追記するか、 $smtp_tls_CApath ディレクトリに インストールします。ルートCAの信頼を設定すると、$smtp_tls_scert_verifydepth が 注目するサーバへの証明書チェーンにおけるCAの数よりも小さくなければ、 ルートCAによって署名された中間CAを明示的に信頼する必要はありません。検証の 深さを1とすると、信頼するCAによって直接署名された証明書のみを検証します。 深さが2であれば、ルートCAもしくは直接の中間CA によって署名されたサーバを 検証できます (サーバが中間CA証明書を提供するように正しく設定されている限り)。
RSA鍵と証明書の例:
/etc/postfix/main.cf: smtp_tls_cert_file = /etc/postfix/client.pem smtp_tls_key_file = $smtp_tls_cert_file
DSAで対応するもの:
/etc/postfix/main.cf: smtp_tls_dcert_file = /etc/postfix/client-dsa.pem smtp_tls_dkey_file = $smtpd_tls_cert_file
リモートSMTPサーバ証明書を検証するには、Postfix SMTPクライアントは発行証明 機関の証明書を信頼する必要があります。これらの "pem" 形式の証明書は単一 ファイルの $smtp_tls_CAfile として保管するか、CA ごとに1ファイルとして複数ファイルを $smtp_tls_CApath ディレクトリに 保存できます。ディレクトリを使うのであれば、以下のコマンドで "hash" リンクを 作成するのを忘れないでください:
# $OPENSSL_HOME/bin/c_rehash /path/to/directory
$smtp_tls_CAfile は1つ以上の 信頼したCAのCA証明書を含んでいます。このファイルはPostfixがオプションの chroot監獄に入る前に (root権限で) 開かれるため、chroot監獄からアクセスできる 必要はありません。
信頼された他のCAは $smtp_tls_CApath ディレクトリを通して指定できますが、その場合証明書は ($mail_owner 権限で) 情報が必要な ときにこのディレクトリのファイルから読み込まれます。そのため、 $smtp_tls_CApath ディレクトリは オプションのchroot監獄の内部でアクセスできる必要があります。
$smtp_tls_CAfile と $smtpd_tls_CApath との選択は 空間と時間のトレードオフです。信頼されたCAがたくさんある場合、すべてを あらかじめメモリに読み込むコストは証明書が必要となったときのアクセス時間が 減っても報われないかもしれません。
例:
/etc/postfix/main.cf: smtp_tls_CAfile = /etc/postfix/CAcert.pem smtp_tls_CApath = /etc/postfix/certs
Postfix SMTPクライアントのTLS行動に関してさらなる情報を得るために、 ログレベルを0から4まで増加させることができます。それぞれのログレベルは下位の ログレベルで記録される情報も含みます。
0 TLS行動に関するログ記録を無効にします。 1 TLSハンドシェイクと証明書の情報をログに記録します。 2 TLSネゴシエーションの間のレベルをログに記録します。 3 TLSネゴシエーションプロセスの16進数およびASCIIダンプを ログに記録します。 4 STARTTLS以降の通信の16進数およびASCIIダンプを完全に ログに記録します。
例:
/etc/postfix/main.cf: smtp_tls_loglevel = 0
リモートのSMTPサーバおよびPostfix SMTPクライアントがセッションの ネゴシエーションをおこなうと、いくらか計算時間とネットワークのバンド幅を 消費します。デフォルトでは、このセッションを実際に使っている smtp(8) プロセスでセッション情報はキャッシュされ、 プロセスが終了するとセッション情報も失われます。セッション情報を複数の smtp(8) プロセスで共有するために、永続性 セッションキャッシュが使えます。数キロバイトのオブジェクトを保存できて 連続操作をサポートしている、どんなデータベース形式でも指定することができます。 DBMデータベースは小さなオブジェクトしか保存できないため、これには適しません。 キャッシュは tlsmgr(8) プロセスによって管理される ため、並列アクセスでも問題ありません。TLSセッションキーを繰り返し交換するのは 負荷が高いため、セッションをキャッシュすることを強く推奨します。Postfix SMTP サーバは将来、1つのクライアントが単位時間あたりに交換できるセッションの数を 制限することになるでしょう。
例:
/etc/postfix/main.cf: smtp_tls_session_cache_database = btree:/etc/postfix/smtp_scache
キャッシュされたPostfix SMTPクライアントセッション情報は一定の時間が 経過すると失効します。Postfix/TLSはOpenSSLのデフォルトである300秒は使わず、 もっと長い時間の3600秒 (=1時間) を使います。RFC 2246 は最大の24時間を推奨しています。
例:
/etc/postfix/main.cf: smtp_tls_session_cache_timeout = 3600s
デフォルトではPostfix SMTPクライアントのTLSは無効になっており、見た目には そのままのPostfixと違いはありません。TLSを有効にすると、リモートのSMTPサーバに よってTLSサポートが案内されたときにPostfix SMTPクライアントはSTARTTLSを 送ります。
サーバが STARTTLS コマンドを受け入れたがそれに続くTLSハンドシェイクに 失敗し、他に利用可能なサーバがない場合、Postfix SMTPクライアントは配送試行を 遅延し、メールはキューに残ります。ハンドシェイクに失敗すると、 コミュニケーションチャネルは不定状態になり、非TLS配送には使えなくなります。
例:
/etc/postfix/main.cf: smtp_use_tls = yes
TLSの使用を「強制する」こともできますが、そうするとPostfix SMTP クライアントは暗号化されていない接続ではメールを配送しません。このモードでは リモートSMTPサーバホスト名はリモートサーバ証明書の情報にマッチしなければ ならず、そのサーバ証明書はPostfix SMTPクライアントが信頼したCAによって 発行されていなければいけません。リモートサーバ証明書が検証できなかったり リモートSMTPサーバホスト名がマッチせず、他に使えるサーバがなければ、 配送試行は遅延され、キューに残り続けます。
リモートSMTPサーバホスト名は SubjectAlternativeName の dNSNames として 提供される全ての名前に対して検証されます。dNSNames が指定されていないと、 CommonName がチェックされます。以下で議論する smtp_tls_enforce_peername オプションで検証を無効にすることもできます。
RFC 2487 をサポートし、 _かつ_上の要求に合うサーバ証明書を出すサーバにのみ接続することがわかっている 場合には、TLSの利用を強制することは便利です。例としては、必要な STARTTLS サポートを提供する、ある特定のメールハブにのみ、クライアントがEメールを 送る場合です。
例:
/etc/postfix/main.cf: smtp_enforce_tls = yes
RFC 2487では、MTA クライアントがホスト名のチェックをおこなうことは要求されていません。TLSが 要求されると (smtp_enforce_tls = yes)、 厳格なリモートSMTPサーバホスト名チェックを無効にするためにオプション smtp_tls_enforce_peername が "no" にセットされます。この場合、メール配送は証明書にリストアップされた CommonName などとは関係なく進められます。
"中間者 (man-in-the-middle)" 攻撃や他の攻撃を減らす可能性があるのに、 現時点では証明書/peername検証の強制はデフォルトのインターネットメール配送 ポリシーとしては有効になっていません。TLSが有効になったMTAのかなりの割合が 自己署名証明書を使っているか、プライベート認証局によって署名された証明書を 使っています。インターネットにメールを配信するマシンでは、 smtp_enforce_tls = yes をセットする場合に smtp_tls_enforce_peername = no もセットすることになる でしょう。有効なTLSサーバ証明書を持っていることがわかっている特定の配送先に 対して完全なピア検証を有効にするために、サイトごとのTLSポリシー (以下参照) を 使うことができます。
例:
/etc/postfix/main.cf: smtp_enforce_tls = yes smtp_tls_enforce_peername = no
一部のサーバでは STARTTLS を提供しているもののネゴシエーションは常に失敗し、 メールはキューで期限を迎えて送信者にバウンスされてしまうことがあります。 そのような場合、サイトごとのポリシーを使って問題のサイトへのTLSを無効に できます。逆に特定の少数のサイトに対してのみTLSを有効にしてそれ以外には 有効にしないこともできます。
smtp_tls_per_site テーブルでは、 以下の情報にマッチするポリシーが検索されます:
- remote SMTP server hostname
- これはPostfix SMTPクライアントが 接続しようとするサーバの、単なるDNS名です; この名前はMX検索やCNAME検索など、 他のDNS検索から得られるものかもしれません。
- next-hop destination
- これは単に受信者アドレスのドメイン 部分ですが、transport(5) テーブルや relayhost パラメータ設定、 relay_transport 設定の情報で 上書きされるかもしれません。それが受信者ドメインではない場合、next-hop 配送先は Postfix特有の形式、"[name]" や [name]:port"、"name"、 "name:port" を持つことができます。
ホスト名検索とnext-hop検索の両方が成功した場合、ホストポリシーは自動的には next-hopポリシーを上書きしません。以下に示すような、より特定された、 もしくはより安全なサイトごとのポリシーが代わりに優先されます。
smtp_tls_per_site テーブルは単純な "name whitespace value" 形式を使います。左側にはホスト名または next-hop配送先を指定します; ワイルドカードは使えません。右側には以下の いずれかのキーワードを指定します:
- NONE
- TLSを全く使いません。これは代替ホストやnext-hop 検索キーからの、MAY という指定が弱い検索結果、およびグローバルな smtp_use_tls もしくは smtp_enforce_tls、 smtp_tls_enforce_peername 設定を上書きします。
- MAY
- サーバがTLSサポートを通知する場合にはSTARTTLSの使用を 試し、通知されなければ暗号化されていない接続を使います。これは代替ホストや next-hop検索キーからの、より強く特定された結果 (NONE を含む) およびより特定されたグローバルの "smtp_enforce_tls = yes" もしくは "smtp_tls_enforce_peername = yes" よりも低い優先度を持ちます。
- MUST_NOPEERMATCH
- STARTTLSの利用を要求しますが、リモートSMTP サーバホスト名がリモートSMTPサーバ証明書の情報にマッチすることや、リモート SMTPサーバ証明書が信頼するCAによって発行されていることは求めません。 これは代替ホストやnext-hop検索キーからの、安全性が弱い NONE や特定度の 弱い MAY 検索結果、およびグローバルな smtp_use_tls や smtp_enforce_tls、 smtp_tls_enforce_peername 設定を上書きします。
- MUST
- TLS暗号化を必須とします。リモートSMTPサーバホスト名が リモートSMTPサーバ証明書の情報にマッチし、リモートSMTPサーバ証明書が 信頼するCAによって発行されていなければいけません。これは代替ホストや next-hop検索キーからの、安全性が弱い NONE や MUST_NOPEERMATCH および特定度の弱い MAY といった検索結果、グローバルな smtp_use_tls や smtp_enforce_tls、 smtp_tls_enforce_peername 設定を上書きします。
グローバル (main.cf) TLSポリシーとサイトごとのTLSポリシーの間の優先度は 以下のようにまとめられます:
リモートSMTPサーバホスト名とnext-hop配送先のどちらも smtp_tls_per_site テーブルに見つからない場合、ポリシーは smtp_use_tls、 smtp_enforce_tls および smtp_tls_enforce_peername に基づきます。注意: "smtp_enforce_tls = yes" と "smtp_tls_enforce_peername = yes" は "smtp_use_tls = yes" も含みます。
ホスト名とnext-hop配送先の両方とも検索結果が見つかると、サイトごとの より制限の強いポリシー (NONE, MUST など) が制限の弱いポリシー (MAY) を 上書きし、またサイトごとのより安全なポリシー (MUST など) が安全ではない ポリシー (NONE) を上書きします。
サイトごとのポリシー検索が組み合わされた結果は、たいていの場合 グローバルポリシーを上書きします。制限の弱いサイトごとの MAY ポリシーは例外で、smtp_tls_enforce_peername パラメータで指定された証明書の検証を持つ、より制限の強いグローバルな "smtp_enforce_tls = yes" パラメータに支配されます。
安全なDNS検索メカニズムが使えない限り、MX応答やCNAME応答でのホスト名が 間違っていると、PostfixがTLSポリシー検索やサーバ証明書の検証で使うホスト名が 変わってしまいます。サーバホスト名とサーバ証明書が完全にマッチしていたと しても、Postfixが正しいサーバに接続されたかどうかは保証できません。 この抜け穴を避けるため、以下のステップに従ってください:
MX検索を止めます。注意が必要なドメインに対しては smtp:[mailhost] や smtp:[mailhost]:port 配送先としてローカルの transport(5) テーブルにエントリを指定します (DNSとは異なり、このテーブルの安全性はあなたが保証できます); smtp_tls_per_site テーブルで [mailhost] キーまたは smtp:[mailhost]:port キーに対して値 MUST を指定します。これによりDNS MXレコードで 間違った情報があっても、PostfixがTLSポリシー検索やサーバ証明書の検証で 使うホスト名が変わってしまうことがなくなります。
CNAMEによるホスト名の上書きを禁止します。main.cfで "smtp_cname_overrides_servername = no" を指定します。これによりDNS CNAMEレコードで間違った情報があっても、 PostfixがTLSポリシー検索やサーバ証明書の検証で使うホスト名が変わって しまうことがなくなります。この機能を使うには、Postfix 2.2.9以降が必要です。
例:
/etc/postfix/main.cf: smtp_tls_per_site = hash:/etc/postfix/tls_per_site relayhost = [msa.example.net]:587 /etc/postfix/tls_per_site: # relayhost exact nexthop match [msa.example.net]:587 MUST # TLS should not be used with the example.org MX hosts. example.org NONE # TLS should not be used with the host smtp.example.com. smtp.example.com NONE
TLSを使う使わないに関わらず "サイト単位" ベースとすることに決めたため、 "STARTTLS" を提供するサイトのリストを持つのに適しています。このオプションで 自分自身で集めることができます。
smtp_tls_note_starttls_offer 機能が有効になっていてサーバが STARTTLS を 提供しており、そのサーバに対してすでにTLSが有効になっているのでなければ、 Postfix SMTPクライアントは以下のような行をログに残します:
postfix/smtp[pid]: Host offered STARTTLS: [hostname.example.com]
例:
/etc/postfix/main.cf: smtp_tls_note_starttls_offer = yes
リモートSMTPサーバ証明書を検証する際、smtp_tls_CAfile または smtp_tls_CApath で 指定されたCAによって直接発行された証明書の場合、検証の深さは1で十分です。 デフォルト値 (5) はより長いチェーンでも十分な値です (ルートCAは実際に証明書を 発行する特別なCAを発行して...)。
例:
/etc/postfix/main.cf: smtp_tls_scert_verifydepth = 5
Postfix SMTPクライアントの暗号選択スキームに影響を与えるため、暗号化方式の リストを与えることができます。詳しい記述はここから遠いところにあります; OpenSSLのドキュメントを参照してください。ここでどうすればよいかわからなければ、 単にこれにはふれずに (opensslを) デフォルトでコンパイルしたままにしておいて ください!
文字列を括るのに " を「使わないで」、文字列だけを指定してください!!!
例:
/etc/postfix/main.cf: smtp_tls_cipherlist = DEFAULT
smtp_starttls_timeout パラメータはTLSのハンドシェイク手順の開始から終了までの間にPostfix SMTP クライアントが読み書きできる時間を制限します。問題が起こると、Postfix SMTP クライアントはメール交換機リストにある次のネットワークアドレスを試し、 代わりのサーバが使えなければ配送は遅延されます。
例:
/etc/postfix/main.cf: smtp_starttls_timeout = 300s
TLSのような暗号ソフトウェアのセキュリティは、キーやその他の情報に対して 予期できない数値を生成する能力に致命的に依存します。その目的のために、 tlsmgr(8) プロセスは擬似乱数生成器 (Pseudo Random Number Generator, PRNG) プールを管理します。これは smtp(8) および smtpd(8) プロセスの初期化の際に問い合わせを受けます。デフォルトでは、これらのデーモンは 32バイト、つまり256ビットを要求します。これは128ビット (もしくは168ビット) の セッションキーを生成するのに十分すぎます。
例:
/etc/postfix/main.cf: tls_daemon_random_bytes = 32
メモリ内PRNGプールを管理するため、tlsmgr(8) は起動時と動いている間に外部ソースからエントロピーを読み込みます。EGDや /dev/urandom のようなよいエントロピーソースを指定してください; non-blocking ソースだけを使うように気を付けてください (OpenBSDで tlsmgr(8) が /dev/urandom のタイムアウトに文句を言う場合には、/dev/arandom を使って ください)。エントロピーソースが通常のファイルではない場合、ソース名の前に ソース形式を付けなければいけません: デバイススペシャルファイルには "dev:" を、 EGD互換ソケットインターフェースを持つソースには "egd:" を付けます。
例 (main.cf で一つだけ指定します):
/etc/postfix/main.cf: tls_random_source = dev:/dev/urandom tls_random_source = egd:/var/run/egd-pool
デフォルトでは、tlsmgr(8) はシードを指定する イベントのたびに外部ソースから32バイトを読み込みます。これ (256ビット) は 128ビットの共通鍵を生成するのに十分すぎる量です。EGDおよびデバイスエントロピー ソースでは、tlsmgr(8) は一度に読み込むデータ量を 255バイトに制限します。通常のファイルをエントロピーソースとして指定した 場合は、より多くのデータを読み込むことができます。
例:
/etc/postfix/main.cf: tls_random_bytes = 32
メモリ内PRNGプールを更新するために、tlsmgr(8) は擬似乱数による時間が経過したら 再び外部エントロピーソースに問い合わせます。その時間はPRNGを使って計算され、 0から最大で tls_random_reseed_period で指定される時間の間の時間です。デフォルトの最大時間間隔は1時間です。
例:
/etc/postfix/main.cf: tls_random_reseed_period = 3600s
tlsmgr(8) プロセスは次回起動時にPRNG状態を 回復できるようにするため、一定時間経過時とプロセス終了時にPRNG状態を永続性 交換ファイルに保存します。このファイルが存在しない場合には作成されます。 デフォルトの場所はPostfix設定ディレクトリの下ですが、Postfixによって改変された 情報を置くにはふさわしくありません。代わりにファイルの場所を /var パーティション (しかしchroot監獄の中 以外) に置くのがよいでしょう。
例:
/etc/postfix/main.cf: tls_random_exchange_name = /etc/postfix/prng_exch tls_random_prng_update_period = 3600s
以下のステップですぐに始められるでしょう。自分自身のPostfix公開鍵証明書に 署名するため、TLS暗号化は使えますがTLS認証はできません。テストや信頼関係を 結んでいないサイトとのEメールの交換にはこれで十分です。実際に認証するには、 Postfixがリモートホストの公開鍵証明書を検証できるように、Postfix公開鍵証明書を 公認の認証局によって署名してもらい、Postfixが認証局の公開鍵証明書を持つように 設定する必要があります。
以下の例では、ユーザの入力は 太字 フォントで示しており、 また "#" プロンプトはスーパーユーザのシェルを示しています。
自分自身の公開鍵に署名できるように、自分自身の認証局になります。 この例ではOpenSSLに付いてくる CA.pl スクリプトを使います。デフォルトでは、 OpenSSLはこれを /usr/local/ssl/misc/CA.pl にインストールしますが、 場合によって異なります。このスクリプトは秘密鍵を ./demoCA/private/cakey.pem に、公開鍵を ./demoCA/cacert.pem に作ります。
% /usr/local/ssl/misc/CA.pl -newca CA certificate filename (or enter to create) Making CA certificate ... Using configuration from /etc/ssl/openssl.cnf Generating a 1024 bit RSA private key ....................++++++ .....++++++ writing new private key to './demoCA/private/cakey.pem' Enter PEM pass phrase:whatever
ホスト FOO に対する、パスワードのかかっていない秘密鍵と、署名されて いない公開鍵証明書を作成します。
% openssl req -new -nodes -keyout FOO-key.pem -out FOO-req.pem -days 365 Using configuration from /etc/ssl/openssl.cnf Generating a 1024 bit RSA private key ........................................++++++ ....++++++ writing new private key to 'FOO-key.pem' ----- 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) [AU]:US State or Province Name (full name) [Some-State]:New York Locality Name (eg, city) []:Westchester Organization Name (eg, company) [Internet Widgits Pty Ltd]:Porcupine Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []:FOO Email Address []:wietse@porcupine.org Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:whatever An optional company name []:
数ステップ前に作った認証局秘密鍵でホスト FOO の公開鍵証明書に 署名します。
% openssl ca -out FOO-cert.pem -infiles FOO-req.pem Uing configuration from /etc/ssl/openssl.cnf Enter PEM pass phrase:whatever Check that the request matches the signature Signature ok The Subjects Distinguished Name is as follows countryName :PRINTABLE:'US' stateOrProvinceName :PRINTABLE:'New York' localityName :PRINTABLE:'Westchester' organizationName :PRINTABLE:'Porcupine' commonName :PRINTABLE:'FOO' emailAddress :IA5STRING:'wietse@porcupine.org' Certificate is to be certified until Nov 21 19:40:56 2005 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
ホストの秘密鍵、ホストの公開鍵証明書、および認証局証明書ファイルを インストールします。これにはスーパーユーザの権限が必要です。
# cp demoCA/cacert.pem FOO-key.pem FOO-cert.pem /etc/postfix # chmod 644 /etc/postfix/FOO-cert.pem /etc/postfix/cacert.pem # chmod 400 /etc/postfix/FOO-key.pem
以下の行を /etc/postfix/main.cf に追加して、Postfixを 設定します。
smtp_tls_CAfile = /etc/postfix/cacert.pem smtp_tls_cert_file = /etc/postfix/FOO-cert.pem smtp_tls_key_file = /etc/postfix/FOO-key.pem smtp_tls_session_cache_database = btree:/var/run/smtp_tls_session_cache smtp_use_tls = yes smtpd_tls_CAfile = /etc/postfix/cacert.pem smtpd_tls_cert_file = /etc/postfix/FOO-cert.pem smtpd_tls_key_file = /etc/postfix/FOO-key.pem smtpd_tls_received_header = yes smtpd_tls_session_cache_database = btree:/var/run/smtpd_tls_session_cache smtpd_use_tls = yes tls_random_source = dev:/dev/urandom
問題を報告する際には、詳細に報告を書いてください。可能であれば、パッチも 歓迎します。
できる限り、以下を区別してください:
Postfix version 2.2 TLSサポートはLutz JänickeによるPostfix/TLS パッチを基にしていますが、細かい点でいくつか異なります。
main.cf: TLSセッションキャッシュデータベースには "sdbm" の代わりに "btree" を指定します。
今はTLSセッションキャッシュデータベースは tlsmgr(8) プロセスからのみアクセスされるため、もう並列問題はありません。Postfixには sdbmクライアントがありますが、sdbmライブラリ(1000行のコード)はPostfixに 含まれていません。
TLSセッションキャッシュは数キロバイト以上のオブジェクトを保存できて 連続操作をサポートしている、どんなデータベースでも使えます。ほとんどの場合、 btreeデータベースが適切でしょう。
注意: dbmデータベースは使えません。TLSセッションオブジェクトは大きすぎます。
master.cf: tlsmgr サービスの種類として "fifo" ではなく "unix" を指定 します。
今は smtp(8) および smtpd(8) プロセスは tlsmgr(8) 擬似乱数生成 (PRNG) プールにアクセスしたりTLSセッションキャッシュデータベースにアクセスするのに クライアント-サーバプロトコルを使います。そのようなプロトコルを fifo で 使うことはできません。
smtp_tls_per_site: サイトごとの MUST_NOPEERMATCH ポリシーはグローバルな "smtp_tls_enforce_peername = yes" 設定を上書きできません。
smtp_tls_per_site: (ホスト名とnext-hop配送先) に対する (NONE + MAY) 検索結果の組み合わせは、 main.cf 設定が異なると直感的ではない結果となります。 "smtp_tls_enforce_peername = no" でTLSが有効となりますが、 "smtp_enforce_tls = yes" かつ "smtp_tls_enforce_peername = yes" の場合にはTLSは無効となります。
smtp_tls_per_site 制限は Postfix 2.2サポートサイクルの最後で削除されました。