PostfixのTLS実装ってSNI対応してないのね…

追記あり、解決したんで最後まで読んでね。


最近いくつかのドメインSSLサーバ証明書を取ったので折角なのでPostfixにも設定してみようと思ったのが始まりで、改めて TLS_README とかを見ながらマルチホスト名のSSL設定方法を探してみたんだがどうにも見つからないぞ?

通常のTLS利用次に行う smtpd_tls_cert_filesmtpd_tls_key_file の設定項目に対して、smtpd_tls_key_file_mapssmtpd_tls_key_file_mapsとかがあるんじゃないかと思ってたんだがどうにも見当たらない。smtp_tls_per_site とかsmtp_tls_policy_mapsとかsmtp_tls_fingerprint_cert_matchとか何かそれっぽい名前の設定項目も見つけたが、どうやらこれらは接続先の証明書の妥当性チェックの設定をホスト名毎に行うとかの、SNI(Server Name Identification)とは全く別の話に関するもののようだ…。

2年前の議論(この記事を書いた2012年から見て、だから2010年な…)

ひたすら情報が見つからない中、それでもPostfix程メジャーなプロダクトがSNI出来ないわけ無いよなーなんて思いながら頑張ってググってたら以下のMLのスレッドに行き着いた。
http://tech.groups.yahoo.com/group/postfix-users/message/266148?threaded=1

話の流れ的は以下のような感じだ。

  • 質問者: Postfixドメイン毎に複数証明書を設定するにはどうしたらよいの?
  • Wietse Venema: つ「Hint: SMTP is not HTTP」*1
  • Victor Duchovni: OpenSSL 1.0だとSNIが使えるから実装してみようかと思ったんだけど、まだ多くの人が0.9.xだし優先度低いわ。クライアントもSNIに対応してるのが殆ど無いしね。
  • ドメイン毎にIP分けて1IP1証明書でやればいいんじゃね?*2
  • Victor Duchovni: やっぱまだクライアントの対応少ないしSNIが普及したらでいいから今は優先度高くないよ。他のSMTPサーバでもSNI対応してるの知らないし。

とこんな感じだと思う(超意訳)。ちなみにVictor DuchovniとWietse VenemaはPostfixTLS実装をしてる人達らしい。(追記)というかWietse VenemaさんってPostfixの生みの親な人なんですね。
これらの発言は2年前の2010年6月頃の話なので、まぁ当時は世間の環境的にまだSNI実装が進まなくても仕方がなくなったかもしれないね。で、これ以降は現在まで特にPostfixのSNI対応に関する議論は起こってないみたいだ。
でも、そろそろいいんじゃないかな?ThunderbirdiPhoneやその他色んなMUAが最近は当たり前のようにSNI使えるようになってるみたいだし。サーバアプリもWEBを中心にその他のプロトコルでもSNI対応してるものが増えてきたしさ。
今改めて同じポストをしたら話進むんじゃないかなー、頑張って英語書いてみようかな?

諦めた

そんな訳でTLS周りの実装してる人達が否定してるのでSNI設定があるんじゃ?という見逃しの心配はしなくてよさそうで、今日は安心して諦められる。
各ユーザにはCNが違う証明書を例外としてクライアントに保存してもらうか、証明書のCNのホスト名でアクセスしてもらうかっていうありきたりの対応をしてもらうことにするか。WEBと比べたら需要も低いしいいや。

追記 2014/08/05 絶望…?

前回調査した時から2年半、そろそろ何か進捗あったかな?と思って調べてみたら…なんと衝撃の結末が!?

There are no plans to implement SNI in the Postfix SMTP server.

最新の2.11.1のTLS_READMEに「サポート予定ねーからww」って追記されとるww バージョン2.10.3にはこの記述はなくて、2.11.0からコレが追記されてるな。ファイルのタイムスタンプは2014-01-07。

追記 2015/02/23 解決してた!

TLSのSNI対応しねーよ宣言を見てグンニャリしてたんだが、実は2.10でProxy Protocolに対応してるからHAProxy噛ませばSNI対応出来そう。だからこれ使えよってことでSNI対応やめたのかもな。...出来た!

ちなみにProxy Protocolって何ぞ?てとこだが、これは「TCPプロキシを単純に行った際にリモートのIPやPORTがプロキシ先のアプリで知るすべが無い」という問題を解決するもので、TCPのバケツリレーをする際に最初の1行で接続情報を付けて裏に教えてやるという仕組みです。これによってプロキシ先のPostfixで接続元のIPをチェックすることが出来るようになり、Postfix自身が直接LISTENした場合と同様に各種処理が行えるようになるというものです。

設定的には以下をmain.cfに追加してやるとProxy ProtocolモードでLISTENするようになるというものです。

smtpd_upstream_proxy_protocol = haproxy

これを有効にした上で待ち受けポートを 25→10025 とか 587→10587 とかに変えて、25や587はhaproxyでSTARTTLSしたときにSNI使って復数証明書が切り替えれる感じでLISTENした上でlocalにプロキシしてやればOK。この場合Postfixの直ポートは外部からはアクセス拒否してhaproxyからのみ受け付けるようにすべき。以上!

*1:多分SMTPにはHTTPのHostヘッダみたいなの無いしプギャー、みたいなことを言ってるんだろうけど、SSL/TLSに限っては暗号化のハンドシェイクの最初にクライアントがCLIENT HELLOでホスト名を教えてくれる決め事が出来たのでホスト名が分からないという問題はなくなった筈。RFC3546

*2:これはHTTPのSSLの時もよくある会話だったがSNIという仕組みが出来た今はそっちを使いたいんだよぉ。ていうかいつもIP一杯あるわけじゃないしさ。