「Spam」カテゴリーアーカイブ

Spam度合いによってメールを振り分ける(2)

前回はSpamassassinのスコアを元にスパム度合いを判定して真っ黒なスパムをはじく設定を行った。これはこれで大成功だったわけだが、スコアを数値としてではなく文字列で判定しているので、30以上とか20以上とかキリのいいスコアでの切り分けは楽だけど16以上などの中途半端なスコア以上の切り分けは面倒。正規表現で数値として判定させる方法なんてあるのかな?

どうもグレーなスパムや誤判定は0~15くらいのスコアに収まるみたいで、16とか17以上のスコアを判別したくなってきた。そこで少しググって見るとSpamassassinのスコアレベルを判定する方法を紹介しているサイトがあった。

なるほどなるほど。スパムレベルは「*」の数でスパムスコアが表されるので、ただ単純に「*」の数をマッチングさせればスパムスコアを判定できそうだ。:0H:
* ^X-Spam-Level: ¥*¥*¥*¥*¥*¥*¥*¥*¥*¥*¥*¥*¥*¥*¥*¥*+
* ^X-Spam-Flag: YES
$MAILDIR/.SpamX
これでスパムスコアが16以上のメールはSpamXフォルダに振り分けられるようになった。

これで少し様子を見ることにしよう。

Spam度合いによってメールを振り分ける

真っ黒なスパムはその存在を知る前に消し去りたい。Spamassassinのスコアで20以上であればまず間違いなくスパム。user.prefsをちょっといじっているから安全を見て、30以上のメールは瞬殺したい。と、まあ過激になる前に、真っ黒なスパムを試しにSpamXフォルダに振り分けてみることにした。

参考にしたのはこのページで、ここの「6.2. スパムの疑いの濃さに従って、振り分け」をSpamassassin用にカスタマイズしてみよう。

実はSpamassassin側でスパムメールのサブジェクトの先頭にはスコアを表示させるようにしている。よって、サブジェクトの先頭を見るだけでスパム度が分かるようにしてある。そのスコアをprocmailで判別すればいい。:0 HB
* ^Subject: *\/.*
{
:0
* $MATCH ?? [3-9][0-9]\\.
* ^X-Spam-Status: Yes
$MAILDIR/.SpamX/
}

これでしばらく運用してみて、SpamXのしきい値をもうちょっと下げてそれでも真っ黒なスパムだけだったら /dev/null してあげよう!

縦読み、キターーーー

こんな内容のスパムが届いた。which one is better than other Varrius
Instead
Ates
Gauge
Representations
Ates
Loyalty
Exploit
Varrius
Instead
Themthat
Representations
Ates
Commence
Instead
Ates
Loyalty
Instead
Silent
read about it here
またベイズ攪乱攻撃かと思ったら実はHTMLメールで、こんな内容だった。

2chじゃないんだから、縦読みするなって (-_-###

それにしても、いよいよきたな~。そうするとネ申とか火暴とかの英語バージョンなんかも現れるのかなぁ。乙、kwsk、wktkなんかもこれから出てくるのか??? スパマーたちよ、もういい加減にしないか?

Spam wordの出現回数で点数をつける(2)

Spam wordの出現回数で点数をつけるの続きで、full __SPAM_TALK /buy|sale|purchase|bargain|off|click/i
tflags __SPAM_TALK multiple
meta SPAM_TALK_MULTI __SPAM_TALK > 2
score SPAM_TALK_MULTI 2.0
みたいにすると、怪しい単語が羅列されているspamには良く効く。

けど、これは1行目の怪しい単語をうまく選ばないとhamに大きくspamスコアがつく原因となる。失敗したのは、学位取得系のspamに多い “class” を登録したとき。これって、普通のメールはいいけどHTMLメールには普通にtagの属性として使うので、一発で高得点をとってしまう。

よって、引っ掛ける単語を工夫して、”class=” となるときだけ除外するように “class[^=]” とするとか、他の単語に含まれる可能性の高い “test” なんかは “\btest\b” みたいにするといい。また、spamassassinの精神に則り、何かひとつのルールで一発アウトにするよりも、こつこつと地道に点数を築き上げたほうが誤判定が少ない。

とはいえ、ほんの数行だけわけ分からんspam wordとリンクだけ書いてあるものはDNSBL以外ではスコアのつけようもないなぁ。

Spam wordの出現回数で点数をつける

Spamassassinで怪しい単語(spam word)の出現回数で点数をつけられないかいろいろ試行錯誤したけど、metaとtflagsで何とかできそう。

例えば、スパムにありがちな$100などのUSドル表示が多いほどスパムっぽいとすると、~/.spamassassin/user_prefsにfull __US_DOLLAR_SINGLE /\$[0-9.,]{3,}/
tflags __US_DOLLAR_SINGLE multiple
meta US_DOLLAR_MULTI __US_DOLLAR_SINGLE > 2
score US_DOLLAR_MULTI 2.0
を追加してみる。

これは1行目にまず、メールのすべてにおいてドル金額が “$” に続けて数字、カンマ、小数点が3個以上続くものを “__US_DOLLAR_SINGLE” として定義している。ちなみに、ただ “$” または “$[0-9]” だけだとMIMEエンコードされた部分や日本語部分にやたらめったらヒットしまくる。そして定義名の前に “_”(アンダーバー、アンダースコア)が二つついているんだけど、これはルールとして定義しても得点としては計算しない定義に用いられる。得点に加算しないルールなんて作っても意味ないじゃん、と思うんだけど meta で使うんだな、これが。

2行目は “tflags” でルール定義のタイプを “multi” に設定している。 “multi” を設定すると、ルール(この場合は “__US_DOLLAR_SINGLE”)が合致するたびにヒットするようになる。これで、1行目の定義に “__” がなければドル金額表示があるだけヒットするようになる。これはこれで便利なんだけど、メールのヘッダーにヒットする回数だけ表示されてちょっとうざい。でも、ヒット数と得点を比例させたい場合はこれしか方法はないんじゃないかな。特に比例させる必要はなさそうだし、誤検出もちらほらあるからこのような設定はしていない。

3行目は “__US_DOLLAR_SINGLE” が2回より多く(3回以上)ヒットした場合に有効となるルール “US_DOLLAR_MULTI” を定義している。ここがミソで、”__US_DOLLAR_SINGLE” の検出回数で発動させることができる。ここは “2” を調整することで大体うちに届くスパムは、ドル金額が書いてある場合は3回以上は書かれている。

4行目は “US_DOLLAR_MULTI” に対するスコア。

ここで、1行目の定義を “/buy|sale|purchase|bargain|off|click/i” みたいによく届くスパムに多い怪しい単語を並べておくと、それらの出現頻度でスコアをつけるようにもできる。デフォルトのルールでは引っ掛けにくい学位取得スパムはこれでやっつけてる。

これでちょっと様子を見て、hamとspamの区別がはっきりしてきたらある程度のスコア以上のメールはばっさりと削除することにしようかな。

[12/18 update]大枠はこれでいいんだけど、これだとhamが誤検出されてしまうことが発覚! 改善策はSpam wordの出現回数で点数をつける(2)で!

メールタイトルにスパムスコアを表示する

一応スパムメールと判断されたメールにも目を通すようにしている。ほぼ100%SpamAssassinは間違いなくスパムをソートするんだけど、やはりまだ誤判定がある。英文のhamメールをspam判定してしまう。

ある程度誤判定は仕方ないにしろ、スパムにいちいち目を通すのも鬱陶しい。目を通すといっても一番の拠り所はスパムスコアで、これが10以下なら要チェック、それ以上ならばまず間違いなくスパムである。よって、10以上なら無条件に削除。。。 としてしまいたいところだけど、まだちょっと怖い。

よって、スパムスコアをメールのタイトルに表示することにした。これならメール一覧でスパムの度合いを素早く知ることができる。それにはSpamAssassinの設定を弄る必要があり、~/.spamassassin/user_prefsに以下の設定を追加する。rewrite_header Subject [ _SCORE_ ]これでスパム判定されたメールには [ xx.x ] がタイトルの頭に追加され、xx.x のスコアにさえ気をつければ良くなった。上記設定で、_SCORE(0)_ とすれば十の位が必ず表示されるようになり桁が揃うようになるけど、桁が揃わない方が10以下のものが目立つのであえて揃えていない。

SpamAssassinのハム学習

もともとスパムはすべて英語メールで、英語のハムメールは少なかったのでSpamAssassinのヒット率はほぼ100%。最近user_prefsをちょこちょこいじって、要注意単語を増やしたおかげでスコアも安定的にスパムは20点を越すようになってきた。20点以上は自動的に削除してもいいかもしれない。

でも、はじめて誤認識があった。いらないけど一方的に送りつけてくるVisualWareのNewsletterで、これは個人的にはスパムなんだけどやはりハムである。そこで、ハム学習を行ってみる。

元のメールはスパム判定メールに添付されているので、スパムとして誤認識されたハムメールをHamboxに移動したら、添付されている実際のメールを同じディレクトリに保存する。自分のアカウントでログインしていることを確認したら、
$ sa-learn --ham /[自分のメールディレクトリのフルパス]/.Hambox/cur/ --dirとコマンドラインで打ち込む。すると、Learned tokens from 1 message(s) (1 message(s) examined)と応答が返ってきて、無事学習された。

さて、誤判定はこのように手動で正しい判定に直していくことによってしか修正できないらしい。なので、こまめにハム学習、スパム学習を行っていくしかない。

SpamassassinにNGワードルールを追加

ほぼ100%スパムを弾けるようにまでチューニングされてきたspamassassin。それでも突破してくるものもあるけど、100%は土台無理な話だから。

にしても、viagraって書いてあるメールがそれに対してなんらスパム加点されていないのは、なんとも苛立たしい。と言うことで、思いっ切ってNGワードに対しては無条件で加点するルールを作ってみた。

でも、まずは独自ルールを作成できるように、/etc/spamassassin/local.cfに# ユーザー固有ルール設定を有効にする
allow_user_rules 1
を追加する。

そして、/home/ユーザ名/.spamassassin/user_prefsに# とにかく以下の文字列があれば加点する。
body NG_WORD /viagra|cialis|tramadol/i
describe NG_WORD Contains NG word
score NG_WORD 3.0
を追加する。

3点は厳しいかもしれないけど、これでhamが増えてきたら少し減点しよう。

X-Spam: Not Detected

最近妙にX-Spam: Not DetectedなるヘッダーがついたメールがSpamassassinを通過してくる。どうも、SAを素通りしているようで、他にSAヘッダーが見当たらない。

へんだなぁ、と思ってぐぐってみると、スパムメール自体に上記ヘッダーが最初からついてて、.procmailrcの:0fwi
* !^X-Spam.*
|/usr/bin/spamc
の条件文(赤字)の条件が満たされずにSAを通らないことが判明。スパマーのやろーども、賢いな。

この条件は、「一度他のプロセスでSAがスパム判定されているものにはX-Spamヘッダーがついてるはずだから、二度目はしない」、というもの。それを逆手にとられてしまったので、今度は無条件にSAを通すことにした。そしてダメ押しで、このような小賢しいヘッダーをつけてくるメールは無条件にSpamフォルダにフィルタすることにした。まあ、この手の小賢しいヘッダーは数種類あるらしいから、これ以上、このヘッダーにこだわることはやめよう。

ちなみに、改変後の.procmailrc(の該当部分)は、:0fwi
|/usr/bin/spamc

:0:
* ^X-Spam-Status: Yes
$MAILDIR/.Spam/

:0:
* ^X-Spam: Not Detected
$MAILDIR/.Spam/

:0:
* ^X-Spam-Level: 0
$MAILDIR/.Spam/
こんな感じ。

SpamAssassinの学習効果が現れる?!

これまで一回もスパム検出されなかったスパムメールを初めてスパム抽出することに成功!!

そのスパムメールは件名に「Re: 蜿ょ刈縺励∪縺励◆」と付く〇イアグラとか〇アリスとか言う薬を売り付けようとする良くあるスパム。でも、なぜかこいつだけ取りこぼしていた。件名がめちゃくちゃだからか?

27通(上記スパムの類は16通)しか学習させてないんだけど、もう学習効果がでたのかな。それともまぐれ? もう少し様子を見よう。ちなみに最近はスパムが来るとわくわくするような気がする。