まんぷく

Exim + SpamAssassinで迷惑メール対策

迷惑メールが急増

 最近中国からの迷惑メールがどんどん激しさを増してきて、受信メールの99%がスパム?な状況になってきたのでSpamAssassinを導入して対策することにしました。

実行速度を考えるとサーバープロセスとして常駐させる必要があり、スパム対策のためだけに貴重なサーバー資源を浪費するのが嫌で今まで導入をためらってきたのですが、ここまでの状況になるともはや仕事に使えない状況です。

またiPhoneには迷惑メール判定機能がないので、サーバ側で振り分けてくれると、毎度毎度「プチプチ」つぶしのごとく迷惑メールをゴミ箱に放り込む作業が不要になります。

SpamAssassinって何?

 SpamAssassinは読んで字のごとく(Spam=迷惑メール Assassin=刺客)迷惑メール判定対策ソフトで、チョー有名ドコロのオープンソース・ソフトウェアです。ウェブサーバーで有名なASFのトッププロジェクトの一つでもあります。結構長い間バージョンが上がっていませんが、十分な機能と安定性があるからだと思います。  

SpamAssassinをDebianへ導入

 弊社サーバーは[Debian Linux][]で構築しているので、apt-getコマンド一発でインストール出来ます。

~$ sudo apt-get install spam assassin

/etc/default/spamassassinを変更します。

ENABLED=0
CRON=0

ENABLED=1
CRON=1

変更出来たら以下のコマンドで実行を開始します。

~$ sudo /etc/init.d/spamassassin start

デフォルト設定のままだと783ポートを使いますので、以下のコマンドで実行を確認出来ます。

~$ sudo lsof -i:spamd

その他にも色々あるので好みの方法で実際に動いている事を確認して下さい。

~$ netstat -a | grep spamd
~$ ps aux | grep spamd
~$ /etc/init.d/spamassassin status

Eximの設定

注)

heavyじゃないと駄目です。

 この記事では既にEximは導入済みであることが前提ですが一つ注意があります。DebianのExim4には二つのdaemonパッケージ(exim4-daemon-lightとexim4-daemon-heavy)があり、SpanAssassinを利用したい場合はexim4-daemon-heavyをインストールする必要があります。もしlightをお使いの場合はheavyに置き換えて下さい。sudo apt-get install exim4-daemon-heavyで自動的に置き換わる(squeezeで確認)ので、手間は殆どかかりませんのでご安心を。

single or multi ?

 Eximは導入時に設定ファイルを単独ファイルにするか、分割ファイルにするかを選択するようになっています。これから出てくるファイル名は分割ファイル設定用ですので、単独ファイル設定の場合は修正先が異なります。

設定ファイルを変更

spamdの接続先設定

 SpamAssassinの接続ポート番号を変更していなければ変更の必要はありません。/etc/exim4/conf.d/main/02_exim4-config_optionsの以下の行をコメント外して変更します。複数のspamdを設定出来るのでスケールさせる時に使うって感じでしょうかね。

# spamd_address = 127.0.0.1 783 
X-Spamヘッダー追加設定

/etc/exim4/conf.d/acl/40_exim4-config_check_dataの以下のコメントをはずします。これでX-Spamヘッダーがメールボディに追加されるようになります。X-Spam_reportはかなりうざいヘッダーなので正直いらないかも。普通は見えないので問題にはならないと思いますが。

 # warn
 #   spam = Debian-exim:true
 #   message = X-Spam_score: $spam_score
 #             X-Spam_score_int: $spam_score_int
 #             X-Spam_bar: $spam_bar
 #             X-Spam_report: $spam_report

  warn
    spam = Debian-exim:true
    message = X-Spam_score: $spam_score
              X-Spam_score_int: $spam_score_int
              X-Spam_bar: $spam_bar
              X-Spam_report: $spam_report
システム全体フィルタの設定

 この設定はどこでも良さそうなのですが、とりあえず/etc/exim4/conf.d/main/02_exim4-config_optionsの最後のほうに書いておいて下さい。system_filterは任意のファイル名です。

transportについては/etc/exim4/conf.d/transport以下で定義済みの名前を使っています。「既存の設定じゃ満足出来ないんだよ、ジョー!」って人は独自にtransportを定義してもらって、お好きな名前に変更することも可能です。homeじゃないけどmaildirは自動で生成して欲しい等のワガママを叶えるには独自transportの定義が必要になるかもですね。参考ページ

system_filter = "/etc/exim4/system.filter"
system_filter_user = Debian-exim
system_filter_group = Debian-exim
system_filter_directory_transport = address_directory
system_filter_pipe_transport = address_pipe
system_filter_file_transport = address_file
system_filter_reply_transport = address_reply
system.filter作成

 あくまでサンプルですので好みに合わせて修正をお願いします。

スパマーにメールを送り付けるサンプル
# Exim filter
if $h_X-Spam_score_int is above 99 and
    foranyaddress $recipients ($thisaddress contains "@mydomain.com") then
    testprint "SPAM !!"
	save /var/mail/suspect_spam
	mail to $thisaddress
	subject "[ SPAM Witheld ] $local_part $h_subject:"
	from "Company Mail Server <noreply@mydomain.com>"
	text "This Message is sent automatically by e-mail software, please do not reply to it\n\nThe server suspects that a message sent to you by $h_From: is spam.\nThe original message has not been sent to you, but stored on the server.\nIf you were expecting it, please contact your system administrator with the reference\n$message_id"
	finish
endif

最初はここのをまるごとコピーして使ってみたのですが、記述ミスがいくつも有ってエライ事になりました。テスト送信してもメールが届かないのでログを見てみたら案の定このざまでした。paniclogなんて初めて見ましたよ(笑)。

cat /var/log/exim4/paniclog
2013-08-31 14:43:39 1VFdx2-000692-9h Error in system filter: "and" or "or" or "then" expected near line 3 of filter file, but found "save"

いくらプライベートメールサービスだからってノーテストでの実践投入はさすがに無理がありました。焦ってリスタートとしようとしたら、以下のメッセージに追い打ちをかけられたりで実にガクブルな体験が出来ました。ちなみに取り敢えずフィルターの中身を空っぽにして、/var/log/exim4/paniclogを消してから落ち着いてリスタートすればあっさり動きます。

~$ sudo /etc/init.d/exim4 restart
Stopping MTA for restart: exim4_listener.
Restarting MTA: exim4.
ALERT: exim paniclog /var/log/exim4/paniclog has non-zero size, mail system possibly broken ... failed!

で、さすがにやばいと思ったので本家のドキュメントを読んだらちゃんとテスト方法ものってました。

exim -bF system.filter -bfl user_name -bfd mydomain.com < test.mail
メールアドレス毎のフィルタの設定

 Systemwide Filterで迷惑メールを判定した後、直接特定ユーザーの迷惑メールフォルダに送り込めると思っていたのですが、それは間違いで.forward同様にメールアドレス毎に呼び出す設定を追加しないと駄目でした。てな訳で/etc/exim4/cond.d/router/にファイルを追加します。

#####################################################
### router/650_exim4-config_gotojunk_filter
#####################################################
gotojunk_filter:
  debug_print = "R: gotojunk_filter for $local_part@$domain"
  driver = redirect
  domains = +local_domains
  check_local_user
  check_owner = false
  file = /etc/exim4/gotojunk.filter
  no_verify
  no_expn
  check_ancestor
  allow_filter
  forbid_smtp_code = true
  directory_transport = address_directory
  file_transport = address_file
  pipe_transport = address_pipe
  reply_transport = address_reply
#####################################################
### end router/650_exim4-config_gotojunk_filter
#####################################################
迷惑メールフォルダ(Maildir前提)にしまっちゃうサンプル
# Exim filter
if $h_X-Spam_score_int is not "" and
   $h_X-Spam_score_int is above 96 then
   save $home/Maildir/.Junk/
   finish
endif

ちなみにUser Filterをテストする場合のオプションは-bFではなくて-bfです。

exim -bf gotojunk.filter -bfl user_name -bfd mydomain.com < test.mail

雑感

 元々がqmailからの乗り換え組だったのでeximには余り思い入れが無かったのですが、今回のSpamAssassin導入にあたって関連ドキュメントを読んで、理解が深まりちょっと愛着がわきました。それにしてもfilterが非常にプログラマブルに書ける事を知ったのは収穫でした。

Categories
tech

Tags
Exim4 / SpamAssassin / Debian