vpopmailでPOP before SMTPできない罠(;・∀・)

どーも、へっぽこサーバ管理者ですっ!(`・ω・´)
最近会社のメールサーバが挙動不審でして、複数のお客様から
メール送信できねぇぞ(#゚Д゚)ゴルァ!!
とお叱りの言葉を頂戴しました(;・∀・)

メールサーバのログをチェックすると”rejected relaying”というメッセージが出ており、不正中継と見なされ送信を拒否されているようです。
会社のメールサーバは qmail と vpopmail の2つ(正確にはもうちょっとある)のOSS(オープンソースソフトウェア、つまり無償のソフトウェア)を組み合わせて構築しており、POP before SMTPという仕組みを導入して、メールの不正中継を防止しています。
POP before SMTPについての解説はコチラ

それで、苦情の件はメールを受信した後、一定時間の間にメールを送信するという「条件」をクリアしていなんだろうな・・・と簡単に考えておりました。
だがしかし、さらに調査を進めるとその「条件」はクリアしていたのです(汗)
しかも、まったく送信できないわけではなく、送信できているお客様もいる。。
各種ログを調査しても手がかりはなく、暗礁に乗りあげてしましました(滝汗)。
vpopmailがPOP before SMTPを実現するキーとなっているのが

/home/vpopmail/etc/open-smtp

というファイルです。
こちらのファイルはPOP3でメールを受信する際、ユーザー認証に成功するとアクセス元のIPアドレスが記録されます(vpopmailが自動で作成します)。
こちらファイルに着目したところ、所有者がroot:rootに変わっており、所有者を本来のvpopmail:vchkpwに変更しても、何らかのタイミングでroot:rootに戻ってしまう。
困ったときのstrace頼みでプロセス(デーモン)をトレースしてみました。

# strace -p プロセス番号 -f -e trace=open 2>&1 | grep "open-smtp"
[pid 24081] open("/home/vpopmail/etc/open-smtp.lock", O_RDWR|O_CREAT|O_TRUNC, 0666) = 4
[pid 24081] open("/home/vpopmail/etc/open-smtp", O_RDWR) = -1 EACCES (Permission denied)
[pid 24081] open("/home/vpopmail/etc/open-smtp", O_RDWR|O_CREAT|O_TRUNC, 0666) = -1 EACCES (Permission denied)

Bingo!やっぱりエラーが出ていて、書き込めないようです。
犯人はPOP3S・・・tcpserver+stunnelで起動するのですが、/home/vpopmail/bin/vchkpwがroot権限で動くため、作られるファイルも所有者がroot:rootになってしまうのが原因のよう。
動きとしては/home/vpopmail/etc/open-smtp.tmp.????? を所有者root:rootで作成、その後/home/vpopmail/etc/open-smtpへrenameしているという流れ。
対症療法としては/home/vpopmail/bin/vchkpwの所有者をrootに変更してchmod u+sで
SUIDをセットすれば動くようになりますが、/home/vpopmail/bin/vchkpwをroot権限で動かしたくないので別の方法をとることにしました。

■tcpserver(SSL対応版)のインストール

$ wget http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz
$ tar -xzf ucspi-tcp-0.88.tar.gz
$ cd ucspi-tcp-ssl-0.88
$ wget http://www.nrg4u.com/qmail/ucspi-tcp-ssl-20050405.patch.gz
$ gunzip ucspi-tcp-ssl-20050405.patch.gz
$ patch < ucspi-tcp-ssl-20050405.patch
$ su
# make
# install -m 755 -o root -g root tcpserver /usr/local/bin/tcpserver-ssl

tcpserverにSSL対応のパッチを当ててtcpserver-sslとしてインストールします。

■POP3 over SSLの設定

# cat > /service/qmail-pop3s/run < #!/bin/sh
VPOPMAILUID=`id -u vpopmail`
VPOPMAILGID=`id -g vpopmail`
exec env - PATH="/usr/local/bin:/var/qmail/bin:/home/vpopmail/bin:${PATH}"
tcpserver-ssl -vRDH -l0 -s -n /etc/stunnel/server.pem
-u "$VPOPMAILUID" -g "$VPOPMAILGID" 0 pop3s
qmail-popup mail.mmy.ne.jp vchkpw qmail-pop3d Maildir 2>&1
EOF
# chmod 755 /service/qmail-pop3s/run
# svstat /service/qmail-pop3s{,/log}
/service/qmail-pop3s: up (pid 22570) 1621 seconds
/service/qmail-pop3s/log: up (pid 22571) 1621 seconds
# svc -t /service/qmail-pop3s{,/log}
# svstat /service/qmail-{pop3,smtp}s{,/log}
/service/qmail-pop3s: up (pid 22570) 2 seconds
/service/qmail-pop3s/log: up (pid 22571) 2 seconds

tcpserver-sslがpop3sを待ち受けして、所有者vpopmail:vchkpwで/home/vpopmail/bin/vchkpwを起動するようにします。

# strace -p プロセス番号 -f -e trace=open 2>&1 | grep "open-smtp"
[pid 29184] open("/home/vpopmail/etc/open-smtp.lock", O_RDWR|O_CREAT|O_TRUNC, 0666) = 4
[pid 29184] open("/home/vpopmail/etc/open-smtp", O_RDWR) = 5
[pid 29184] open("/home/vpopmail/etc/open-smtp.tmp.29184", O_RDWR|O_CREAT|O_TRUNC, 0666) = 6

straceの結果もOK。
これでバッチリです。