Maildrop

IMAPはサーバー上でフォルダを分けますが、メールの振り分けもサーバー上で行うのがMaildropです。別ページにて解説している bsfilter(スパムフィルター)と組み合わせることで、スパムメールの自動振り分けも行います。

インストール

インストール後、各ユーザーへのメールの配信がPostfixからMaildrop経由で行われるよう設定します。

  1. インストールします。(実際にはPostfixをインストールした時にすでに入れているはずですが。)
    # apt install maildrop
  2. グローバル設定は/etc/maildroprcにあり、設定内容も1つだけです。
    # Uncomment this line to make maildrop default to ~/Maildir for
    # delivery- this is where courier-imap (amongst others) will look.
    DEFAULT="$HOME/Maildir"
    これで、配送先に$DEFAULTを指定するとINBOXに入るようになります。
  3. /etc/postfix/main.cfにMaildropを指定し、Postfixからの配送は全ユーザーに対してMaildropで行うように します。
    mailbox_command = /usr/bin/maildrop
    PostfixのREADMEに書いてあるコマンドでは-dオプションを付けるよう書いてありますが、MaildropのREADME.Debian.gzでは 「不要」と書いてあります。
  4. Maildropのメール振り分けについては、各ユーザーで~/.mailfilterというファイルを作り、そこに設定することになります。なお、 振り分けのテスト中はどのような処理がメールにされたか確認するため、ログファイルを書きだしておくことをお勧めします。
    logfile "/home/xxx/maildrop.log"
    安定してきたらログの書き出しをやめるか、cronでローテートさせるなどすれば良いでしょう。

基本的なルールの書き方

フィルタリングルールについては、$ man maildropfilterで読むことができます。ま た、複雑なことをしようとする場合は、/usr/share/doc/maildrop/maildroptips.txt.gzを参照してください。(私の 書き方はとり あえず動くように、後から見て分かりやすくという方針ですので、省略形などもあまいり使っていませんし…。)
プログラミングをする方にとっては、「どっかで見たことあるような書き方」になっているようです。

注意

一番最後の行には、全てのメールを無条件に拾う設定を入れてください。そうしないと、どの条件にもひっかからなかったメールが消えてしまいます。

# Others
to "$DEFAULT"

振り分けの基本

例えばfacebookからのnotifyメールを特定のフォルダに振り分けるのは、下のようになります。

if ( /^X-Facebook-Notify/:h )
{
        to "$DEFAULT/.Facebook/"
}

複数条件

ToまたはCcが特定のアドレス宛の場合に振り分けるときは、(a|b)の形式で表現できます。

if ( /^(To|Cc):.*xxx@example.jp/:h )
{
        to "$DEFAULT/.hoge/"
}

ifの条件を複数にしたい場合は、||や&&が使えます。

if ( /^X-Spam-Flag: YES/:h \
|| /^Message-ID: <.\[20/:h )
{
        to "$DEFAULT/.spam/"
}

(参考)振り分けに使うヘッダの例

特定のnotifyメールやメーリングリストを振り分けることが多いかと思いますので、私が使っているヘッダを書いておきます。これらのヘッダと、下で説明 するSPAM判定だけでほとんど用は足りるでしょう。

/^From: xxx@example.com/:h
/^Reply-To: xxx@example.com/:h
送信元や返信先による振り分けです。可能であれば他のヘッダを使ったほうが信頼性が高いのですが、ない場合はこれで。
/^List-Id: xxxML.list.exmaple.jp/:h
/^X-mlcname: ml@list.example.com/:h
/^X-ML-Name: ml-name/:h
メーリングリストからのメールは、上記どれかのヘッダを持っていることが多いです。このヘッダを利用すると、メーリングリストに投稿しているにも関わらず投稿者本人とMLの両方に返信する人がいた場合、ML経由のメールだけ正確にピックアップできます。

bsfilterの組み込み

別途インストールしたbsfilterを組み込み、スパム判定結果を振り分けに利用します。とはいえ、maildrop側はxfilterという1行を追加 すれば使えます。

xfilter "bsfilter"

# SPAM filter
if ( /^X-Spam-Flag: YES/:h )
{
        to "$DEFAULT/.spam/"
}

これでメールが届くごとにbsfilterが呼び出され、判定結果がメールヘッダに追加されます。このメールヘッダを元に、spamフォルダへ振り分けま す。
先頭に書いておけば、まずはスパムが振り分けられるので、その他の振り分けルールにスパムが紛れ込んでしまうのを防止できます。
なお、bsfilterも誤判定することがありますので、spamフォルダをたまに見て学習させ直してください。

件名による振り分け

特定の文字列が件名に入ったメールの振り分けをする際、件名をデコードしないと一致判定ができません。ここでは、nkfを使って$SUBJECTにデコード した件名を入れることで、その後の振り分けに使えるようにします。
英語の件名であれば、普通に/^Subject: xxx/:hの設定で問題ありません。

# Subject decode
SUBJECT=`cat | nkf -mw | grep Subject`

# Subject
if ( $SUBJECT =~ /.*日本語での件名.*/ )
{
        to "$DEFAULT/.mailfolder/"
}

テスト方法

.mailfilterを修正した後は、必ずテストをしてください。文法の誤りがあった場合maildropはそこで停止し、メールをホールドしたままエ ラーが修正されるまで配信を止めてしまいます。

$ maildrop -V 9 </dev/null

デバッグ用のオプションをつけることで、正しくフィルタリングルールが解釈できるかが表示されます。syntax errorで止まった場合は、該当場所の記述を見直してください。

具体的に条件に合致するかどうかは、合致することが分かっているメールと合致しないことが分かっているメールをそれぞれ通し、振り分けが予定通りに動いてい るかmaildrop.logなどから確認してください。

$ maildrop <target_mail
$ maildrop <not_target_mail

設定例

例えば、こんな感じの設定になっています。

logfile "/home/xxx/maildrop.log"

xfilter "bsfilter"

# SPAM filtering
if ( /^X-Spam-Flag: YES/:h )
{
        to "$DEFAULT/.spam/"
}

# Subject decode
SUBJECT=`cat | nkf -mw | grep Subject`

# ML
if ( /^List-Id: xxx.list.example.jp/:h )
{
        to "$DEFAULT/.ML/"
}

# Subject
if ( /^From: example@example.com/:h \
&& $SUBJECT =~ /.*日本語で件名.*/ )
{
        to "$DEFAULT/.xxx/"
}

# Others
to "$DEFAULT"

目次へ戻る