CORESERVERのメールフィルタ

CORESERVERのサーバーに付与されるメールアカウントで、カスタムフィルタ同様、特定のドメインから送付されたメールを削除する。

前エントリの電波時計が決着しないまま、またも公私とも多忙となり、月日は無情に過ぎ去っていった。月日の代わりにやってきたものは、日本海対岸からのスパムメールの嵐である。題名・本文とも、とんと皆目つかない、いわゆる「とんとかいも」である(嘘)。明鏡止水の心境で捨て置く、というにはあまりに数が多すぎる。なにせ1通/分だから。

お陰様でこのブログの『CORESERVERのメール設定』は人気があるようで、ひとつこれに乗じてメールネタを増やしてみようと思った。まず試したのは、CORESERVERコントロールパネルの「ドメインメール」→「カスタムフィルタ」からの設定である。ウェブ上にもいくつかの情報があった。ところが、これはサーバ受信時に働くものではないようである。そこで、カスタマサポートにそれとなくprocmailが使えないか問い合わせたところ、以下の回答を得た。

誠に恐縮ですが、サーバーに付与されるメールアカウントにつきましては
カスタムフィルタ機能を有しておりません。

メールソフトなどの機能を用いて、制限いただきますよう
お願い申しあげます。

その間、30分程度。5つ星を付けて問い合わせをクローズにした。さすがCORESERVER、こうこなくっちゃ。簡にして潔、かつ高速。Simple is best。ggrks(いや、出てこなかったんだけど)。しかし、となると、自分で何とかしなければならない。

Perlのバージョンアップ

前置きが長くなりすぎた。使い慣れたPerlでIMAPクライアントを作り、特定のメールを削除することにする。当m40サーバのPerlは本記事作成時点で5.8系なので、まずはperlbrewで次期仕様の5.16系まであげておく。また、cpanminusをインストールし、クライアントモジュールNet::IMAP::Clientもインストールする。

$ curl -L http://install.perlbrew.pl | bash
$ source ~/perl5/perlbrew/etc/bashrc
$ perlbrew --notest install perl-5.16.3
$ perlbrew switch perl-5.16.3
$ perlbrew install-cpanm
$ cpanm -f Net::IMAP::Client

IMAPクライアントの動作確認

使用するスクリプトは以下のとおり。送信元の正規表現が$TARGET_PATTERNと一致したら削除、というごく簡単なものである(しれっと送信先をさらしておく)。このサイトの場合、firewheel<ユーザ名>m40<サーバ番号>に相当する。アップグレード済みのサーバではIMAPサーバ(server)が異なっているので、ご注意を。

#!/usr/bin/env perl
use 5.12.0;
use warnings;

use Net::IMAP::Client;

my $FOLDER_TO_SEARCH =  q{INBOX};
my $TARGET_PATTERN   = qr{qq[.]com \z}imsx;

my $client = Net::IMAP::Client->new(
    server          => '<サーバ番号>-coreserver-jp.value-domain.com',
    user            => '<ユーザ名>@<サーバ番号>.coreserver.jp',
    pass            => '<パスワード>',
    ssl             => 1, ## use SSL
    ssl_verify_peer => 0, ## don't use CA
    port            => 993,
) or die "failed to connect to the server.\n";
$client->login()
  or die "failed to login to the server.\n"
         . $client->last_error() . "\n";
$client->select($FOLDER_TO_SEARCH)
  or die "failed to select the folder.\n"
         . $client->last_error() . "\n";
my $message_ids_ref = $client->search('ALL', '^DATE', 'iso-8859-1')
  or die "failed to fetch messages.\n"
         . $client->last_error() . "\n";

process($client, $message_ids_ref);

$client->logout();

sub process {
    my ($client, $message_ids_ref) = @_;

    MESSAGE:
    for my $message_id (@$message_ids_ref) {
        my $summary_ref = $client->get_summaries($message_id);
        next MESSAGE
          if !defined $summary_ref || scalar @$summary_ref == 0;

        my $addresses_ref = $summary_ref->[0]{'from'};
        next MESSAGE
          if !defined $addresses_ref || scalar @$addresses_ref == 0;

        my $host = $addresses_ref->[0]{'host'};

        if ($host =~ $TARGET_PATTERN) {
            $client->delete_message($message_id);
        }
    }

    $client->expunge();

    return;
}
__END__

これを下記のようにして目的どおりメールが削除されることを確認する。

$ vi ~/bin/mail_processor.pl
$ chmod u+x ~/bin/mail_processor.pl
$ ~/bin/mail_processor.pl

一定時間ごとの自動作動

上記でスクリプトの動作確認が取れたら、一定時間ごとに自動的に作動させる。そう、cron。まず、"As a Futurist…"さんのポストを参考に、以下のシェルスクリプトを作成する。これを経由しないと、システムデフォルトの5.8系が使用されてしまう。

#!/bin/sh
export HOME=/virtual/<ユーザ名>
export BREWPERL=5.16.3

source ~/perl5/perlbrew/etc/bashrc
perlbrew use "perl-$BREWPERL"

exec "$@"

念のため、このスクリプト経由でもメールが削除することを再確認する。

$ vi ~/bin/env
$ chmod u+x ~/bin/env
$ /virtual/<ユーザ名>/bin/env perl /virtual/<ユーザ名>/bin/mail_processor.pl >/dev/null 2>&1

再確認後、CORESERVERコントロールパネルの「CRONジョブ」で毎xx分に、つまり1時間ごとに上記コマンドが実行されるようにすればよい。

本記事作成後、念のためメールボックスを覗いたら嵐は過ぎ去った後のようであった。何たることか。

コメントをどうぞ