ProcmailをPostfixのバーチャルドメインに設定

覚書です。
ところどころ省いています。
実践環境で使う場合はご注意ください。

特徴

  • Postfix
  • バーチャルドメイン
  • メールサーバ内で不要メールの削除

特定バージョンでの開発や動作確認など開発環境での用途を目的としています。

環境

実施日2019-10-31
サーバさくらのVPS 512
OSCentOS 5.11
cat /etc/redhat-release
CentOS release 5.11 (Final)
rpm -qa | grep centos-release
centos-release-notes-5.11-0
centos-release-5-11.el5.centos

メールサーバについて

このメールサーバは、さくらのVPS 512 で2010年10月から契約をしているVPSです。さくらインターネットのこちらのお知らせによると「さくらのVPS」が正式に新サービスとして始まったのが2010年9月1日。

ほぼサービス開始初期に契約しており、本日は2019年10月31日。
まる9年間利用し続けていることになります。
この間、目立ったトラブル、特にさくらインターネット側に責任のあるトラブルは記憶にありません。

現在のサーバ情報はこちら。
「さくらのVPS 512では? メモリ 1GB ? 」
はい、そうです。
契約当初は、メモリ512MB、HDD20GBのプランでした。記憶ではCPUも1コアだったような気がします。
細かいことは忘れましたが、SSDプランが出始めたころに料金はそのままアップデートしてくれる案内がありました。
ちょうどSSDプランが出始めたころなので、サービスプランでのバランスなんだと思います。

サーバの目的・用途

このメールサーバは弊社の受信専用サーバという位置づけです。
送信を伴う通常のメールは、G Suite のGmailを使っています。

各種サービスに会員登録をするのはこちらのメールを使います。
twitterとかfacebookとか、会員登録にメールアドレスが必要になりますが、こういのって会員登録をするときにだけ必要で、その後は広告とかいらないメールがバンバン送られてきますよね。それに自分から送信することはまずありません。
なので「受信専用」のメールで登録を行います。

弊社ではシステム開発をしている関係でメール送信プログラムを扱うことが多々あります。
例えば、Webページでよくみかけるお問い合わせフォーム。またはショッピングサイトのカートや決済。お問い合わせを送信すると、また、ネットショップで購入をするとメールが送られてくる経験があると思います。
これらシステムを開発するときには、に何度も何度もメールを送信して間違いや問題がないか入念にチェックします。
なので「受信専用」のメールで登録を行います。

システム開発繋がりでもう1つ。
というか割とメインなのが、自動処理の通知です。
専門的に書くとCRONのメールとか。
受信専用のメール宛に送信し、受信専用のメーラーでチェックします。
エラーとか異常があるときは、メインのGMailのほうに転送されるようにしています。

Procmailを設定する前の状態

上記のとおり9年もののメールサーバです。
そろそろ一新しようかなと思いつつまだまだどうしようかと悩むところです。

OS側のいろいろはともかくとして、メール部分については当時からほぼ変わりなくやってきたのですが、ここ最近ちょっと我慢ならない自体になってきたのでProcmailを設定することにしました。

なんで今さらかっていうと、当時は Procmail が難しくてよく分かんなかったのと、最近くらいまでは必要性がなかったからです。
※メーラーの振り分け機能で充分でした。

ということで、見ていきましょう。

※下記は本記事に関わりのある主要な個所の抜粋です。本記事を通して変更してく個所もありますが、ここでは変更する前の状態です。

cat /etc/redhat-release
CentOS release 5.11 (Final)
/usr/sbin/postconf | grep mail_version
mail_version = 2.3.3
milter_macro_v = $mail_name $mail_version
rpm -qa dovecot
dovecot-1.0.7-9.el5_11.4

/etc/postfix/main.cf

vi /etc/postfix/main.cf
# 次の3つともコメント
#mailbox_command = /some/where/procmail
#mailbox_command = /some/where/procmail -a "$EXTENSION"
#mailbox_command = /usr/bin/procmail

# バーチャルドメイン
local_transport = virtual
virtual_transport = virtual
virtual_alias_maps = hash:/etc/postfix/virtual
virtual_alias_domains = $virtual_alias_maps
virtual_mailbox_base = /home/user_mails
virtual_mailbox_domains = /etc/postfix/virtual_domains
virtual_mailbox_maps = hash:/etc/postfix/virtual_maps

# uidとgidを指定している
virtual_minimum_uid = 499
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

Procmailを有効化する

作業前の状態が分かったところでいよいよですね。
それでは、Procmailを有効化していきましょう。
手順はいくつかあるので順番に進めていきます。

※ちなみに設定を間違えると、その間に届いたメールが消えてしまうので注意です。具体例というか私の経験で言うとディレクトリのパーミッションを間違えていてProcmailからメールボックスにメールを書き込めない、けど、エラーと表示されない。みたいになって「なんで消えた?」と小一時間はまってしまいました。

Procmailのインストール

まずはProcmailがインストールされているか確認してみます。

which procmail
/usr/bin/procmail

インストールされていれば↑のようになります。
まだの場合は yum から入れます。

yum install procmail

/etc/procmailrc

まずはメール処理を書いていきます。

vi /etc/procmailrc
SHELL=/bin/bash

PATH=/usr/bin:/bin

DROPPRIVS=yes

# user_mails はバーチャルドメインの設定次第で異なるかも
MAILDIR=/home/user_mails/$DOMAIN/$USER/Maildir

DEFAULT=$MAILDIR/

# ロックファイル
LOCKFILE=/home/user_mails/.procmail.lock

# ログ出力先
LOGFILE=/home/user_mails/.procmail.log

# 詳細ログ出力
VERBOSE=OFF

# 未承諾広告メール削除
:0
* ^Subject:.*iso-2022-jp
* ^Subject:\/.*
* ? echo "$MATCH" | nkf -mwZ2 | sed 's/[[:space:]]//g' | egrep '未承諾広告※'
/dev/null

# (例)どこかのテストサーバの会員情報に設定したメール
:0
* ^To.*test-dammyuser-[0-9]+@example.com
/dev/null

# (例)どこかのテストサーバのCRONに設定されたメール
:0
*^Subject:.+Cron <example@example> .*
/dev/null

今の時代「未承諾広告」の設定はいらないんじゃないかと思いますがなんとなく。

28行目からはサンプルです。
書き方が特殊で最初みたときなんこれですが、「:0」から 「:0」 までが1つの設定です。36行目の次の 「:0」 は不要です。
この設定のことを「レシピ」と呼びます。

とりあえずは、1~25行目までコピペしておけば良いと思います。
自分なりの条件設定は全部動くところまで出来てからが良いです。

/etc/postfix/master.cf

次は master.cf です。
最終行に追加します。

vi /etc/postfix/master.cf
procmail  unix  -       n       n       -       -       pipe
  flags=R user=vmailuser argv=/usr/bin/procmail -t -m USER=${user} DOMAIN=${nexthop} /etc/procmailrc

ユーザー名には「vmailuser」を指定しています。
このタイミングではまだ vmailuser は作られていない前提で進めます。

/etc/postfix/main.cf

次は main.cf です。

vi /etc/postfix/main.cf
# 3つともコメントのままにする
#mailbox_command = /some/where/procmail
#mailbox_command = /some/where/procmail -a "$EXTENSION"
#mailbox_command = /usr/bin/procmail

~~~ 途中省略 ~~~

# バーチャルドメイン
local_transport = virtual

# virtual_transport = virtual
virtual_transport = procmail

virtual_alias_maps = hash:/etc/postfix/virtual
virtual_alias_domains = $virtual_alias_maps
virtual_mailbox_base = /home/user_mails
virtual_mailbox_domains = /etc/postfix/virtual_domains
virtual_mailbox_maps = hash:/etc/postfix/virtual_maps

# uidとgidを指定している
virtual_minimum_uid = 499
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

バーチャルドメインを使っているので mailbox_command の設定は使われません。なので mailbox_command はコメントのままでOKです。

代わりに、virtual_transport = procmail に変えます。

virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
の指定があるので、uid と gid が5000のLinuxのユーザーが必要です。

ということで、main.cf で書き換えが必要なのは上記 11 ~ 12 行目の virtual_transport を procmail にするところです。

vmailuser ユーザーの作成

「vmailuser」ではなく名前はなんでも良いですが変える場合は master.cf など他の個所も統一します。

まずは 5000 のユーザーが作られていないことを確認します。

cat /etc/group | grep 5000

何もでてこなければ作られていません。
作りましょう。

groupadd -g 5000 vmailuser
useradd -u 5000 -g vmailuser -s /sbin/nologin vmailuser

ログのローテーション

procmail のログのローテーションを設定します。

vi /etc/logrotate.d/procmail
/home/user_mails/.procmail.log {
    missingok
    nocreate
    notifempty
}

Postfixの再起動

/etc/rc.d/init.d/postfix restart

Postfixを再起動すると設定が反映されます。

適当にメールを送信

設定が適切にできたか確認していきましょう。

現在 /etc/procmailrc には「未承諾広告※」の設定がされていると思います。

いつも使っているメールソフトを起動し、新規でメールを2通作成します。

一通目のメールタイトルには「未承諾広告※」から始まる内容を入れてください。
二通目のメールタイトルには「未承諾広告※」を含まない内容とします。

メールを送信してみて、一通目のメールが受信できず消え去り、二通目のメールが受信できれば成功です。

これでうまくいけば、完了です。
/etc/procmailrc に独自の条件を追加していきましょう。

うまくいかなかったとき

maillogを見る

処理の流れとして、サーバがメールを受け取るとまず Postfix が受け取ります。
それを procmail に渡し、 /etc/procmailrc の条件にマッチすればその通りに処理を行い、マッチしなければ本来入るべき Mailbox に格納される仕組みです。

ということで、maillog を見ていきます。

tail -n 100 /var/log/maillog
status=sent (delivered via procmail service)

Postfix から Procmail にうまくメールが渡されていれば上記のようなログが見えると思います。この行のスグ上か手前には宛先のメールアドレスが書かれていると思います。

(unknown mail transport error)

こちらのようなログが出ていれば、Postfix から Procmail にうまく渡せていないことを示します。
master.cf に追記したユーザー、そのユーザーの gid・uid あたりが怪しい気がします。

Procmailのログを見る

maillog を見て、Procmail に渡せていることが確認できたら次はProcMailのログを見ていきましょう。

Procmailのログは簡易版と詳細版があります。

vi /etc/procmailrc
VERBOSE=ON  # 詳細
VERBOSE=OFF # 簡易

普段は OFF にしておいて、調査するときだけ ON にしたら良いと思います。

ログの設定ができたらメールを送信してログがどうなるか確認してみましょう。

メールを送信したらログを見てみます。

tail -n 100 /home/user_mails/.procmail.log

条件に一致していたら「Match on」が見えます。
条件に一致しない場合は「No match」が見えます。

メールが消える

ログを見る限りうまくいっているように見えるけど、Procmailの条件に引っかからないはずのメールが受信できない、消えてなくなる、という場合がごく稀にあります。

master.cf で 5000 でないユーザーを指定したときとかですね。

Procmailが効かない、反映しない

バーチャルドメインを使っているなら、mailbox_command ではなく virtual_transport = procmail です。

以上、私がハマったあたりを中心に記してみました。