aSPFやSender IDをみてくれるmilter (sendmail由来のmail filterの仕組み)を、IIJのひとたちが実装したものが今週から公開されている。
http://sourceforge.net/projects/enma
でPerlで書かれたものはあったけど高負荷時にどうなんだとか、あるいは大手各社は自分で実装してそうだけど外には出せないんだろうなあと思っていたので、このようにCでゴリっと書かれたものが表にでてくるのはありがたい。開発陣も山本和彦さんとかそうそうたるメンツのようだ。
きょう土曜は中野で LL Future があったようで、しかしすっかり行くのを忘れてしまい、天気もわるくなってきてそのままずっと家にいたりして、じゃあenmaを試してみるかと思ったら若干いじる必要があり、ついでなのでDebian GNU/Linuxのパッケージにしてみた。debsignもしてないdebですがよければどうぞ。
https://mrmt.github.io/assets/blog/enma_1.0.0-1_i386.deb
md5sum bd68b60b5112c4f9a53ac50a0218e535
postfixで使う場合は、/etc/enma.confのmilter.postfixをtrueに変えて、/etc/postfix/main.cfに以下みたいに足してやってください。
smtpd_milters = inet:127.0.0.1:10025
glibcマター
enmaはlibbind の __res_ndestroy()を呼んでいるんだけど、近年の glibc ではlibresolvでこのへんを吸収しちゃってるのと(ただ Debian GNU/Linux特有の事情がさらにあって後述)、__res_ndestroy()がいつからかobsoleteになってて__res_nclose()を呼ぶようにしないといけない。
ただここは意図して__res_ndestroy()のほうを呼んでるようだ。enma-1.0.0/libsidf/src/dnsresolv.c参照:
void DnsResolver_free(DnsResolver *self){ assert(NULL != self); res_ndestroy(&self->resolver); /* * glibc-2.4.0 以降ならば * res_nclose(&self->resolver); * とすることで libresolv でも対応可能. * glibc-2.3.x にも res_nclose() は存在するが, * マルチスレッド環境下ではメモリリークを引き起こす. */ free(self); } // end function : DnsResolver_free
このへん、autoconf/automake レベルできれいに切り分けて upstream にパッチ出したいところだがとりあえず。
ちなみにDebian GNU/Linuxだと、bind 9.x系はライブラリの名前もlibbind9とかですね。
Debian GNU/Linuxマター
daemonは/usr/binじゃなくて/usr/sbinに入れましょうね、はいいとして、libresolvに入ってるns_initparse()とかがどうにもリンクできねー。
なんでだよ、と調べてみると、なんかDebian GNU/Linuxのglibcパッケージ特有の問題みたい。
Re: why debian doesn't allow calling ns_initparse in shared lib?
#291609 - libc6-dev: Missing (not exported) funcions in libresolv.so - Debian Bug report logs
- libresolvでもそのへんはinternal functionだからね、ABIとかAPIも保証できんからあえてexportしてないんだよ。
- はぁ? ns_initparse()なんて十年前からDNS and BINDに載ってますが何か?
という愉快な会話がbugs.debian.orgで1年前にされたままの状態で、識者もちょっとつかまらず。
しょうがないので LDFLAGSに/usr/lib/libresolv.aをベタに足すというナニなことをするはめに。あまり納得できる感じではないし、Debian specificすぎるのでこれもupstreamにパッチ投げるには躊躇する話。
postfixと組み合わせて動かすと、incoming mailのヘッダに以下のように評価結果が足されていきます。
Authentication-Results: localhost; spf=pass smtp.mailfrom=do_not_reply@apple.com; senderid=pass header.From=do_not_reply@apple.com Authentication-Results: localhost; spf=pass smtp.mailfrom=morimoto@gmail.com; senderid=pass header.Sender=morimoto@gmail.com Authentication-Results: localhost; spf=none smtp.mailfrom=dfgt@vengeur.net; senderid=none header.From=dfgt@vengeur.net
あとは評価したメールを具体的にどうすんの、って話ですね。
こういうのをいろいろ実験するには、pure perlなsmtpdであるqpsmtpdも面白いですね。僕もpostfixのincoming smtpハンドリングのとこをqpsmtpdにして半年ぐらい遊んでました。ただ本気のトラフィックをどんぐらい捌けるかはどうなんでしょうね。