Postfixで書式に基づいてメールを受信する
Postfixの設定メモ。現在開発中のシステムにメールを配信する機能がある。このシステムでメールを送信する際に、中にはエラーとなって戻ってくるメールアドレスも含まれているかもしれない。この時、エラーとなるメールアドレスを識別する手法を考えていた。
最初に考えた方法はErrors-toやEnvelope-fromにエラー受信用のメールアドレス(例えばerror@example.com)を設定しておき、エラーとして戻ってきたメールの本文中に含まれるメールアドレスを抽出して、それを処理する方法だ。しかしこの方法だと、メールアドレスの抽出で一苦労しそう。例えばエラーとなるメールアドレス以外に、相手方メールサーバの管理者のメールアドレス等関係のないメールアドレスが含まれている可能性もある。
そこで考えた方法がErrors-toやEnvelope-fromに以下のようなメールアドレスを設定する方法だ。
error_1q2w3e4r@example.com
1q2w3e4rはメールの宛先ごとに一意となるように設定する。つまり宛先メールアドレスごとにErrors-toとEnvelope-fromに個別のメールアドレスを設定してしまうのだ。これで一意となるキーの部分(1q2w3e4r)と宛先メールアドレスをマッピングしたデータを持っていれば、エラーの宛先を確実に取得することができる。
メールを配信するたびに、エラー受信用のメールボックスを作るわけにはいかないので、何らかの設定をしなくてはいけない。一番簡単に考えられる方法はcatch-allだ。catch-allとして特定のメールアドレスを指定しておけば、とにかくすべてのメールを処理することができる。しかしこの場合だと、なんでもかんでも処理してしまうため(存在しないメールアドレスへのスパムメールとか)、処理に負担がかかる。
そこでメールアドレスに正規表現を施して、処理を分岐する手法だ。いろいろ調べてやっと実現する方法を見つけた。
まずPostfixで単独ドメインでとりあえずメールサーバとしては機能しているという前提にたち、main.cfに設定を加える。末尾に以下の行を追加した。
virtual_alias_domains = example.com
virtual_alias_maps = regexp:/etc/postfix/virtual
上記1行目はバーチャルドメインの設定をしているのだが、このとき、main.cfで既に設定されているmydestinationの設定と同じドメインが設定されているとまずいらしい。なのでmydestinationの行はコメントアウトしてみた。
次に上記2行目にある/etc/postfix/virtualというファイルに、以下の1行を追加した。
/bounce_(.*?)@example\.com/ bounce
上記は宛先メールアドレスとしてbounce_で始まり、@example.comで終わるメールアドレスすべてをシステム内のbounceというメールアドレスに送信するための設定だ。つまり何でもかんでも処理するのではなく、bounce_で始まるメールアドレスのみ処理するように設定している訳だ。これにより大半のスパムメールを除外することができる。
そして以下のコマンドを実行する。
postmap /etc/postfix/virtual
その後Postfixを再起動すればOKだ。
意外とこういうのって調べても見つからなかったりする。数時間も費やしてしまった。