pop-before-smtp


spam対策で自由に使えるSMTPサーバが消滅した。
プロバイダのSMTPサーバにしてもOP25Bや他のネットワークからのアクセス制限などもあり使いにくくなっている。
F&Fではfnf.jpドメインのメールを使用しているのだが、SPF関係もあってfnfドメインのメールを正しく送信するためにはfnf.jpでSMT
サーバを建てるしかない。
そこでpop-before-smtpを組んでみることにする。
MTAはpostfixを、popperにはqpopperを使っているこのシステムにpop-before-smtpを追加する。
pop-before-smtpはportsでもインストールできるし、そもそもPer
で書かれているのでインストール自体は簡単だと思う。
原理的にはqpopperの吐き出したログをチェックして、そのログから認証に成功したIPアドレスを抽出、それをdbファイルに書き出しす。
postfixはこの「信頼出来るIPアドレスからのメール中継を許可する」設定をしてpop-before-smtpの作ったファイルを監視させるというわけだ。


pop-before-smtpのインストールは何ということはないが、configファイルの設定変更には少々悩んだ。
まず最初はBerkeleyDB関係だ。
pop-before-smtp-conf.plファイルで以下の部分を有効化する(=cutを消す) とBerkeleyDB.pmを要求してくる。
=cut #====================== Postfix BerkeleyDB =======================START=
# If you comment-out (or remove) the two surrounding =cut lines, we'll use
# BerkeleyDB instead of DB_File
use BerkeleyDB
#$mynet_func = \&mynet_postfix;
# Use the default $tie_func = \&tie_BerkeleyDB; $sync_func = \&sync_BerkeleyDB; $flock = 0
my $dbh
# We must tie the global %db using the global $dbfile. Also sets $dbh for
# our sync function. sub tie_BerkeleyDB { $dbh = tie %db,'BerkeleyDB Hash',-Filename=>"$dbfile.db",-Flags=>DB_CREATE or die "$0 cannot dbopen $dbfile $!\n"; } sub sync_BerkeleyDB { $dbh->db_sync and die "$0 sync $dbfile $!\n"; }
=cut #====================== Postfix BerkeleyDB =========================END=
まずBerkeleyDB本体?をインストールする。
これにも少々癖があってtar zxvf db-4.3.27.tar.gz
cd db-4.3.27 #cd build_unix/
../dist/configure
make
make instal
とやるのだが、最初からdistディレクトリでmakeしようとすると失敗する。
ま、しかしこれは良いだろう。
次にcpanでBerkeleyDB.pmのインストールを試みるが失敗。
cpan install BerkeleyDB
OSの種類やバージョンなどによっては成功するかも知れないが、少なくともFreeBSD7.0-RELEASEではダメだった。
そこで/root/cpan/build/BerkeleyDB......に移動して、make clea
その後、config.inを開いてINCLUDEとLIBのディレクトリ指定を実際にインストールされているバージョンの正しいものに変更する。
どちらも/usr/local/BerkeleyDB/...になっているはずなので、これを/usr/local/BerkeleyDB.4.3.27/...に変更する。
そしてperl Makefile.PL
make
make instal
とすれば良いが疲れるなぁ。
というわけで(つまりこれは前書きだ)、BerkeleyDBを使わなければいい。
#----------------------- Postfix NDBM_File -----------------------START-
# If you comment-out (or remove) the two surrounding =cut lines, we'll use
# NDBM_File instead of DB_File
use Fcntl;
use NDBM_File
#$mynet_func = \&mynet_postfix; # Use the default
$tie_func = \&tie_NDBM;
$sync_func = sub { };
$flock = 0
# We must tie the global %db using the global $dbfile.
sub tie_NDBM
{
 tie %db, 'NDBM_File', $dbfile, O_RDWR|O_CREAT, 0664
   or die "$0 cannot dbopen $dbfile $!\n";
}
#----------------------- Postfix NDBM_File -------------------------END- ここのコメント(=cut)を外す。
これでBerkeleyDBなしでも動く。
ちなみに、他のモジュールも無いと言われたらcpanでインストールするがこれは失敗しないと思う。
cpan install Date Parse
cpan install Net Netmask


次なる問題?はログファイルのフォーマットだ。
pop-before-smtp-conf.plには代表的popperの吐き出すログフォーマットに合わせたセッティングがされていて、そこのコメントを外すことで容易にインストールできるようになっている。
が、残念ながらF&Fで使っているqpopperのログとは合わなかった。
通常であれば、
# For Qpopper POP/APOP Server (matches in.qpopper, qpopper, and popper).
#$pat = '^[LOGTIME] \S+ (? in\.q|q)?popper\[\d+\] Stats \S+ ' .
# ココのコメントを外すだけなのだが、これはログに合わせて改造した。
$pat = '^[LOGTIME] 2008 \[\d+\] Stats \S+ ' .
'\d+ \d+ \d+ \d+ (\d+\.\d+\.\d+\.\d+) (\d+\.\d+\.\d+\.\d+)'
qpopperの吐き出すログは↓である。
Jul 2 07 14 55.518 2008 [30401] Stats username 0 0 440 4495031 210.230.189.98 210.230.189.98
従って[LOGTIME]の所も変更する必要があり、
$logtime_pat = '(\S\S\S .\d \d\d \d\d \d\d\.\d\d\d)'
こんな感じになった。
他に変更点は、qpopperの吐き出すログの位置を示す部分
$file_tail{'name'} = '/var/log/qpopper.log'
postfixに渡すためのdbファイルを作る場所の指定
$dbfile = '/etc/postfix/pop-before-smtp'
である。
ちなみにqpopperがログを出さない場合はinetd.confで(他のやり方もある)
pop3 stream tcp nowait root /usr/local/libexec/qpopper popper -s -R -t /var/log/qpopper.lo
こんな風に変更し、inetdにHUPを送ればログが生成される。
なお適当なところでログを消すなり圧縮保存するなりのシカケをしておかないとビックリするようなことが起こるに違いない。
(syslog.confに↓でも付け加えておけばOK)
/var/log/qpopper.log  644 7  100 *   J
設定を変更したら、
/usr/local/sbin/pop-before-smtp --config=/usr/local/etc/pop-before-smtp-conf.pl --debug --nowrite --reproces
として起動してみる。
(ディレクトリはあくまでもportsで入れた場合のもの)もしもログフォーマットが合っていなければ何も表示されないか、或いはタイムフォーマットがおかしいと言ってくる。
もっとプリミティブな問題であれば、例えば○○のモジュールが無いとか何だとかと文句が表示されるかも知れない。
ログのIPアドレス部分がうまく取れないときにはPerlのモジュールがエラーを激しく表示してくることもある。
それらが一段落して動作が確認できたようならば、postfix用のdbが作られているはずだ。
strings /etc/postfix/pop-before-smtp.d
ここにIPアドレスが入っていればOKである。
ok210.230.189.98 次にpostfix側の設定を行う。
main.cfに以下を追加する。
smtpd_recipient_restrictions = permit_mynetworks,
   reject_non_fqdn_recipient
   check_client_access hash /etc/postfix/pop-before-smtp
   reject_unauth_destinatio
これでpop before smtpが動作するようになっているはずだ。
【追記】
NDBMを指定すると、pop-before-smtpのログには正しい動作が記録されるものの、pop-before-smtp.dbが更新されない。
いや、pop-before-smtp reloadを行うと更新される。
何故だ?!試しにerkeleyDBを使うようにしてみるとIPアドレスはリアルタイムに追加されるのだが消去されない。
これではセキュリティホールがどんどん拡大していくだけだ。
何故だ?!しかもpostfixが要求するdbフォーマットと違うようで認証されない。
仕方ない、smtp-authにチャレンジするか…詳細は別記事で。