ENMAをDebianで試してみた

SPFSender IDをみてくれるmilter(sendmail由来のmail filterの仕組み)を、IIJのひとたちが実装したものが今週から公開されている。

http://sourceforge.net/projects/enma

Perlで書かれたものはあったけど高負荷時にどうなんだとか、あるいは大手各社は自分で実装してそうだけど外には出せないんだろうなあと思っていたので、このようにCでゴリっと書かれたものが表にでてくるのはありがたい。開発陣も山本和彦さんとかそうそうたるメンツのようだ。

きょう土曜は中野で LL Future があったようで、しかしすっかり行くのを忘れてしまい、天気もわるくなってきてそのままずっと家にいたりして、じゃあenmaを試してみるかと思ったら若干いじる必要があり、ついでなのでDebian GNU/Linuxのパッケージにしてみた。debsignもしてないdebですがよければどうぞ。

http://tmp.mrmt.net/enma_1.0.0-1_i386.deb
md5sum bd68b60b5112c4f9a53ac50a0218e535

postfixで使う場合は、/etc/enma.confmilter.postfixtrueに変えて、/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/Linuxglibcパッケージ特有の問題みたい。

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にして半年ぐらい遊んでました。ただ本気のトラフィックをどんぐらい捌けるかはどうなんでしょうね。