メールでデータ入力できるWebアプリなどを作るときに、非ユーザー宛のメールを受信して任意のプログラムに渡したいことがある。そのときのやり方。Postfixの正規表現によるエイリアス機能を使って実現する。
なお、このやり方だと私の環境ではユーザー宛(アカウントがあるユーザー宛)のメールがうまく受信できていない。
参考
main.cfの設定変更
まずは初期状態を確認する。
# postconf -d | grep ^local_recipient_maps local_recipient_maps = proxy:unix:passwd.byname $alias_maps # postconf -d | grep ^alias_maps alias_maps = hash:/etc/aliases # postconf -d | grep ^default_privs default_privs = nobody
local_recipient_mapsで、どこ宛のメールであるならば受け付けるのかを設定している。デフォルトは、@の前が、アカウントがあるユーザー名とエイリアスに登録されている文字列。 alias_mapsで@の前の文字列をチェックするためのデータベース(ファイル)を指定している。デフォルトは/etc/aliases。default_privsで、エイリアスにマッチしたメールを処理するためのコマンドの実行者を指定している。
この3つのパラメーターを変更する。
% cd /etc/postfix % sudo cp -p main.cf main.cf.org % vi main.cf
以下のようにパラメータを変更する。
# postconf | grep ^alias_maps alias_maps = hash:/etc/aliases, regexp:/etc/postfix/application.regexp # postconf | grep ^local_recipient_maps local_recipient_maps = # postconf | grep ^default_privs default_privs = 任意のユーザー名(新規ユーザを作るか、メールの処理プログラムのユーザにしておく)
正規表現によるエイリアスの記述場所である/etc/postfix/application.regexpを作成する。
% sudo touch application.regexp
postfixを再起動する。
% sudo postfix reload
受け入れメールアドレスの指定
/etc/postfix/application.regexp を編集する。たとえば、「数字4桁」-「英数字3文字」-d@foo.bar.jpというメールアドレスを受けとり、/tmp/mail-spool.txtというファイルに保存したければ以下のように記述する。ポイントは@の後ろが省略されることがあるので、「(@.*)?$」を記述すること。
/^[0-9]{4}-[0-9a-zA-Z]{3}-d(@.*)?$/ "| /bin/cat >> /tmp/mail-spool.txt"
これで、1234-abc-d@foo.bar.jp というメールを送ると /tmp/mail-spool.txt に保存される。ちゃんと動いているかは /var/log/mail.log で確認する。自分が作成したプログラムへ送りたい場合は「"| /bin/cat >> /tmp/mail-spool.txt"」のパイプの後ろを修正すればよい。このコマンドは default_privs で設定したユーザー権限で実行される。
しかし、このままだと上の正規表現に引っかからないメールはすべて "unknown user"としてエラーメールが送信者へ返ってしまう。スパムが多い現在あまり良い挙動でない。そこで、正規表現が上から評価されていくことを利用して、一番最後に何でも/dev/nullへ放り込む設定にする。つまり以下のように2行目を書き加える。
/^[0-9]{4}-[0-9a-zA-Z]{3}-d(@.*)?$/ "| /bin/cat >> /tmp/mail-spool.txt" /^.*(@.*)?$/ /dev/null
これで、1234-abcd-e@foo.bar.jp というメールを送ると、このメールは /dev/nullへ直行するようになる。直行しているかどうかは、/var/log/mail.log で確認する。