The ULTIMATE spam Filter NNIPF(Nearest Neighbor IP address based mail Filter) Version 0.04-beta
★このドキュメントは,Linuxやメイルの配送システム等に詳しい上級者向けに書かれています.内容が理解できない場合は,詳しい人にインストールしてもらってください.素人によるインストールはおそらく不可能です.

[What's New] NNIPFのPerlの書き方がよろしくないという意見を各方面から頂戴しまして,ゆっくりですが書き直しつつあります.書き直しをしたことで動作の信頼性にどの程度の違いが出るかは分かりませんが,現バージョンは,ベータ版ということをご了承ください.0.03-betaから0.04-beta では下記の変更を施しています.

今後はリファレンスの使用,モジュール化,MTAOBの判断方法,全体のコードの見直し,複数ユーザに対応するために,マスターのBIP,GIPとユーザ毎のBIP,GIPに分離することなどを進めていく予定で,これらが済んだらbetaを取り除きます.いつになるやら.

利用者の声:(使っていない人の意見は割愛してます)

NNIPF とは ?
NNIPF は sendmail, postfix, qmail などのメイル配送エージェント(MTA)上でユーザ定義のフィルタとして動作するスパムメイルフィルタです.
  • 最近良く用いられるSMTP強制切断を行いRFC2821準拠でないものを落とす,あるいは,MTAの反応をわざと遅らせるSMTPターピットでスパムを受けないという対処法があります.しかし,この方法でも,一旦他のMTAで中継されたメイルは通り抜けます.また,最近は専用MTAからまっとうに送られてくるスパムも増えつつあるため,上記のチェックをしても約半数程度のスパムしか除去できないというのが現状です.
  • このため,各ユーザが設定可能なスパム検出フィルターは依然として必要ですが,メイルのボディーを見て識別するタイプのフィルターは誤検出/未検出のミスをします.ちなみに,高額で導入したBayesian型スパムフィルタによって,重要事務書類が紛失という事故もあちこちで起きています.また,「お姉ちゃんと一緒に帰る.」という子供のショートメイルが「お姉」というスパム確率の高い辞書エントリにマッチしてスパムに分類されるといった問題は,コンテンツ分析型のフィルタリングでは根本的な解決は極めて困難です.さらに,学習がいつどのように行なわれるのかがよく分からず,識別器をうまくトレーニングできないという方も多いと聞きます.
NNIPFが作られた背景は,以上の通りであり,基本的には誤りの少ないメールフィルタの実現ということが目標です.

誤りの少ないフィルタを作成するためには,メイルがスパムであるか否かを特徴付ける明確な特徴を見つける必要があります.NNIPFでは,我々が長年蓄積した100万通以上の大量のスパムデータを詳細に解析した結果,最も有効であると思われる「送信者の情報」を特徴として利用しております.これは,偽造されている可能性のあるメイルのヘッダー情報から,正しい送信者の情報を得るという問題を解決しなければなりません.このために,
「自分が外部からメイルを受けるときに使っている信頼できるMTA(Mail Transfer Agent)を登録しておき,そのMTAが生成したReceived:行から送信元のIPアドレスを割り出す」
という機能を実現しました.これにより,メイルヘッダーの偽造に対しても頑健な送信元アドレスの割り出しが実現できます.このときに登録する信頼できるMTAをNNIPFではMTA On the Border (MTAOB)と呼ぶことにします.

MTAOBは外部からのメイルを受け付けている信頼できるMTAであり,これによって受信されたメイルは決まった配送経路でBase MTAに送られます.MTAOBは,外部の野蛮な世界に面しているMTAであり,MTAOB上では送信元のIPアドレスを正確に把握できます.通常,メイルヘッダーに含まれる多数の"Received"フィールドにはIPアドレスが書かれていますが,それらは偽造されたものであるかもしれないし,また一部は見飽きたものばかりです.しかし,MTAOBの生成した"Received"行には,図1吹き出し内の赤字の部分に示したように送信者の正しいIPアドレスが含まれているので,これを利用してスパム検出を行うことができます.

当初はMTAOBの生成したReceived行に対して様々なルールを適用してスコアリングするといった小細工をやっていましたが,こういった人間の作ったルールよりもIPアドレスの識別の方が精度が高く,見通しが良かったため,次のような方式に切り替えました.
図1.MTAOBの概念図

次に問題となるのは,抽出されたIPアドレスが果たしてスパム送信者のアドレスか,そうではないのかを判断しなければなりません.一般にメイルの判別には,従来Bayesianフィルタや,Support Vector Machine, ADABoostingなどの識別器が用いられてきました.しかし,これらの手法は
  • P1)学習に時間がかかる.
  • P2)1回スパムや正常なメイルの学習データを与えただけでは再び同じ失敗をする可能性がある.
という欠点があるため,NNIPFでは最近傍識別器を用いています.
この手法は,「既知のスパム送信者のIPアドレス集合」,および「既知の正常なメイル送信者のIPアドレス集合」を事前に用意しておき,未知のメイルから抽出されたIPアドレスと,それぞれの集合との最短距離を計算し,より近い方に識別するという方式です.この方式の良さは,
  • S1)学習にほとんど時間を要しない.
  • S2)柔軟な識別面を構成でき,1つのデータを与えるだけで同じ間違いを繰り返さない.
という2点です.最近傍識別だけでは「スパムかNonスパムか」という二者択一的判断しか行なえませんが,NNIPFでは,最近傍識別理論に基づきながら,スパムらしさの指標となる「弁別度」という量を計算しております.
 具体的には,
  • Dspam:メイルのIPアドレスと,スパム送信者のIPアドレス集合の間の最短距離
  • Dnormal:メイルのIPアドレスと,通常のメイル送信者のIPアドレス集合との最短距離
とすると,
  • Dnormal/(Dspam+Dnormal)
が弁別度になります.これは,スパムと通常のメイルの生起確率密度分布をそれぞれ1/Dspam, 1/Dnormalとした場合の事後確率をBayes則で計算したのと同じ量になります.お暇な人は計算してみてください.
この量が0であれば,確実に普通のメイルであり,1であれば確実にスパムメイルで,その中間の0.5であれば,どちらとも言えないということになります.システムでは,弁別度の値が0〜0.35であれば正常,0.65〜1であればスパム,そしてそれ以外は不確かというような扱いができるように作ってあります.(0.35や0.65の値は調整できます.).現在登録しているスパム-IPアドレスは4千以上,Nonスパム-IPアドレスは千数百程度ですが,最近傍探索と弁別度の計算は一瞬で終わります.

では,これらを組み合わせて実現される「IPアドレスの最近傍識別」にどのような意味があるかという問題について考えてみます.もともと,IPアドレスは,国別,組織別,に割り振られており,勝手なIPアドレスを用いてもきちんと通信は行なえません.したがって,スパム送信者のIPアドレスが大学や政府機関とは異なるアドレスに分布していることは容易に想像ができます.実際に,この分布を調べてみたところ,かなり明白な分布の偏りが存在することを確認しております.ですから,この方式では,怪しいMTAから送られてくるメイルを全てブロックできます.その一方で,まっとうな組織から送られてくるスパムメイルは検出できないという限界もあります.これは,ウイルスやワームに感染した正当な組織のコンピュータがスパム送信にABUSE(不正利用)されたケースに相当しますが,これは現在のところ前述したターピットや強制切断などの様々な対策の結果,ユーザまで送り届けられるケースは少なくなっております.実際,半年間運用してみた限り作者はこういうケースに遭遇しておりません.

NNIPFのプラットフォームは,ユーザの使っているMTAであり,ユーザはそこからPOPやIMAPなどのプロトコルを用いてメイルをダウンロードしています. ここで,スパム検出が行われるということは,ユーザは自分のPCにスパムメイルをダウンロードすることはないということです.これは,出張先などで低速の通信回線でインターネットに接続されている場合などで特に有利に働く特徴です.

NNIPFは他のフィルタよりも精度およびスピードの点で優れていますが,人間の作ったソフトウエアは間違いを起こすものです.間違いを起こした場合,NNIPFはWEBインターフェイスを通じて誤りを修正し,フィルターを再トレーニングすることができます.これが行なえるためには,
  • MTA, POP/IMAPサーバ,WEBサーバの3つが動いている計算機
がプラットフォームとして必要になります.NNIPFは,このようにどこでも動くというわけではないので,これは1つの欠点と見なせます.(以降,NNIPFが動いている計算機のことを以降 Base MTAと呼びます.)

NNIPFは,スパムメイルとして検出したメイルを全て蓄積しており,それらはWEBを介して見ることができます.もし,ユーザが誤分類を発見した場合にはそれをWEB経由で修正することができるようになっています.これは,同時に識別器の再トレーニングにもなっており,この修正以降は同じ間違いは2度としません.

問題点など.
  • 現在のバージョンでは,IPアドレスのデータをディレクトリの階層構造を利用して蓄積しています.ですので,i-nodeを大量に消費します(小飼さんからの指摘).それだけではなくext3のファイルシステムでは数百MBのディスク領域を消費してしまいます(こじまさんに教えてもらいました).当面の解決策としては,B-treeベースで,i-nodeを動的に確保するXFS,JFS,ReiserFSなどのファイルシステムを利用することがお勧めです.これらでは,ディスクが空いている限りi-nodeの枯渇はなく,ext3に比べるとかなり少ないディスクスペースですみます.また,数百以上のユーザにこれをそのまま使わせると,大変なことになります.しかし,DBMなどのデータベースを用いた場合,データをメモリにロードしないで効率のよい最近傍探索が行えないという問題があるため,解決は容易ではありません.この問題の解決法については,鋭意検討中でありますが,良いアイデアがある方は教えてください.
  • botが正常なMTAを用いてスパムを送る場合,この方法では正常なMTAがスパム送信元として登録されるのではないかという意見があります.これは,昔はそうでしたがISPの努力によりこういったケースは非常に減っています.かなり遠慮気味に書けば,NNIPFは様々な方法で減らされた残りのスパムを取り除くという現代的な問題に対するする処方箋とも言えます.むろん,NNIPFだけでも高精度でSPAMがはじけます.
  • 作者は,どちらかというと本業が忙しいので,「使ってるよ」とか,暖かい言葉をかけてやらないと,そのうち放り投げる可能性が高いと思います.使用感について肯定的・否定的どちらでも構わないので,メールしてやるとバージョンアップのスピードが速くなります.

NNIPF.tgzの中身
説明 名前 中身
設定ファイルが置かれたディレクトリ(この下のファイルを書き直す必要があります.) CONF Boundary, conf.pl
説明文書が格納されるディレクトリ DOC README-j.txt, WEB-interface.html, README-j.html
.forward, .qmailなどの設定例が格納されたディレクト EXAMPLE dot.forward, dot.qmail, dot.htaccess
Perlのスクリプトの雛形とパッケージが格納されたディレクトリ(analyse.pl,header.plはここに置いておく必要あり) PERL analyze.pl chk.cgi filter.pl header.pl
いわゆる makefile Makefile


インストールの手順
順番 作業
1 ユーザのWEBページが格納される~/public_html以下でアーカイブされたファイルを展開してください.これによって"~/public_html/NNIPF" というディレクトリが作成される筈です.
2 下記の2つのURLからBIP.tgz, GIP.tgzをダウンロードし,NNIPFのディレクトリ内で展開し,BIP,GIPというディレクトリを作ります.
  http://vrl.sys.wakayama-u.ac.jp/~twada/BIP.tgz
  http://vrl.sys.wakayama-u.ac.jp/~twada/GIP.tgz
これらは,それぞれ BAD IP, GOOD IPのデータベースを表すディレクトリです.
2007年4月15日午前1時10分以降,BIPの内容を更新しました.以前のものは,過去約10年間で一度でもスパムを送信したことのあるMTAのアドレスになっておりました.したがって,最近ではスパムを送信していないocnとかyahooのアドレスも含まれており,初めてこれらのアドレスから受け取ったメイルがスパムと誤判定されることが報告されております.これに対処するため,過去半年以内にスパムを送ったアドレスに限定したBIPに変更しました.ディレクトリの大きさは1/4以下になり,おそらく上記の誤検出も少なくなるはずです.)これらのアドレスは,予告なく変更しますので,新しいかどうかはみなさんでチェックしてみてください.NNIPFのバージョンアップ時には常に更新されています.

ここまでの作業で,NNIPF直下には下記のディレクトリとファイルができている筈です.確認して下さい.
BIP/ CONF/ DOC/ EXAMPLE/ GIP/ Makefile PERL/
3 CONF/conf.pl を編集します.少なくとも$PERLはシステムにあわせて正確に書き直して下さい.また,$cgi_user, $cgi_passもCGIのユーザ名とパスワードを設定する重要なものですので,書き直して下さい.
4 NNIPF直下で make を実行します.これによって,./chk.cgi, ./filter.pl, というperl script, ~/Maildir/trashというディレクトリ, .htaccess, .htpasswdができます.chk.cgiはWeb interface用のCGI,filter.plはフィルタソフトの本体です.
5 先の make で,
  • ~/public_html/NNIPF/以下でchk.cgiが動作するWEBサーバの設定
  • chk.cgiを他人に悪用されないようにパスワードでガードすること
の2つは設定された筈ですが,確認を忘れないで下さい.
例えば Base MTAが,base.mta.ac.jpであり,あなたのアカウントがjimであった場合,http://base.mta.ac.jp/~jim/NNIPF/chk.cgiに,設定したユーザ名とパスワードでアクセスでき,エラーも出なければOKです.以降,このページからREADMEが読めるようになります.もし,CGIが動かなければWEBサーバの管理者に.htaccessの内容を見せて,尋ねてください.
6 ***ここは特に注意深く読んでください***
 "CONF/Boundary" というファイルにはMTAOBが記載されています. 繰り返しになりますが,MTAOBとは以下のような計算機を指します.
  • 外部のスパム送信ホストから直接メイルを受ける可能性のある組織内のホストで,Receivedの改竄を行なわない信頼できるホスト
  • メイリングリストのサーバなどで,直接スパムメイルを受ける可能性のあるホスト
  • メイルのフォワードサービスなどに用いている信頼できるホストで,直接スパムを受ける可能性があるホスト
しかし,あなたのあやふやな記憶でこのファイルを作らないで下さい.
最も良いのは,実際に受信したメイルの"Received"フィールドからあなたのMTAOBを見つけて抜き出すことです.
例えば,あなたの受信したメイルのヘッダーが以下のようなReceived行を含んでおり,
178.95.4.140を特徴ベクトルとして抽出すべきであるときには,
mgate.var.wakayama-u.ac.jp
を"Boundary"に追加します.これは,"by"直後のスペースで区切られた文字列です.
Received: from msr40.hxnet.net (msr40.hxnet.net [178.95.5.140])
by
mgate.var.wakayama-u.ac.jp (8.13.6/8.13.6) with ESMTP id l31C8n6J010000
for <foo@var.wakayama-u.ac.jp>; Sun, 1 Apr 2007 21:10:50 +0900

MTAOBが複数個ある場合は,複数行にそれらを書いてください.

また,似たような名前のMTAOBがある場合,
hormel[1-8].ieee.orgのように,正規表現を使うことができます.

MTAOBの詳しい決め方はこちらを参照してください.
7 "~/public_html/NNIPF/filter.pl" をあなたのMTAのフィルタとして設定してください.

Postfix と sendmailの場合: 下記の行を .forwardに書き込んでください.
| "~/public_html/NNIPF/filter.pl > /dev/null"
Qmailの場合:下記の行を .qmailに書き込んでください.
| ./public_html/NNIPF/filter.pl > /dev/null

filter.pl は受信したメイルがスパムと判定されなかった場合,受信したメイルの内容をそのまま標準出力に吐き出します.これは,携帯への転送など他のフィルタと連動させるための仕組みです.その場合には,以下のようになります.

.forward(Postfix & sendmail)の場合
| "~/public_html/NNIPF/filter.pl| some filter"
.qmail(Qmail)の場合
| ./public_html/NNIPF/filter.pl| some filter

EXAMPLEに設定の例がありますので,これを参考にして下さい.
8 テストメイルを自分に送り正しく受信できることを確認してください.(この段階ですでにメイルフィルタは動作しています.)もし受信できず,TRASHにも入っていない場合は,即座に使用を中止してください.この間に届いたメイルが消えてしまいます.
TRASHに入った場合は,Boundaryファイルの書き方がおかしいか,あなたのメールサーバがBIPに入っている可能性があります.WEBから確認してみてください.
9 しばらく放置しておき"~public_html/NNIPF/chk.cgi"に対応するWEBページを見に行ってください.もしあなたが頻繁にスパムメイルを受けるのなら,この内容が時々刻々変化するはずです.これは特に最初の頃は毎日見る必要があります.このWEBページの操作は,WEB-interface.htmlを参照してください.

うまく行けばこれだけで終わりです.

運用
検出率を上げ,誤検出率を下げるコツはとにかくBoundaryファイルを正しく書くことと,トレーニングをきちんと行なうことです.これをきちんと行なっておけば,このフィルタは殆ど間違わずにスパムをブロックします.
  • WEBページ上での操作方法に関しては,"WEB-interface.html"をご覧下さい.
  • Version0.02-betaから,BoundaryファイルをWebから修正できるようにしました.
  • NNIPFは,現在のところMaildir形式でメイルを蓄積するように設定した postfixとqmailで,popを使う場合に動作は確認しております.imapでも動作するはずですが,確認できておりません.


[無保証]
尚,このソフトウエアの使用により被った被害については,作者は一切責任を取りませんので,使用者側で問題が生じないかどうかを十分テストをした上で運用して下さい.

[著作権]
各プログラムをご覧下さい.

2007年4月6日公開,同日0.02beta,15日0.03beta,18日0.04betaに改訂
作者:
 和歌山大学 システム工学部 和田俊和(twada@ieee.org)

謝辞: 本プログラムは,平成17年度(H17-H18)和歌山大学「オンリー・ワン創成プロジェクト経費」の補助を受けて開発された.