送信ドメイン認証技術のうちのひとつ、DKIM を Sendmail/Postfix で使えるようにするための作業メモ。DomainKeys は今後なくなることが確定しているので、新規にインストールするのは推奨しない。yahoo とか gmail とか、DomainKeys を使っているところがないわけじゃないけど、そんなことは忘れましょう。とはいえ、自分が署名するのではなく、よそからの DomainKeys 署名つきメールを検証できる環境があるのは悪いことではない。実は最近のバージョンの dkim-milter は dk-milter のライブラリを組み込んで DomainKeys の検証が可能になっているので、dkim-milter に一本化しちゃいましょう。
なお、以下はあくまでインストールして動かすためだけのメモであって、DKIM とはいったい何なのかとか起動オプションだとかなどについては一部の例外を除いて説明しない。そのあたりは必ず自分で調べて理解してください。
(2007/7/19 追記)
今回は DomainKeys verify もできる DKIM milter を作るので、dkim-milter だけでなく、dk-milter のソースも取得しておく。もちろん、dk-milter を単体でコンパイル、インストールすれば DomainKeys 署名も可能だが、上述のとおり廃止されるべきものなので対応はしない。
まず、libmilter が存在しているか確認する。Linux では sendmail がインストールされていても libmilter は別パッケージだったり、postfix と sendmail が排他になっていて postfix と libmilter が共存できない、なんてことがあるので注意。このあたりは自分で解決してくだされ。
では、ソースを展開する。
% tar xvfz dkim-milter-0.5.2.tar.gz % tar xvfz dk-milter-0.4.1.tar.gz
中に入ってるドキュメントを熟読してください。少なくとも sendmail で使うかぎりにおいては、ドキュメントさえ読んでおけば、以下の説明はいらないはず。
dk-milter に含まれる DomainKeys 処理のライブラリを dkim-milter のソースの下にもっていく。
% cd dkim-milter-0.5.2 % ln -s ../dk-milter-0.4.1/libdk .
で、DKIM で DomainKeys を扱えるように設定してやる。
--- dkim-filter/Makefile.m4.orig Fri Jun 9 16:01:19 2006 +++ dkim-filter/Makefile.m4 Thu Sep 28 21:15:16 2006 @@ -17,8 +17,8 @@ dnl If you also want to verify messages signed with DomainKeys, dnl enable these lines as well as the corresponding FFR line below. -dnl bldPUSH_SMLIB(`dk') -dnl APPENDDEF(`confINCDIRS', `-I../libdk/ ') +bldPUSH_SMLIB(`dk') +APPENDDEF(`confINCDIRS', `-I../libdk/ ') bldPUSH_SMLIB(`sm') @@ -44,7 +44,7 @@ dnl APPENDDEF(`confENVDEF', `-D_FFR_SELECT_SIGN_HEADERS ') dnl APPENDDEF(`confENVDEF', `-D_FFR_SET_DNS_CALLBACK ') dnl APPENDDEF(`confENVDEF', `-D_FFR_SET_REPLY ') -dnl APPENDDEF(`confENVDEF', `-D_FFR_VERIFY_DOMAINKEYS ') +APPENDDEF(`confENVDEF', `-D_FFR_VERIFY_DOMAINKEYS ') dnl If you do POP before SMTP: dnl APPENDDEF(`confENVDEF', `-DPOPAUTH ')
FFR というのは for future release のことで、将来は正式サポートになるだろう機能を先取りして使うよ、といった意味。
さらに、インストール環境にあわせて devtools/Site/site.config.m4 もてきとーに書く。うちの場合はこんな感じ。詳細はドキュメントや example を参照。
define(`confEBINDIR',`/usr/local/libexec') define(`confMANROOT',`/usr/local/man/man') define(`confMANROOTMAN',`/usr/local/man/man') define(`confUBINDIR',`/usr/local/libexec') define(`confLIBDIR',`/usr/local/lib')
コンパイルしてインストール。
% ./Build % sudo ./Build install
べつに make; sudo make install でもかまわんけど。
root で起動しちゃうのはよろしくないので、専用のユーザを作ってそいつで動かす。なんでもいいんだけど、milter というユーザを作って、既存の mail というグループに所属させておいた。こんなかんじ。
% id milter uid=400(milter) gid=6(mail) groups=6(mail)
署名と検証に使う鍵ペアを作る。セレクタごとに鍵を用意するのだが、セレクタって何、ということについてはほかで調べてくれ。ここでは hoge というセレクタにする。
# dkim-filter/gentxt.csh hoge hoge._domainkey IN TXT "v=DKIM1; k=rsa; t=y; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChx....."
gentxt.csh を実行すると DNS に登録すべきレコードの例が出力されるので、問題なければそのまま DNS に登録する。意味についてはここでは触れないので自分で調べること。また、これとは別に、_policy._domainkey という SSP (site signing policy) 用のレコードも登録しておくとよい。これの意味についてもここでは書かない。
_policy._domainkey IN TXT "t=y; o=~"
登録したレコードが DNS に反映されていることを確認する。
% dig txt hoge._domainkey.example.org % dig txt _policy._domainkey.example.org
また、これとは別に、というかこっちが本体だけど、hoge.public、hoge.private という鍵ペアが作成される。hoge.public は公開鍵で、中身はさっき TXT レコードに登録したものと同じ。hoge.private は署名に使う秘密鍵。
作られた鍵は milter から読めるところに置いておく。秘密鍵は秘密なので必要最小限のパーミッションに、公開鍵は DNS を通じて世界中から見えるようにするものなので、改竄されなければどうでもよし、というか、DNS に登録したらもう使わない。
# mv hoge.public hoge.private /etc/mail # chown root:mail /etc/mail/hoge.private # chmod 440 /etc/mail/hoge.private
pid ファイルや MTA と通信するためのソケットを置いておく場所を作成する。
# mkdir /var/run/milter # chown milter:mail /var/run/milter
設定ファイルを作ることもできるが、ほとんどの設定は起動時の引数で指定できるので、今回は用意しない。
# su milter -c "umask 117; /usr/local/libexec/dkim-filter -P /var/run/milter/dkim-filter.pid -p local:/var/run/milter/dkim -l -d example.org -s hoge -k /etc/mail/hoge.private"
su milter として、milter ユーザの権限で起動する。実は -u というオプションでユーザを指定することもできるのだが、このオプションは setuid() だけして setgid() はしないので、milter の所属するグループである mail の権限にならない。秘密鍵のパーミッションを上のように root:mail の 440 に していると milter が秘密鍵を読めなくなってしまうので、-u は使わず、su milter としてグループも変更させる。
umask を設定するのも、MTA とやりとりするためのソケットファイルを mail グループの権限で読み書きできるようにするため。unix ドメインソケットではなく TCP で通信させる場合はこれは不要。
sendmail ならばどうせ root で動くので、このあたりのパーミッションまわりのことはあまり気にしなくていいのだが、postfix で動かす場合は注意しておくこと。
これ以外の起動引数の意味はここではいちいち説明しないのでドキュメントを参照のこと。
ちゃんと起動すればこんな感じで syslog に記録される。
Sep 28 21:59:52 tomo dkim-filter[13354]: Sendmail DKIM Filter v0.5.2 starting (args: 以下起動時の引数につき省略)
まず milter が使えるようコンパイルされているか確認する。
% sendmail -bt -d0.1 < /dev/null Version 8.13.6 Compiled with: DNSMAP LOG MAP_REGEX MATCHGECOS MILTER MIME7TO8 MIME8TO7 NAMED_BIND NETINET NETINET6 NETUNIX NEWDB NIS PIPELINING SCANF STARTTLS TCPWRAPPERS USERDB XDEBUG (以下略)
Compiled with: の中に MILTER が含まれているかどうか確認する。なければバイナリを作りなおし。
.mc に以下を追加して .cf を作りなおす。S= で指定するところは milter 起動時の -p で指定した値と一致させる。そのほかの設定の意味については cf/README と doc/op/op.me を参照のこと。
INPUT_MAIL_FILTER(`dkim-filter', `S=local:/var/run/milter/dkim, F=T')
これだけなのであまり悩む必要はない。
なにはなくとも、ドキュメント読んどけ。
milter が使えるバージョンかどうか確認する。
% postconf mail_version mail_version = 2.3.3
2.3 以上なら OK。2.2 以下ならばバージョンを上げないと使えない。バージョンに問題なければ以下を main.cf に追加する。
smtpd_milters = unix:/var/run/milter/dkim non_smtpd_milters = unix:/var/run/milter/dkim
見ればわかるとおり、SMTP なメールと非 SMTP なメールそれぞれに対する設定。前者は外から来るメールの検証および、ローカルユーザからの署名用。後者は非 smtp な内部からのメールを署名するためのもの。
もうひとつ、milter とのやりとりを TCP ではなく unix ドメインソケットを使う場合は、ソケットに postfix の権限で読み書きできるか確認しておく。具体的には、上記のように milter を起動した場合、ソケットファイルは milter:mail の 660 というパーミッションになっているはずなので、postfix ユーザを mail グループに所属させておかないと milter と通信できない(もちろん postfix グループにも所属させる)。なお、ソケットのパス指定は milter 起動時の -p で指定したものと一致させるのだが、書式が postfix と milter とで異なるので注意。
sendmail.net に検証用のアドレスがあって、そこにメールを送ると署名が正しいかチェックして結果を返送してくれる。また、その返送メールは DomainKeys、DKIM で署名されているので、こちらがそれを正しく検証できるかを確認する。
% echo test | mail -s sa-test_at_sendmail.net # _at_ を @ に変えてね
sendmail の場合は、sm-msp が sm-mta にリレーし、sm-mta が署名して sendmail.net に送る。postfix の場合は non_smtpd_milters の設定により署名される。postfix の場合は smtpd_milters の方の設定も正しいかどうか確認するため、mail コマンドではなく SMTP 接続による送信も確認しておいた方がよい。
しばし待つとメールが返ってくる。確認すべき点は以下。
こちらからのメールに正しく DKIM 署名が付加されていて、sendmail.net での検証に pass したか。
Authentication System: DomainKeys Identified Mail Result: DKIM signature confirmed GOOD Authentication System: Domain Keys Result: (no result present)
DomainKeys は署名してないので結果なしが正しい。DKIM だけ GOOD になればよい。
あちらから届いたメールに付加されていた DKIM、DomainKyes 署名をこちらでうまく検証できているか。
Authentication-Results: example.org from=sa-test_at_sendmail.net; domainkeys=pass (testing) Authentication-Results: example.org header.From=sa-test_at_sendmail.net; dkim=pass (1024-bit key/testing)
ちなみに、このテスト用メールアドレスは SPF/SenderID のチェックもやってくれるので、可能ならば確認しておくべし。
ちなみに、似たような送信者ドメイン認証の検証サービスは check-auth_at_verifier.port25.com でもやってるんだけど、SPF/SenderID/DomainKeys だけで DKIM は未対応で、しかも返送メールは DK/DKIM のどちらの署名もないので、今回のような場合では使えない。っていうか、DomainKeys はもうダメだっつーのに。
上の例では milter をコマンドラインから起動してるけど、OS 再起動時にちゃんと milter も上がってくるように起動スクリプトを作っておいてね。