Chapter 21. フィルタ

レシピ’s

1. フィルタシステムを使わない独自のフィルタを設定したい
2. 特定のメールアドレスを拒否したい
3. message/partial をフィルタしたい。
4. 危ない添付ファイルがついてきたメールは拒否する HOOK
5. フィルタで弾いた時に、エラーメールをどこへ返す
6. spamassassin で SPAM メールを無視する。
7. spamassassin で SPAM メールと判定したら、 ヘッダに X-Spam-Status: Yes をつける。
8. SPAM 対策として、To: および Cc: に ML 名を必須としたい
9. ML独自の Message-ID: をつけて矯正したい

1. フィルタシステムを使わない独自のフィルタを設定したい

fml8 のフィルタシステムで利用可能なフィルタは

/usr/local/etc/fml//defaults/$VERSION/default_config.cf.ja
を読むと分かります。

この内蔵フィルタで実装されていない内容のフィルタは article_post_verify_request_end_hook article_filter_start_hook article_filter_end_hook article_post_run_start_hook のいづれかの HOOK でおこなえばよいでしょう。

$article_filter_start_hook = q{
	my $header = $curproc->incoming_message_header();
	my $body   = $curproc->incoming_message_body();

	if (条件) {
		$curproc->policy_reject_this_message();
	}
};
のように書けば良いとおもいます。 フィルタの書き方についてはソースコード本体や、 以下のレシピも参照して下さい。

2. 特定のメールアドレスを拒否したい

たとえば特定のドメイン(\S+\@example.co.jp)は全部はじきたいといった フィルタのことです。 内蔵フィルタの一部として実装しようと考えていますが、 残念ながら未実装です _o_

3. message/partial をフィルタしたい。

mime component filter で「message/partial * reject」を設定して下さい。

[/usr/local/etc/fml/mime_component_filter]

# allow only text/plain messages.
message/partial *		reject
text/plain	*		permit
text/html	*		reject
multipart/*	!text/plain	reject

注意: このフィルタは全MLに反映されます。

4. 危ない添付ファイルがついてきたメールは拒否する HOOK

fml8 は、あらかじめ入力されたメッセージを解析し、メモリ上に鎖状の Mail::Message オブジェクトの形で持っています。そこで、MIME/Multipart の各部分のヘッダを取り出して、正規表現で順に確認すればよいだけです。

HOOK でなんとかする/ごまかす例は次の通りです。 どちらの例でも、マッチした場合、stop_this_process() 命令で、 それ以上の処理を止めています。 また、この例では何もエラーメッセージを返そうとしていないため、 結果として、このメッセージは無視されて終りになっています。

返事をしてあげたいなら、 reply_message() で、何か返事を返してあげてく ださい…が、たぶんウィルスとかなので返事をしないほうが良いでしょう。

.exe など特定のファイル拡張子にマッチするか?を調べる例。 昔の fml8 (2004/12/08 以前)なら、こんな感じ。

$distribute_verify_request_start_hook = q{
    my $msg = $curproc->incoming_message() || undef;
    for (my $m = $msg; $m ; $m = $m->{ next } ) {
	my $hs = $m->message_fields() || '';
	if ($hs =~ /filename=.*\.(com|vbs|vbe|wsh|wse|js|exe|doc|rtf)/o) {
	    $curproc->log("attachment \.$1 found");
	    $curproc->stop_this_process();
	}
    }
};
2004/12/08 以降の fml8 なら、こんなかんじ。
$distribute_verify_request_start_hook = q{
    my $msg  = $curproc->incoming_message() || undef;
    my $list = $msg->message_chain_as_array_ref();
    for my $m (@$list) {
	my $hs = $m->message_fields() || '';
	if ($hs =~ /filename=.*\.(com|vbs|vbe|wsh|wse|js|exe|doc|rtf)/o) {
	    $curproc->log("[new] attachment \.$1 found");
	    $curproc->stop_this_process();
	}
    }
};

別解としては、

Content-Disposition: attachment;
という表示になることを前提に、これを引っかけるという案もあります。
$distribute_verify_request_start_hook = q{
    my $msg = $curproc->incoming_message() || undef;
    for (my $m = $msg; $m ; $m = $m->{ next } ) {
	my $hs = $m->message_fields() || '';
	if ($hs =~ /Content-Disposition:.*attachment;/o) {
	    $curproc->log("attachment \.$1 found");
	    $curproc->stop_this_process();
	}
    }
};
2004/12/08 の fml8 以降なら、こんなかんじ。
$distribute_verify_request_start_hook = q{
    my $msg  = $curproc->incoming_message() || undef;
    my $list = $msg->message_chain_as_array_ref();
    for my $m (@$list) {
	my $hs = $m->message_fields() || '';
	if ($hs =~ /Content-Disposition:.*attachment;/o) {
	    $curproc->log("[new] attachment \.$1 found");
	    $curproc->stop_this_process();
	}
    }
};

5. フィルタで弾いた時に、エラーメールをどこへ返す

デフォルトでは

use_article_filter_reject_notice	=	yes
article_filter_reject_notice_recipient	=	maintainer sender
となっています。 つまり、 (1) エラーメールを返し(yes)、 (2) 返す先はMLの管理者と送信者の両方(maintainer sender) です。

返送する先を送信者( From: のアドレス )にするには

article_filter_reject_notice_recipient	=	sender
としてください。

MLの管理者と送信者( From: のアドレス )の両方に返すには

article_filter_reject_notice_recipient	=	maintainer sender
としてください。

そもそもエラーメールを返さないようにするには、

use_article_filter_reject_notice	=	no
としてください。

6. spamassassin で SPAM メールを無視する。

Caution

そもそも spamassassin をよびだす内蔵フィルタがあるのですが、 それをあえて使わない例です。

1. 内蔵フィルタの方の設定です。

use_article_spam_filter         =       yes
article_spam_filter_drivers     =       spamassassin

2. HOOK でなんとかする/ごまかす例は次の通りです。

$distribute_verify_request_end_hook = q{
        my $spamassassin = '/usr/pkg/bin/spamc -c';

        use FileHandle;
        my $wh  = new FileHandle "| $spamassassin";

        if (defined $wh) {
                $wh->autoflush(1);
                my $msg = $curproc->incoming_message();
                $msg->print($wh);
                $wh->close();
                if ($?) {
                        $curproc->log("spam: (code = $?)");
                        $curproc->stop_this_process();  
                }
        }
};

7. spamassassin で SPAM メールと判定したら、 ヘッダに X-Spam-Status: Yes をつける。

$distribute_verify_request_end_hook = q{
	my $spamassassin = '/usr/pkg/bin/spamc -c';

	use FileHandle;
	my $wh  = new FileHandle "| $spamassassin";

	if (defined $wh) {
		$wh->autoflush(1);
		my $msg = $curproc->incoming_message();
		$msg->print($wh);
		$wh->close();
		if ($?) {
			$curproc->log("spam: (code = $?)");
			my $hdr = $curproc->incoming_message_header();
			$hdr->add('X-Spam-Status', 'Yes');
		}
	}
};

ちょっとトリッキーですが、動きます。

8. SPAM 対策として、To: および Cc: に ML 名を必須としたい

HOOK で行なうなら次のようになります。

$article_filter_end_hook = q{
	my $header = $curproc->incoming_message_header();
	my $addr   = $config->{ article_post_address };
	my $to     = $header->get('To') || '';
	my $cc     = $header->get('Cc') || '';
	my $to_cc  = "$to, $cc";
	my $found  = 0;

	use Mail::Address;
	my (@addrlist) = Mail::Address->parse($to_cc);
	for my $a (@addrlist) {
		my $_addr = $a->address();
		if ($_addr =~ /^$addr$/i) {
			$found = 1;
		}	
	}

	if ($found) {
		$curproc->log("article_post_address found in header");
	}
	else {
		$curproc->log("article_post_address not found in header");
		$curproc->policy_reject_this_message();
	}
};

9. ML独自の Message-ID: をつけて矯正したい

未実装です。

HOOK でなんとかすることは出来ます。 「記事に ML 独自の Message-ID: をつけたい」というレシピを参照して下さい。

fml4 では「In-Reply-To: や References: をつけてくれない MUA があるた めにスレッドがうまく扱えない」という問題を解決するために、ML独自の Message-ID: をつけて矯正するという機能がありました。現代では、そういっ た MUA も死に絶えたでしょうから fml8 では考慮しないことにします。

fml 8.0 (fml-devel) project homepage is www.fml.org/software/fml8/.
fml 4.0 project homepage is www.fml.org/software/fml4/.
about one floppy bsd routers, see www.bsdrouter.org/.
other free softwares are found at www.fml.org/software/.

author's homepage is www.fml.org/home/fukachan/.
Also, visit nuinui's world :) at www.nuinui.net.

For questions about FML, e-mail <fml-bugs@fml.org>.