[HOME] [github] [twitter] [blog] [fml4] [fml8] [北海道] Powered by NetBSD and [nuinui.net] .

フィルタ

レシピ’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. 上と同様に spamassassi を呼び出すのですが、 それを 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 では考慮しないことにしています。

[HOME] [github] [twitter] [blog] [fml4] [fml8] [北海道] Powered by NetBSD and [nuinui.net] .
Copyright (C) 1993-2022 Ken'ichi Fukamachi mail:< fukachan at fml.org >