最近,自宅のメールサーバから fetchmail でメールを取得しようとすると,「認証に失敗した」などというエラーが出るようになった。調べたところ,メールスプールのフォーマットが壊れているとこのような事態になるようである。
メールスプールを修復するには,次のように formail を使う。以下のオペレーション例における user はメールスプールファイルであり,実際はメールアカウントのユーザ名と同一の名称に読み替えればよい。
% cd /var/mail % cp -p user /tmp/user.bak % formail -b < user > /tmp/user % cp /tmp/user user
しかし,これで修復してみると,From ヘッダも To ヘッダも何もない空メールであることがわかる。あまりに頻繁にこの現象が発生するので,その根本原因を探ってみた。procmail のログをみると,SpamAssassin (スパムチェッカー) が SIGPIPE シグナルで異常終了しているとき ([xxxxx] warn: spamassassin: killed by SIGPIPE メッセージ),この状態に陥るようである。この場合,チェックされたメールはただの空白文字でスプールされてしまい,結果的にメールスプールが壊れた状態になってしまうというわけであった。なぜ SpamAssassin がコケるのか。Assassin とは「暗殺者」の意味だけど,殺し屋がターゲットを始末する前に自らが不慮の死に襲われるなんてマヌケではないか。詳しくはわからない。いちばんありそうなのはメモリ不足だろうか。ご存知の方はご教示いただけると幸いである。
SpamAssassin が異常終了するとメールが壊れるというのは大問題である。大事なメールがスペースに化けて失われてしまうのだから。アベンドの原因は不明である以上,適切な対策を施すことは難しい。とりあえず SpamAssassin を 3.2.5 にバージョンアップし,これまで spamassassin コマンドを使用していたのを,spamd に切替えることにした。spamd はデーモンとして動作する SpamAssassin 付属のプログラムであり,より高速にスパムチェックを行うとのこと。よって所要リソースも spamassassin コマンドより少ないだろうと期待したのである。
FreeBSD では mail/p5-Mail-SpamAssassin を ports でインストールすると,spamd とともに,これを起動するための sa-spamd.sh が組込まれる。/usr/local/etc/rc.d ディレクトリにおいて sa-spamd.sh start を実行するか,もしくは /etc/rc.conf に spamd_enable="YES" 行を追加してリブートすると,spamd が起動して常駐する。
spamd にチェックを依頼するクライアントプログラムは spamc である。procmail で自動的にスパムチェックする場合は,以下のような記述を $HOME/.procmailrc に追加する。
:0fw * !^X-Spam.* | /usr/local/bin/spamc :0: * ^X-Spam-Status: Yes spam/.
いまのところ,受信したメールの処理状況を見ているいる限り SIGPIPE アベンドは出ていない。しばらくは受信したメールすべてをバックアップした上で,スパムチェックを施す運用とすることにした。