http://www.sendmail.org/m4/starttls.html
STARTTLS
この文書では、X.509 証明書を cert という略称で表記しています。また、DN
は cert の識別名 (distinguished name) を、CA は認証局 (certification
authority) を指します。
sendmail で STARTTLS を使用するには、最低限以下の変数を設定する必要が
あります (記載しているファイル名やパスは単なる例です)。
define(`confCACERT_PATH', `/etc/mail/certs/')
define(`confCACERT', `/etc/mail/certs/CA.cert.pem')
define(`confSERVER_CERT', `/etc/mail/certs/my.cert.pem')
define(`confSERVER_KEY', `/etc/mail/certs/my.key.pem')
コンパイルフラグ HASURANDOM を持っていないシステムでは
(sendmail/README ファイルを参照してください)、confRAND_FILE も設定する
必要があります。
これらのオプションについての詳細は、doc/op/op.{me,ps} の特に
``Certificates for STARTTLS'' と ``PRNG for STARTTLS'' の章を参照して
ください。
STARTTLS に関連するマクロを以下に示します。
${cert_issuer} CA の DN (cert の発行者)
${cert_subject} cert の DN (cert subject と呼ばれます)
${tls_version} コネクションで使用される TLS/SSL のバージョン
例: TLSv1, SSLv3, SSLv2
${cipher} コネクションで使用される暗号化方式
例: EDH-DSS-DES-CBC3-SHA, EDH-RSA-DES-CBC-SHA, DES-CBC-MD5,
DES-CBC3-SHA
${cipher_bits} コネクションで使用される共通鍵暗号の鍵長 (ビット数)
${verify} 提示された cert の検証結果
取りうる値は以下のとおり。
OK 正常に確証された
NO cert が提示されなかった
FAIL cert は提示されたが確証できなかった
例: CA への署名が失われていた
NONE STARTTLS が実行されていない
TEMP 一時的なエラーが発生した
PROTOCOL 何らかのプロトコルエラーが発生した
SOFTWARE STARTTLS ハンドシェイクに失敗した
${server_name} 現在の接続先 SMTP サーバ名
${server_addr} 現在の接続先 SMTP サーバのアドレス
中継
SMTP STARTTLS を使用することで、自分自身を正しく認証させた配送元に対し
て中継を許可するという設定が可能になります。この設定は RelayAuth とい
うルールセットで行ないます。
cert の検証に失敗した場合
(${verify} != OK)、中継は通常のルールに従います。
検証に成功した場合、
CERTISSUER タグを使用して、発行元の DN をアクセスマップから検索します。
検索結果が RELAY であれば中継が許可されます。SUBJECT であれば、次に
CERTSUBJECT タグを使用して cert subject の DN をアクセスマップから検索
します。検索結果が RELAY であれば、中継が許可されます。
もう少し柔軟 (もしくは複雑) にするために、${cert_issuer} と
${cert_subject} の値は、m4 変数の _CERT_REGEX_ISSUER_ と
_CERT_REGEX_SUBJECT_ で定義した正規表現で、それぞれ付加的に変更するこ
とができます。
ルールセットとマップ検索において問題を避けるため、これら
のマクロは次のように書き直されます。
非表示 (non-printable) 文字と
'<',
'>', '(', ')', '"', '+'
は、'+' に続けてその文字を表す 16 進数に置き換
えられます。たとえば、
/C=US/ST=California/O=endmail.org/OU=private/CN=Darth Mail (Cert)/Email=
darth+cert@endmail.org
をエンコードした結果は、
/C=US/ST=California/O=endmail.org/OU=private/CN=
Darth+20Mail+20+28Cert+29/Email=darth+2Bcert@endmail.org
となります (読みやすくするため改行を入れてあります)。
もちろん、認証可能な cert が提示された場合、誰に対しても中継を許可する
というような簡単なルールセットを書くことも可能です。
LOCAL_RULESETS
SLocal_check_rcpt
R$* $: $&{verify}
ROK $# OK
コネクションの許可
ルールセット tls_server と tls_client は、SMTP コネクションを受け付け
るかどうか (あるいは処理を続けるかどうか) を決定するために使用します。
STARTTLS コマンドが発行された後に sendmail がクライアントとして動作す
る際に、tls_server が呼び出されます。
パラメータは ${verify} の値です。
sendmail がサーバとして動作する際、STARTTLS コマンドが発行された後、あ
るいは check_mail ルールにより tls_client が呼び出されます。パラメータ
は ${verify} の値と、それぞれ STARTTLS、MAIL となります。
どちらのルールセットも同じ動作をします。アクセスマップを使用しない場合、
${verify} の値が SOFTWARE でない限り、コネクションは受け付けられます。
${verify} が SOFTWARE の場合は、コネクションは必ず中止されます。アクセ
スマップを使用する場合、TLS_Srv (または TLS_Clt) タグを使用したアクセ
スマップからの ${client_name} (${server_name}) の検索が LookUpDomain
ルールセットにおいて行なわれます。エントリが見つからなければ、
${client_addr} (${server_addr}) がアクセスマップから (同じタグで
LookUpAddr ルールセットにおいて) 検索されます。それでもエントリが見つ
からなければ、そのタグがアクセスマップ (: を後ろに含む) から検索されま
す。
その検索結果は tls_connection ルールセットの呼び出しに使用され、そ
れにより現在の TLS コネクションの実際のパラメータ、特に ${verify} と
${cipher_bits} に対するアクセスマップ内の RHS で指定された要求事項が確
認されます。アクセスマップで許される RHS は次のとおりです。
VERIFY 検証が成功しなければならない
VERIFY:bits 検証が成功しなければならず、${cipher_bits} は bits で
指定されたビット数以上でなければならない
ENCR:bits ${cipher_bits} は bits で指定されたビット数以上でなけ
ればならない
一時的、あるいは恒久的なエラーを選択するのに、オプションとして RHS の
前に TEMP+ や PERM+ を置くことができます。.cf ファイルを生成する際にマ
クロ TLS_PERM_ERR が設定されていなければ、デフォルトで一時的なエラーを
意味するコード (403 4.7.0) となります。
一定の暗号レベルが必要な場合、このレベルは SASL アルゴリズムのセキュリ
ティレイヤ、たとえば DIGEST-MD5 で提供されても構いません。
例:
TLS_Srv:secure.example.com ENCR:112
TLS_Clt:laptop.example.com PERM+VERIFY:112
この場合、secure.example.com に送るメールは暗号化されたコネクションだ
けを使用します。laptop.example.com ドメイン内のホストからのメールは、
それらのホストが認証された場合にのみ受け付けます。
注意: あるサーバに送信するメールを暗号化したものに限るために、
TLS_Srv:secure.domain ENCR:112
としても、そのドメインに送られるメールが必ずしも暗号化されていることを
意味しません。たとえば、
secure.domain. IN MX 10 mail.secure.domain.
secure.domain. IN MX 50 mail.other.domain.
のように、そのドメインが複数の MX サーバを持つ場合、user@secure.domain
宛てのメールは mail.other.domain に暗号化されていなくても送られること
があります。
Received: ヘッダ
Received: ヘッダは、STARTTLS が使用されたかどうかを示します。このヘッ
ダには以下のような特別な行が含まれます。
(using ${tls_version} with cipher ${cipher} (${cipher_bits} bits) verified ${verify})
|