昔, netnews に何度か投稿したせいか こちらにメールアドレスを飾ってるせいか 毎日多くのスパムメールが届きます. 本当うんざりきます.
POPFile などを使い, メールを受け取る時点でスパムか否か判断し振り分けるのが世の主流のようですが, 時折 LinuxZaurus を使って外でメールを取る受け取ることもある手前, できたらプロバイダのメールサーバ (POP サーバ) からスパムを抹消したいものです.
プロバイダから取ってスパムを除いたメールを自宅で立てた専用の POP/IMAP サーバを建てて公開するという手もありますが, セキュリティの観点から あまりそのように外部にサービスを公開したくありません.
適当な間隔で POP サーバからヘッダだけ取って, 適当なルールでスパムか否か判断し, スパムだったら消すことができればいいのです. 例によってこんなツールあるはずだと思って検索してみたのですが, Windows 用のもの (SpamMailKiller ) は見つかったのですが UNIX 用のが見当たりません. Linux なら自宅で LANDISK (NAS として売られているが, 実は sh4 で動く Linux サーバ) が 24 時間動いているで, そいつにやらしたいと考えました (LANDISK による実現はこちらや, こちらを参照して下さい).
という訳で, そんな難しくなかんべということで作ってしまいました (まぁ実際は「あの機能も欲しい, この機能も欲しい」とどんどん深みにはまって 苦労しましたが...).
目的を達成するためには, Perl なり C のソースにベタでスパム判定ルールを書き, ルールを変えたい場合はソースを書き換えるという手もあったのですが, なんか美しくありません. という訳で, もっと汎用的にホームディレクトリにルールファイルを書き, それを読んで実行するという UNIX 流なものを作りました.
ソース一式はこちらです (V0.02). メイクして出来た実行ファイルを必要に応じ適当な所にコピーしてください. メイクには GNU Rx が必要です (どうしても入手できなかった場合は MakeFile の LIB と DEF の 定義を消してください. その場合ルールの記述に正規表現が使えなくなります).
SpamMailEraser は ~/.spamrule ファイルに記述されたルールに基づき, サーバからメールを消すか否か判定します. 通常は -e をつけて実行します.
と言ってもいきなり実行すると, ルールの記述間違いなどで大切なメールを消して しまう恐れがありますから, 以下のようなテスト用のオプションを用意しています.
ヘッダが書かれたファイルを開き, それが削除対象か否かを調べ表示します.
実際にサーバにアクセスし, ヘッダを取得して削除対象か否か調べ表示します. 実際に削除はしません.
実際にサーバにアクセスし, ヘッダを取得して削除対象か否か調べ削除対象だと 実際に削除します. -e と似てますが結果を標準出力に出してます. ログが必要だと思う方はこのオプションをお使いください.
スクリプトファイル (.spamrule) の書式は以下の通りです.
APOP HOST POP3 サーバ ID POP ユーザ名 PASS POP パスワード Command ルール |
ルールの書式は以下の通りです.
[ヘッダ]行の中に [パターン] が含まれていたら[変数]を TRUE に, 無ければ FALSE にします. ヘッダ行が無い場合は FALSE です. 変数には英数字とハイフンとアンダーバしか使えません. ヘッダは : で終わっている必要があります. 頭に $ が付いていたら MIME デコードします (ISO2022JP のみ). GNU Rx のバグか私の使い方が悪いのかどうも日本語では正規表現がうまく動かないので, MIME デコードの際は正規表現は無効にしています. また, _: を指定するとは全ヘッダになります. なお, [パターン]に日本語を入れる場合は EUC コードで書いてください.
GNU Rx を入れてコンパイルした場合, [パターン]に正規表現が使えます. 正規表現のルールは GNU Rx を参照してください.
GNU Rx を入れてない場合に備え, [パターン]文字の先頭に \ を入れると 拡張命令になります. そのため \ で始まる文字列をパターンにしたい場合は \\ とエスケープする必要があります. 拡張命令は以下の通りです.
8bit コードがある場合 TRUE
大文字小文字を区別せずに比較
そのヘッダ行が存在していれば TRUE
例 |
SET A Content-Type: \nocase text/html |
SET A X-Mailer: Microsoft Outlook Express |
SET A $Subject: 未承諾広告※ |
[計算式]を計算し, その結果を[変数]に入れます. [計算式]で使える演算子は & (AND), | (OR) 及び ! (NOT) だけです. & と | はどちらを先に計算するか分かりません. 括弧 () を使って順番を指定してください.
例 | LET D (A & B) | !C |
もし[変数]が TRUE ならばメールを削除します. 以降の行の判定は実行しません.
もし[変数]が TRUE ならばメールを削除しません. 以降の行の判定は実行しません.
[文字列] を標準出力に出力します. デバッグ用.
その行が実行された時点で設定された全変数を表示します. デバッグ用.
なお, 記述ミスがある場合はその時点で処理を中断し終了します. エラーチェックはルールファイルを読み込む時点と実行時に行っています. 読み込み時のエラーチェックは命令が上に挙げたものかどうかや パラメータの数が正しいかを調べてます. 一方 LET 文や REJECTIF/ACCEPTIF 文などは, その時点で変数を探し, TRUE/FALSE を調べてますので, 探すのに失敗するとエラーになります.
あっそうそう, 一行は 1020 文字以内で書いてください.
以下はあくまで例です. EUC で保存することを忘れずに.
APOP HOST Your.pop.server.net ID hogehoge PASS ****** # はじまり Command # はじまり # ヘッダに 8bit を流すメール SET TMP _: \8bit REJECTIF TMP # html なんていらね SET TMP Content-Type: \nocase text/html REJECTIF TMP # 韓国語はよめましぇん SET TMP Content-Type: euc-kr REJECTIF TMP # [未承諾広告]は要りません SET TMP $Subject: 未承諾広告※ REJECTIF TMP |
正規表現を使うともっといいでしょう.