sendmail による「!広告!」フィルタ

 SPAM 業者保護法案ともいうべき法案が可決したのはご存知のことと思います。 この中で、Subject: に「!広告!」と記述することが求められています。 sendmail でのこれに対するフィルタを作ってみました。

 当初、regex map を用いて MIME 展開前のパターンを設定するという戦略で作業を開始しました。 あれこれ思考錯誤した末に、いくつかの MIME なパターンを加えて、

LOCAL_CONFIG
Kadsign regex -a@MATCH -f (B\!\*9-9p\!\*|^=\?[Ii][Ss][Oo]-2022-[Jj][Pp]\?B\?(GyRCISo5LTlwIS|IRskQjktOXAbKEIh|GyRCISobKEI=\?=\.=\?[Ii][Ss][Oo]-2022-[Jj][Pp]\?B\?GyRCOS05cBsoQg==\?=\.=\?[Ii][Ss][Oo]-2022-[Jj][Pp]\?B\?GyRCISobKEI=\?=))

LOCAL_RULESETS
HSubject: $>CheckSubject

SCheckSubject
R$*			$: $(adsign $1 $)
R@MATCH			$#discard $: discard
のようにしてみました。 (TEXT 版)

 しかし、上記ではまだまだ不十分で、 MIME な組み合わせは valid なのだけを考えても膨大になるので、 結局、ちょっと重くなってしまいますが、 Perl で MIME をデコードしてからマッチングをおこなうスクリプトを書いて、 program map を使って呼び出すようにしました。 .mc は以下のようになります。 (TEXT 版)

LOCAL_CONFIG
Kadsign program /usr/local/libexec/adfilter

LOCAL_RULESETS
HSubject: $>CheckSubject

SCheckSubject
R$*			$: $(adsign $1 $)
R@MATCH			$#discard $: discard
 呼び出される Perl スクリプトは以下のようになります。 (TEXT 版)
#!/usr/bin/perl

use Jcode;
use strict;

my $str = $ARGV[0];

my $s = $str;
$s =~ s/(=\?=)\.(=\?ISO-2022-JP\?B\?)/$1 $2/igo;

my $jconv = new Jcode($s);
$str = '@MATCH' if ( $jconv->mime_decode =~ /^(!|!)広告(!|!)/o );
print "$str";
exit 0;
 adfilter を /usr/local/libexec/adfilter にインストールし、使用してください。 この Perl スクリプトには日本語が含まれます。 EUC で保存して使用する必要がありますので注意してください。
 .mc ファイルに adfilter を呼び出すように定義 を追加して、sendmail.cf を作り直すことで使用できるようになります。
 なお、MIME 解析には Jcode.pm を使用していますので、 インストールされている必要があります。 Jcode.pm は FreeBSD では ports/packages になっており、 ports/japanese/p5-Jcode からインストールできます。
 Jcode.pm は内部的に MIME::Base64 を呼び出しますので、 MIME::Base64 もインストールされている必要があります。 ports から Jcode.pm をインストールすれば依存により MIME::Base64 もインストールされるはずですが、 インストールされなかったという報告もありますので、 もしインストールされないようなら、 ports/converters/p5-MIME-Base64 をインストールしてください。

 先の例に適宜パターンを追加していくか、ちょっと重くても我慢するか、 好みに応じて使い分けると良いかもしれません。
 また、このフィルタはまだまだ不完全だと思いますので、 それなりのものだと理解の上ご使用ください。
 そもそも、所詮「人間が」見て確認するための方法を提示しただけで、 機械的に処理するにはあまりに曖昧な規則です。 それに、広告メールには「!広告!」という記述があると決めただけであり、 「!広告!」と記述されたメールは広告メールであると 定義されたわけでは決してありません。 おそらく、今後、抜け道を突いた記述が出てくるものと予想されます。

 「!」、「広」、「告」、「!」の間に空白があっても SPAM と見倣すべきではないかという意見を頂きました。 空白があっても discard したい方は、パターンを

/^\s*(!|!)\s*広\s*告\s*(!|!)/o
に変えると良いかもしれません。

 なお、このようなフィルタを使用する際、 決して reject するようにしてはいけません。 SPAM は From: あるいは envelope from を偽称しているケースが多いので、 エラーメールが発信元に返るなんてことは期待できませんので。


All Rights Reserved, Copyright (C) 2002 Hajimu UMEMOTO
Last Modified Jan 15, 2002
ume@mahoroba.org