会社の業務でさくらインターネットのレンタルサーバを使用しているのだが、スパムメールの対応で困っている。
ウェブサーバとメーリングリスト(ML)の運用がメインで、ユーザからの問合せ窓口にMLを使っているのだが、最近は海外からのスパムメールが多く1時間あたり10通以上のスパムが届くようになってきた。
MLメンバが20人だと1日で平均5,000通近いスパムメールをMLで配信していることになる。
さくらインターネットは、メールの個別アカウントにはSpamAssassinというベイジアンフィルタのスパムフィルタが使えるのだが、メーリングリストにはデフォルトでは対応していない。しかもMLでSpamAssassinを使うにはどうすればよいのか、さくらではサポートしてくれないので大抵の人はここで手詰まりになる。
さらに、さくらのメーリングリストシステムはfmlという2004だか2008年に開発が終了しているMLシステムを使っており、関連する情報がほとんど見つからない。あってもかなり古い情報なのと、UNIX/Linuxを知らないと理解できない情報がほとんどである。
今回、四苦八苦しながらさくらのレンサバ側で迷惑メールをブロックすることに成功したので、備忘録替わりにやった内容を書いておく。
ネット上の情報を試すがどれもダメだった
「さくら fml スパム」「さくら fml 迷惑メール」で検索すると、2004年とか新しくても2014年とか2015年あたりにトライされた方のサイトがヒットするが、どれも効果が無かった。
一番目にしたのが、MLのアカウントで、fmlの設定ファイルconfig.phやcfやincludeやinclude-ctlを書き換えて、fmlの前にスパムフィルタ”SpamAssassin”を通す方法である。
しかし、さくらではこの方法ではスパムメールはドロップされない。
なぜなら、ML宛てのメールはfmlに渡される前にメールデリバリーエージェント(MDA)である”maildrop”に渡されるからだ。
maildropの設定ファイル.mailfilterが肝
メーリングリストを作ると、レンサバ上の以下のパスにmaildropの設定ファイル.mailfilterが作成される。maildropはその.mailfilterファイルの内容に従って処理を行う。
UNIX/Linuxではファイルの先頭に”.”が付くファイルは隠しファイルを意味する。隠しファイルにしているということは通常は触って欲しくないという意味であるが、今回はこのファイルに変更を加える。
さくらのレンサバだと以下のパスに.mailfilterファイルがある。FTPクライアントで接続するか、UNIX/LinuxのCGIが得意な人はSSHで接続してもOK。
/home/(user_name)/MailBox/(ML名)
ここにある.mailfilterをエディタで開くと
to "| /usr/local/bin/fml-wrapper"
と書かれている。
この”fml-wrapper”は実行ファイル(プログラム)で、ソースコードは /home/(user_name)/fml/spool/ml/(ML名)にある。
Cソースが読める人は見るとわかるが、fml-wrapper.cの中でfml本体(fml.pl)を呼んでいる。
つまり、fmlのconfig.phやcf、includeやinclude-ctlでSpamAssassinを通しても、スパム判定されたメールがただ配信されるだけである。
fmlはSpamAssassinが付けた”X-Spam-Flag: YES”をフックしてそのメールをドロップしてくれる機能があるらしいのだが、それについて解説されたサイトが見当たらない。(ブックオフでO’REILLYの「fmlバイブル」を200円で購入して読んでみるも、イマイチよくわからなかった)
しかし、
to "| /usr/local/bin/fml-wrapper"
の部分でfmlによる配信が実行される前にSpamAssassinを通し、スパム判定されたメールをドロップすれば.mailfilterの変更だけでなんとかイケそうである。
.mailfilterをカスタムする
…ということで実際にスパム対策をした内容がこちら。
/home/(user_name)/MailBox/(ML名)にある.mailfilterをPCにコピーする。(バックアップは保存しておくこと)
.mailfilterをエディタで開き、以下のコードを挿入する。
xfilter "/usr/local/bin/spamc" cc "! (スパムチェック用のメールアドレス)" if ( /^X-Spam-Flag:.*YES/ ) { to "maildir/.spam/" exit } to "| /usr/local/bin/fml-wrapper"
解説すると、まず最初のxfilter~の行でスパムフィルタ”SpamAssassin”を通す。
2行目のcc~の解説は後で。
スパム判定されたメールがあれば、3行目のif( /^X-Spam-Flag:.*YES/ )がtrueになるので、{}内のコードが実行される。
5行目のto “maildir/.spam/”はスパムメールを/.spamディレクトリに保存する。(念のため)
そして6行目でexitすれば、8行目のML配信処理が実行されない。
スパムメールでなければ3行目のif文がfalseになるので、8行目のML配信処理に飛んでくる。
これで大方のスパムメールはML配信されずにレンサバ上で捨てられる。
if ( /^X-Spam-Flag:.*YES/ ){ to "maildir/.spam/" exit }
のような、if文の後ろに'{‘を付けるK&R的な書き方はエラーになるので注意。
スパム判定の確認
晴れてレンサバ上でスパムをブロックできても
という疑念が残ると思う。
そういうときは5行目の
to "maildir/.spam/"
でスパム判定されたメールが保存されるのでよいかと思ったのだが、保存されたファイルを見てもテキスト形式になっていないので、これらの中からスパムでないメールを探したり、内容を確認するという作業は大変そうである。
そこで、レンサバ上のメールアカウントを一つ作り、SpamAssassinを通過した後にそのアカウントにメール送信するために2行目を
cc "! (スパムチェック用のメールアドレス)"
としている。
例えば、spamcheck@hogehoge.comというアドレスであれば、
cc "! spamcheck@hogehoge.com"
と書けばよい。
そうすることで、ML宛ての全てのメールがここに転送されるので、後でチェックすることができる。(同じドメイン上でアカウントを作ればさくらのWEBメールが使えるので、WEBブラウザ上で確認できる)
時々そのアカウントをWEBメールで確認すれば、実際にどのくらいスパムが来ているのか、スパムでないお客さんからのメールを見落とすことを防ぐことができる。
スパムチェック用のアドレスでチェックできれば、5行目の
to "maildir/.spam/"
は無くてもいい。この行があると、定期的に/.spam/配下を削除してあげないとサーバ容量を圧迫するので注意。
スパムメールをサーバ上に保存しない場合は、.mailfilterはこちらの書き方でどうぞ
xfilter "/usr/local/bin/spamc" cc "! (スパムチェック用のメールアドレス)" if ( /^X-Spam-Flag:.*YES/ ) { to "maildir/.Trash/" exit } to "| /usr/local/bin/fml-wrapper"
/.Trashに入ったメールは自動的に削除されるので、後からお掃除しに行かなくても大丈夫。(実際に/.Trushを見に行ってもファイルは無いです)
まとめ
上記の対策を行ってからというもの、ムカつくスパムが末端に配信されなくなって精神衛生上、穏やかな日々を過ごせるようになった。
そりゃそうだ、毎日毎日「ホットな女の子~」「新しいマ○コ」「セ○クス」「フ○ック」なメールを仕事中に見せられりゃ、エロい気持ちなんか通り越して怒りすら沸いてくる。
実際はさくらサーバまで来ているので根本的な対策ではないが、1日に5,000通以上もML配信に費やしていたサーバリソースが限りなく0に近づいたのは気分的にも気持ちいい。
エロ画像を見るよりも、それを送りつけてくるスパムメールを撃退することのほうが気持ちいいとは、なんともよく分からない世の中である。
さくらのレンサバでML運用してスパムメールに悩んでいる人の参考になれば嬉しいです。
というか有償でもいいのでMLの迷惑メールについてサポートして欲しい。
レンサバ利用者のスパム配信を抑えれば、
・サーバの電力削減
で、利益改善できるし、その結果
という形でユーザに還元できるんですけどね。
コメント
すごく試したい情報です。
仰る内容のコードは、このような理解でよろしいでしょうか。
チェック用としてcheckspammail@-を作成しました。
=======================
xfilter “/usr/local/bin/spamc”
// ★ここで全てのメールが、checkspammail@-で受信される
cc “! (checkSpamMail@-)”
if ( /^X-Spam-Flag:.*YES/ )
{
to “maildir/.Trash/”
exit
}
// ★問題ないメールだけそれぞれのメールアドレスなりメーリングリストなりに飛ぶ
to “| /usr/local/bin/fml-wrapper”
=======================
spamassasinをいくらいじっても解決しなくてほとほと困ってます。
ご教示いただければ幸いです。
中小企業のしがないSE さん
はい、それで大丈夫だと思います。ただし.mailfilterファイルを変更する前に、必ず旧ファイルのバックアップを保存してから作業してください。(重々承知のこととは思いますが、自己責任でお願いします)
対策に効果があれば返信いただけると励みになります。
ご確認とご返信をいただきありがとうございます!
人様の環境では動き自分の環境では動かないという、あるあるに陥ってます。
コメント欄を荒らしたくないないので、解決したらご連絡しますね。
このコメントの処理は、残すも消すもお任せします!
◆NG
=======================
xfilter “/usr/local/bin/spamc”
// ★checkspammail@-で受信される
cc “! (checkSpamMail@-)”
// ★問題ないメールなのに.Trashに入っちゃう!
// (.spamにして試したらspamに入っちゃったから、きっと.Trashで消されてる)
// でも、if文の書き方は他所様のサイト拝見しても同じ書き方してる。。。。。。
if ( /^X-Spam-Flag:.*YES/ )
{
to “maildir/.Trash/”
exit
}
// ★exitしてるから、問題ないメールなのに受信されない。
to “| /usr/local/bin/fml-wrapper”
=======================
◆OK:最後まで実行され、ちゃんと受信できる。
=======================
xfilter “/usr/local/bin/spamc”
cc “!checkSpamMail@-”
to “| /usr/local/bin/fml-wrapper”
=======================
ではでは!
できました!
文字コードをUTF-8、改行をLFに指定することで解決しました。
権限600とUTF8は設定してましたが、改行は見落としてました。恥ずかしい。
◆ちゃんと動いたコード
=======================
xfilter “/usr/local/bin/spamc”
cc “! (checkSpamMail@-)”
if ( /^X-Spam-Flag:.*YES/ )
{
to “maildir/.Trash/”
exit
}
to “| /usr/local/bin/fml-wrapper”
=======================
拝見した貴Webサイトの記事が一番シンプルで、分かりやすかったです。
コメントへのご返信も、ありがとうございましたm_ _m
中小企業のしがないSE さん
ご報告ありがとうございます。
文字コードでしたか。普段UTF-8でやっていたので気づきませんでした。
無事に動作したとのことで何よりです!
備忘録のつもりで書いた記事でしたが、お役に立てて嬉しいです。