HOME 備忘録 書き込む

対スパム多重フィルタ


Feb 26, 2012

1. はじめに

紫藤の自宅メールサーバーは bogofilter 1.0 を使ってスパムメールを識別していましたが、 最近、スパムメールが増えたのと、bogofilter の識別率が低下したので、スパム対策を見直すことにしました。

試した対策は以下の5つです。

  1. bogofilter+mecab の導入
  2. postfix の設定の見直し
  3. greylisting の導入
  4. Subject による振り分け
  5. メールアドレスの難読化
これらの対策は単体ではそれほど効果を挙げませんが、複数種類のフィルタで多重処理することにより大きな効果を挙げることができました。

2. bogofilter+mecab の導入

いままでは、nkf, kakashi を通してから、bogofilter にメールを渡していましたが、検出効率がいまいちなので、 bogofilter+mecab を導入しました。 このパッチは、内部で文字コードを UTF-8 に変換し、mecab で分ち書きしてから bogofilter の word list の処理にかけます。

debian のパッケージにはなく、自分でコンパイルする必要がありますが、 ここに書いているとおりにやって問題なくコンパイルできました。

検出効率は期待したほどは向上せず、7--8 割程度です。 それでも もともとの bogofilter 1.0 (6--7 割程度) よりは若干向上しています。 学習によって検出率が順調に良くなっているので、導入した価値はあると思っています。

3. postfix の設定の見直し

あまりにスパムが多量に送られてくるので、明らかにスパムとわかるものは postfix 側ではじくようにしました。 ただ、正常なメールまではじいてしまわないように、控えめに設定しました。 postfix の設定は以下のサイトを参考にしました。
  1. Postfix Documentation
  2. 阻止率99%のスパム対策方式の研究報告
  3. Rgrey - S25R + greylisting
  4. MTA のアクセス制御
#2#4 の議論は大変参考になりました。 #2 は技術的には参考になったのですが、ポリシーは若干過激な気がします。 ポリシーとしては #4 で言われていることがまともだと思います。 紫藤のメールサーバーでやっていることは基本的に #3 と同じですが、 greylisting の適用範囲を逆引きができないクライアントに限っています。

ブラックリストやホワイトリストはメンテナンスが面倒なので、基本的には導入していません。 (greylist 入りから救済するホワイトリストを導入しましたが、必須ではありません。また、今後メンテナンスするつもりはありません。) また、DNSBL は通常のクライアントをブラックリストに挙げていたり、 突然サービスが停止する リスクがあるので、 使用していません。(例えば、ここを参照。)

設定のポリシーは以下のとおりです。 前から順番にチェックしていき、条件に合致したら処理します。そうでない場合はその次の条件をチェックします。 この設定は、明らかにおかしいものや、逆引きできないでかつ再送してこなかったものだけをはじき、他は受け付けます。

  1. 自宅 の 有線 LAN でつながっている PC からのメール送信を許可。
  2. SASL で認証したクライアントからのメール送信は許可。 (スマートフォンからメールを送れるようにする。)
  3. クライアントのホスト名が不正なもの拒否。
  4. 存在しないユーザ宛てのメールは拒否。
  5. 外部から外部へのメール送信は拒否。
  6. 合意なしにコマンドを連続して送ってくるクライアントは拒否。
  7. こちらのサーバを騙ったものは拒否。
  8. こちらのユーザーを騙ったものは拒否。
  9. IP アドレスの逆引きができないときは greylist で処理する。(その際、必要に応じて white list で救済する。)
  10. 外部から内部へのメールの送信を許可。
  11. その他は拒否。
以下に postfix の main.cf ならびにそこで使用されているデータファイルを示します。

[main.cf] (アクセス制限にかかわる部分)

                (前略)
001:   smtpd_delay_reject = yes
002:   smtpd_helo_required = yes
003:   smtpd_recipient_restrictions =
004:     permit_mynetworks
005:     permit_sasl_authenticated
006:     reject_invalid_helo_hostname
007:     reject_unlisted_recipient
008:     reject_unauth_destination
009:     reject_unauth_pipelining
010:     check_helo_access hash:/etc/postfix/myself
011:     check_sender_access hash:/etc/postfix/my_user
012:     check_client_access hash:/etc/postfix/white_clients
013:     check_reverse_client_hostname_access hash:/etc/postfix/grey_clients
014:     permit_auth_destination
015:     reject
016:   
017:   smtpd_restriction_classes = grey
018:   grey = check_policy_service inet:10023
                (後略)

[myself]
#クライアントが以下のドメインを騙ると拒否
shido.info       REJECT
www.shido.info   REJECT
124.41.66.201    REJECT
7c2942c9.i-revonet.jp   REJECT

[my_user]
#Sender にこちらのユーザを騙ると廃棄
takafumi@shido.info   DISCARD

[white_clients]
# whilte list: 逆引きできないが正常な送信者をリストアップ (特には必要ないが念のため)
white.client.com    OK

[grey_clients]
# 逆引きできないクライアントは greylist 入り
unknown   grey
myself, my_user, white_clients, grey_clients は postmap コマンドで hash データベースを作成しておきます。 (Postfix Standard Configuration Examples を参照してください。)

この設定 (greylisting を除く部分)で 数 % 位のスパムを阻止しています。 スパム対策としてはあまり効果はないのですが、MTA の設定をきちんとチェックすることはいいことだと思います。

4. greylisting の導入

greylisting とは怪しげなクライアントには再送を要求する処理です。 正常な MTA は再送してくるので、そこで初めて受け付けます。また、きちんと再送してきたクライアントは一定期間 white list に載せて、再送要求をしません。 ほとんどのスパマーは再送しないので、スパム排除には大きな効果があります。また、正常なメールを失ってしまう危険性もほとんどありません。 (逆引きもできないし、再送もしてこないのは正常とはいえないと考えます。)

全面的に導入すると、メールの受信が遅れるので、逆引きができないクライアントからのメールだけを greylisting にかけました。 ちなみに、逆引きできないとき無条件に拒否するのは相当危険です。(例えば、ここ を見てください。)

greylisting サーバーとして postgrey を導入しました。 インストールと設定は

などを参考にしました。 greylisting はそれなりに効果があり、約 50 % のスパムを阻止します。

5. Subject による振り分け

bogofilter をすり抜けてきたスパムを Subject でさらにふるいに掛けます。 スパムメールの Subject には特徴的な文字や単語が含まれているので、単純な方法ですが、それなりの効果があります。

以前紹介した Subject でメールを振り分けるスクリプトの input file に 以下の条件を追加しました。

前略
X-Bogosity: Unsure
Received: unknown
folder:INBOX.Junk0

X-Bogosity: Unsure
Subject: [!?☆★♪※○◎●裸馬女性肉欲援交稼妻裏払\!\?]|無料|セックス|sex|セフレ|出会|刺激|写真|美人|あなた|貴方|報酬|謝礼|メアド|堪能|(届|とど)いています|だけ|ただ|必見|不倫|浮気|簡単|真剣
folder:INBOX.Junk0
後略
これらの条件は
  1. bogofilter で Unsure と判定され、送信元の逆引きができないメールはスパム一時保管フォルダへ
  2. bogofilter で Unsure と判定され、タイトルにいかがわしい単語や漢字を含むメールはスパム一時保管フォルダへ
という意味です。 この処理で、約 70% のスパムをブロックできます。

6. メールアドレスの難読化

紫藤は今まで無邪気にもホームページで自分のメールアドレスをそのまま晒していましたが、 今回、メールアドレスを文字参照表記にすることによって受け取るスパムメールが激減しました。 具体的には、いままで
"takafumi@shido.info"
と書いていたのを
"takafumi@shido.info"
と書くように改めました。 この 難読化処理 によって、ブラウザを通してこのページを見る人間には正常なメールアドレスに見えますが、メールアドレス収集のためのクローラーにはメールアドレスに見えません。 画像や、全角文字を用いるよりスマートで効果も大きいので是非試してみてください。

すでに5年以上もメールアドレスを晒していたのですが、これによって、1日に受け取るスパムの数が約 1/3 に減少しました。

7. 終わりに

きちんと統計を取ったわけではないですが、 各ステップでスパムがすり抜ける確率はおおよそ以下のようになっています。
  1. メールアドレスの難読化にもかかわらず送られてくるスパムの割合: 0.3
  2. greylisting を透過するスパムの割合: 0.5
  3. bogofilter を透過するスパムの割合: 0.3
  4. Subject による判定を透過するスパムの割合: 0.3
これらの4つのフィルタをすり抜けてくるスパムは 1.4 % で、1日あたり 200 通のスパムが送られてくるとすると、 デフォルトのメールボックスに届くのは 3 通ほどになります。

個々のフィルタはそれほど効率のいいものではありませんが、それらを多段階にして用いると効果的になります。 全体としてスパムの阻止率はほぼ 99 % なので、満足いくものになっています。 また、正常なメールを喪失する可能性は無視しうるほど小さくなっています。 結論としては、複数の緩めのフィルターで多重処理すると、正常なメールを喪失するリスクがほとんどなく、 効率よくスパムを排除できることがわかったということです。
当たり前といえば、当たり前ですが、自分でやってみて実感できました。