どさにっき 3D 〜2011年11月中旬〜

by やまや
<< = >>

2011年11月11日(金)

RRSIG の有効期間

_ fbi.gov が DNSSEC fail してるよー、という話が聞こえてきたんだけど、うちの環境では ad フラグが立ったまま。dig の出力をよく見ると、うん、たしかに RRSIG の有効期間が切れてるな。なんで検証できちゃってるの?

_ …unbound の小さな親切だったみたい。時刻のズレをある程度許容してるので、一定の範囲内であれば検証失敗にならないよ、と。へー。でもこういうのって署名する側であらかじめ余裕を持った範囲で期間を設定しておくものなんで、それを検証側でさらに緩めてしまうのもどうかと思うなぁ。

_ unbound.conf(5) を見ると、このへんのことは以下の値をいじることで制御できるみたい。夏時間の時差を許容するために1時間はおっけー、って、UTC なのになんで夏時間が?

   val-sig-skew-min: <seconds>
          Minimum  number  of  seconds of clock skew to apply to validated
          signatures.  A value of 10% of the signature  lifetime  (expira-
          tion  -  inception) is used, capped by this setting.  Default is
          3600 (1 hour) which allows  for  daylight  savings  differences.
          Lower  this value for more strict checking of short lived signa-
          tures.
   val-sig-skew-max: <seconds>
          Maximum number of seconds of clock skew to  apply  to  validated
          signatures.   A  value of 10% of the signature lifetime (expira-
          tion - inception) is used, capped by this setting.   Default is
          86400  (24  hours) which allows for timezone setting problems in
          stable domains.  Setting both min and max very low disables the
          clock skew allowances.  Setting both min and max very high makes
          the validator check the signature timestamps less strictly.

_ で、fbi.gov の RRSIG の示す期間を見るに、コケるようになってから現時点でもうすぐ24時間で、unbound のデフォ設定でも救済できない時刻が近付いてるんだけど、再署名しないんかね。っていうか、中の人は気付いてないんかね。困る人がちっともいないってのは、やっぱり普及してないんだなぁ。

_ そして有効期間から24時間経過して、無事 SERVFAIL するようになった。わかりにくい。


2011年11月13日(日)

無題

_ 龍王峡〜川治温泉。朝の早いうちは太陽が顔を出してたんだけど、行動開始するころには薄曇りに。うーん。天気をおいておいても、今年の紅葉はいまいち色づきがよくない。かなり残念なことに。
~ ~


2011年11月15日(火)

やっぱり松戸は mad だった

_ うわはははいいぞもっとやれ。それにしてもなぜ松戸や新松戸ではなく馬橋なんてマイナーな駅なのか。最寄り駅なんで毎日お世話になっとるんですが:-)。


2011年11月19日(土)

メールの暗号化

_ スティーグ・ラーソンの『 ミレニアム』3部作の 第2部まで読了。最後が文庫落ちするのは来月か。わざと悪意的に内容を書くと、現実が見えてない理想主義者のジャーナリストと著者の厨二病成分の結晶のスーパーヒロインが力をあわせずてんでばらばらに難事件を解決するお話。いや、おもしろいよ。

_ で、この小説の中でメールを PGP で暗号化して送る場面が何度か出てくる。ああ、そうだなぁ。メールってプライバシーに関する情報のやりとりにも使われるものなのに、暗号化ってぜんぜん普及してないよなぁ。規格自体はだいぶ古くからあるのにちっとも使われてない。作中で使われてる PGP やそれから S/MIME なんかも、サーバは一切何もしてくれず、対応アプリのインストールから設定から鍵/証明書の調達から何から何までユーザがぜんぶやらなきゃいけないってのがハードルが高い。危険な経路を通る場合でも end to end で暗号化されるというメリットは非常に大きいんだけど、これをすべてユーザが自分でやらなきゃいけない、というのではそりゃ普及しないよ。

_ ということで、ユーザが自力で PGP や S/MIME によるメッセージ単位の暗号化をするだけでなく、サーバによる SMTP 自体の暗号化をもっと普及させないといかんよなぁ、と思い至った。プライバシーを含む情報のやりとりに HTTPS や SSH があたりまえになってるように、SMTP でもできるだけ STARTTLS を使うようにせんといかんよ。メールはバケツリレーが基本なので、自分のところだけ TLS で暗号化したところで経路のすべてを暗号で守れるわけじゃないんだけど、だからといってそれを言い訳にみんな何もしなかったらいつまでたっても平文のまま。商用サービスでは submission (や POP3)の TLS 化は採用してるところはそこそこあるけど、これは MUA からの送受信が暗号化されるだけ。submission が TLS 対応していても、その後の MTA 間の中継は平文のままおこなってるサービスがほとんどでありがたみが薄い。submission だけじゃなく MX 配送まで TLS 化に対応してるのって、大手では gmail ぐらいじゃないかな。この状況はよろしくない。少しずつ普及させていかないと。

_ 先づ隗より始めよ。自分のところを TLS に対応させてみる。続く。

SMTP 配送の TLS 化

_ ということで、サーバ間のメール中継を TLS に対応させてみる。まず、お手軽にこちらからよそに送るメールを暗号化できるようにする。

_ postfix での設定。たったこれだけ。

smtp_tls_security_level = may
smtp_tls_CAfile = /etc/ssl/cert.pem
smtp_tls_loglevel = 1

_ この設定は、相手サーバが TLS 非対応だったり、対応してるけどオレオレ証明書を使ってるようなときでも気にせず送ってしまうという緩いもの。smtp_tls_security_level = verify にすると、証明書が本物かどうか検証して有効な場合のみ TLS で送るようになるけど、TLS 非対応の大多数サイトに送れなくなってしまって現実的ではない。その他いくつか選択肢はあるけど、いずれも TLS が一般的でない現状では不特定のサイトに送るのには適切でないので、may にしておくのがよろしいかと。TLS をやってるホストにしか中継しないことがわかってるようなサーバならもっと厳しくてもいいんだけどね。

_ オレオレ証明書でも気にせず送っていいよ、という設定なので、証明書がホンモノかどうか検証する意義というのはあんまりないんだけど、それでもあとからログを見たときにどっちだったか確認できるにこしたことはないので、そのへんを設定しておく。smtp_tls_CAfile はルート CA のリストで、自前で調達する。FreeBSD だと ports/security/ca_root_nss をインストールすると /usr/local/share/certs/ca-root-nss.crt に入る。RHEL や CentOS だと /etc/pki/tls/cert.pem にあるが、こいつには WebTrust for CAの認定を受けていない RedHat のオレオレ CA の証明書がこっそり紛れこんでるのでそのへん注意。あるいは、IE とかのブラウザに入ってるルート CA の証明書をエクスポートして(そのままだとたぶん PKCS12 形式なので PEM に変換して)使ってもよい。いずれにせよ重要なのは、かならず信頼できる経路から入手したものを使うということ。怪しい CA 証明書がこっそり含まれてたりするとよろしくない。もっとも、RHEL のように正規に入手したものに妙なものが含まれてることもあるけど。

_ で、その検証結果はデフォではログに残らない(そもそも TLS で送ったかどうかすら記録されない)ので、ログレベルを上げる。smtp_tls_loglevel = 1 だとこんなログが記録されるようになる。

Nov 19 18:01:31 <mail.info> eel postfix/smtp[87764]: setting up TLS connection to ASPMX.L.GOOGLE.COM[74.125.53.26]:25
Nov 19 18:01:31 <mail.info> eel postfix/smtp[87764]: Trusted TLS connection established to ASPMX.L.GOOGLE.COM[74.125.53.26]:25: TLSv1 with cipher RC4-SHA (128/128 bits)
Trusted TLS connection ... となってるので、ホンモノ証明書を持ってるとこにつないでる。オレオレ証明書を使ってるサーバに送ると Untrusted ... になる。ログレベルをもっと上げるとさらに詳細な情報が記録されるが、ぶっちゃけ詳しすぎてノイズにしかならないのでデバッグ以外ではやめておいた方がよさげ。

_ 以上は SSL の証明書を買わなくても、ただ設定ファイルに追加するだけでできる暗号化なので、ぜひともやっておくべし。現状では TLS で配送できる相手はそんなに多くないんだけど、でもやらないよりはいい。

SMTP 受信の TLS 対応

_ 外に TLS でメールを送れるようになったら、次はよそから届くメールを TLS で受けとれるようにする。こちらはサーバ証明書が必要なので、それを買うためにお金がかかる。オレオレ証明書でもいいんだけど、せっかくならルート CA からチェインがつながった証明書を使いたいよね。

_ ということで、SSL のサーバ証明書をタダで発行してくれるというクレクレ乞食にはたいへんありがたい StartSSL を使わせてもらう。実際の取得手順は略。重要なのは、メールサーバのホスト名を CommonName として取得するということ。foo@example.com というアドレスでやりとりするメールを暗号化したいから example.com で証明書を取得する、というのは間違い。example.com の MX ホスト名で取得する。これを間違えると接続先のホスト名が間違ってるよ、と怒られることになる。もちろん、StartSSL 以外で証明書を買うときも同じ。

_ 証明書の準備ができたところで、設定。まず、 中間証明書を拾ってきて、サーバ証明書とくっつける。

# cat server.crt sub.class1.server.ca.pem > cert.pem
くっつける順番を間違えるとうまく動かないので注意。

_ main.cf に設定追加。

smtpd_tls_security_level = may
smtpd_tls_cert_file = /path/to/cert.pem
smtpd_tls_key_file = /path/to/key.pem
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes

_ STARTTLS を使わない大多数からの接続も受けつけるため、smtpd_tls_security_level = may と緩めの設定にしておく。また、ログと Received ヘッダに TLS まわりの記録を残すための設定もしておく。

_ 設定ができたらテストしてみる。 ルート CA のリストを用意して以下を実行。

> openssl s_client -connect mx.maya.st:25 -starttls smtp -CAfile /etc/ssl/cert.pem
(略)
    Verify return code: 0 (ok)
quit
221 2.0.0 Bye
closed
正しく設定できていれば Verify return code: 0 になる。オレオレ証明書を使っていると、接続自体はできても証明書の検証に失敗して 0 でない結果が返ってくる。

_ gmail からテストメールを送ってみた。こんな感じに。

-- ログ
Nov 19 19:18:25 <mail.info> eel postfix/smtpd[70618]: setting up TLS connection from mail-wy0-f181.google.com[74.125.82.181]
Nov 19 19:18:26 <mail.info> eel postfix/smtpd[70618]: Anonymous TLS connection established from mail-wy0-f181.google.com[74.125.82.181]: TLSv1 with cipher RC4-SHA (128/128 bits)
-- ヘッダ
Received: from mail-wy0-f181.google.com (mail-wy0-f181.google.com [74.125.82.181])
        (using TLSv1 with cipher RC4-SHA (128/128 bits))
        (No client certificate requested)
        by mx.maya.st (Postfix) with ESMTPS id 310D56D41C
        for <y@maya.st>; Sat, 19 Nov 2011 19:18:27 +0900 (JST)
ぶっちゃけ、apache で HTTPS の設定をするよりも設定項目が少なくて楽だと思う。大手のメール屋さんであれば、このぐらいは標準でやってほしいものだよね。証明書を買う費用は増えるけど、全体の運用コストに比べれば微々たるものでしょ。

_ もすこし続く。


2011年11月20日(日)

Submission の TLS 認証

_ つづき。

_ StartSSL でタダの SSL 証明書を 取得したわけなんだけど、実はもらえたのはサーバ証明書だけではない。サーバ証明書を作る前段階としてアカウントを作成するわけなんだけど、その個人証明書もくれるのだ。なんと。StartSSL でいろいろなんかするときのためのユーザ認証用で配ってるんだと思うんだけど、PKI 的に至極まっとうな証明書なので、StartSSL へのログイン以外にもいろいろ使えてしまう。ということで、いろいろ使ってみよう。

_ StartSSL が自分とこの Web サイトのログインに使っているように、個人向けの証明書はユーザ認証に使うことができる。つまり、メール送信時に SMTP AUTH を使わずに TLS クライアント認証で中継を可否を判断していいってことだ。こいつをやるよ。

_ Submission ってのは簡単に言えば SMTP のポートを変えただけのもなので、 SMTP の TLS 化が完了した時点で submission の TLS 化も完了している。が、さらに認証までおこなうとなると、細かい設定が必要になる。

_ まず、サーバ側の設定。main.cf に SMTP で TLS を使う設定をした上でさらに加えて、master.cf にこんな感じで書く。

submission inet n       -       n       -       -       smtpd
    -o smtpd_tls_ask_ccert=yes
    -o smtpd_tls_CAfile=/etc/ssl/cert.pem
    -o smtpd_sasl_auth_enable=yes
    -o smtpd_restriction_classes=
    -o smtpd_client_restrictions=
    -o smtpd_helo_restrictions=
    -o smtpd_sender_restrictions=
    -o smtpd_recipient_restrictions=permit_mynetworks,permit_tls_clientcerts,permit_sasl_authenticated,reject
    -o smtpd_data_restrictions=
    -o receive_override_options=no_header_body_checks
    -o relay_clientcerts = hash:$config_directory/relay_clientcerts
長いけど、大半は TLS とは無関係の submission 用の設定。relay_clientcerts はとりあえず空ファイルを作って postmap しておく。また、これは SMTP AUTH での送信も許可しているので、そちらの設定も別途必要。具体的な方法については触れないので自力でよろしく。わからん場合は -o smtpd_sasl_auth_enable=yes を no に変えると AUTH は使わなくなる。

_ StartSSL に発行してもらった個人証明書がブラウザにインストールされてると思うので、それをエクスポートして、メーラーの方にインポートする。あたりまえだがメーラーの方がクライアント認証に対応してないと意味ないので念のため。さらに、証明書の情報を表示して、フィンガープリントを確認しておく。あるいは、PKCS12 形式でエクスポートしたファイルに対して、

> openssl pkcs12 -in hoge.p12 -out hoge.pem
ってな感じで PEM 形式に変換して、さらに
> openssl x509 -in hoge.pem -fingerprint -md5 -noout
とすることでもフィンガープリントを確認できる。postfix は SHA-1 フィンガープリントは未対応で MD5 しか使えないっぽい。

_ で、このフィンガープリントを relay_clientcerts に書く。.db に変換するので、key - value のペアになってなきゃいかんのだが、必要なのはフィンガープリントだけなので、それに対応する値は適当でよい。左辺はただの16進の羅列でわけわからんので、証明書の CN の欄でもコピペしておくとわかりやすくなってよろしいかと。こんな感じ。

60:1F:45:A4:97:01:B5:B1:06:42:72:D0:03:EE:64:09 CN=y@maya.st/emailAddress=y@maya.st
ほかにオレオレ CA で発行した証明書など必要なだけ列挙したら最後に postmap して .db に変換。

_ メーラー側は、たとえば Thunderbird なら STARTTLS を使って認証なしで設定する。証明書マネージャでクライアント証明書をインストールしてあるので、送信時にこの証明書を使って TLS 接続がおこなわれ、サーバに設定してあるフィンガープリントと一致することが確認され、SMTP AUTH なしでメールの中継が許可されるようになる。

_ ログはこんな感じ。 外から届くときは Anonymous TLS だったけど、今度はクライアント証明書を使っていて送信者の身元を確認できてるのでそのへんの情報がログに記載されている。

Nov 20 00:56:59 <mail.info> eel postfix/smtpd[93826]: setting up TLS connection from ringo.prv.maya.st[192.168.1.16]
Nov 20 00:57:00 <mail.info> eel postfix/smtpd[93826]: ringo.prv.maya.st[192.168.1.16]: Trusted: subject_CN=y@maya.st, issuer=StartCom Class 1 Primary Intermediate Client CA, fingerprint=60:1F:45:A4:97:01:B5:B1:06:42:72:D0:03:EE:64:09
Nov 20 00:57:00 <mail.info> eel postfix/smtpd[93826]: Trusted TLS connection established from ringo.prv.maya.st[192.168.1.16]: TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)
オレオレ CA が発行したクライアント証明書では Untrusted TLS connection とログに出るはず。これは正規の CA が発行したものではないせいで信頼の連鎖を辿れなかったためだけど、フィンガープリントが一致するように偽造するのはかなり困難なのでこの状態でも安全は確保されている(CA を信頼するのではなく、証明書を個別に信頼するような設定にしてあるので)。信頼する CA にオレオレ CA も加えておけば、ちゃんと Trusted TLS になる。オレオレ CA が発行した証明書はフィンガープリントを列挙しなくても全部信用する、という設定にすることも可能だが割愛。

_ Apple Mail では Lion でクライアント認証がサポートされたらしい。Thunderbird では認証なしを選択するけど、Apple Mail では「外部(TLS クライアント証明書)」ってのがメニューにあるのでそれを選択すればいい…んだと思うんだけど、実際やってみてもこちらの証明書を送っている気配がない。キーチェーンアクセスにはちゃんと証明書をつっこんであるんだけどなぁ。どこがおかしいんだろ。ということで、Apple Mail ではうまくできてません。

_ ちなみに、クライアント証明書は InstantSSLでも無料で発行してくれるようだ。ここも 無料サーバ証明書があるけど、期限が90日しかないので使いづらい。

POP/IMAP の TLS 化

_ 同様に、POP/IMAP でも TLS のクライアント認証が可能。…なんだけど、ためしに dovecot のドキュメントを眺めてみたところ、うーん。たしかに クライアント認証は可能っぽいんだけど、これじゃ使えないなぁ。

_ TLS のクライアント認証を使えば STLS 完了時点でユーザ認証が完了してるんだけど、POP/IMAP のプロトコルで規定された認証のやりとりを済ませないとその先に進めない。そのため dovecot ではデタラメなパスワードでも認証をパスできるような オプションを用意している。…が、そうしちゃったら TLS を使わない場合でもでパスワードなしでログインできちゃうよね。TLS クライアント認証以外を一切認めないようにするならそれでもいいんだけど、それはちょっと使いづらいような。TLS のネゴでは認証せず、ふつーに POP/IMAP で認証させた方がよさげな感じ。

_ ということで、使いものにならないと判断して試してない。ドキュメントを読み違えてる可能性もないではないけど。

_ 念のため、クライアント認証を使わない TLS 接続はごくごくあたりまえに可能。dovecot 2.x の場合。1.x は設定パラメータが違う。

ssl = yes
ssl_cert = </path/to/cert.pem
ssl_key = </path/to/key.pem
証明書と鍵のパスを書くだけというお手軽設定。ちょーらくちん。

_ さらにつづく。


<< = >>
やまや