_ 送信者アドレスによって送信に使う IP アドレスを分離する件。試してみた。
_ このアイデアのキモであるエンベロープ書き換え。from: hoge@example.com, to: fuga@example.net のメールを、to: fuga+example.com@example.net に書き換えるところ。でも、よくよく考えてみたら、こんなことできねーよ。from のアドレスに依存して異なる to に書き換えるなんて芸当はムリ。ダメじゃん。
_ 内蔵機能でできないのならば外部の機能でやるしかない。エンベロープの書き換えだけをやる コンテンツフィルタを作るよ。
_ こんなフィルタスクリプトを書く。あくまで動作検証用であっていろいろ手抜きしてるので、実際の運用に耐えるシロモノではない。間違ってもそのまま使ってはいけない。
んで、postfix からこのスクリプトを呼び出す設定と、その他いろいろ設定。#!/bin/sh sender="$1" senderdomain=`expr "$1" : '.*@\(.*\)'` shift for i in "$@"; do rcptlocal=`expr "$i" : '\(.*\)@.*'` rcptdomain=`expr "$i" : '.*@\(.*\)'` rcpt="$rcpt $rcptlocal+$senderdomain@$rcptdomain" done exec /usr/sbin/sendmail -f "$sender" -- $rcpt-- master.cf filter unix - n n - 10 pipe flags=q user=filter argv=/path/to/filter.sh ${sender} ${recipient} pickup fifo n - n 60 1 pickup -o content_filter= smtp-192.0.2.1 unix - - n - - smtp -o smtp_bind_address=192.0.2.1 smtp-192.0.2.2 unix - - n - - smtp -o smtp_bind_address=192.0.2.2 -- main.cf content_filter = filter:dummy transport_maps = pcre:/etc/postfix/transport.pcre smtp_generic_maps = pcre:/etc/postfix/generic.pcre append_at_myorigin = no -- transport.pcre /\+example\.com@[^@]*$/ smtp-192.0.2.1: /\+example\.jp@[^@]*$/ smtp-192.0.2.2: -- generic.pcre /^(.*)\+[^@]*@([^@]*)$/ $1@$2_ content_filter で宛先アドレスを書き換える。書き換え後の宛先を見て、正規表現で transport を選択する。最後に generic_maps で書き換えた宛先を元に戻す。元に戻したアドレスに対してなぜか @$myorigin が補完されてしまうので(原因は追っていない)、これをやめさせる設定を追加しておく。
_ で、期待どおり動きました。ぱちぱちぱち。が、めんどくせー。エンベロープの書き換えしかしないのにメール本体全部やりとりしなきゃいかんからパフォーマンスも悪いし。ここまで苦労してやる価値はないだろ。ムダムダムダ。
_ こんな方法ではなく、milter でやればエンベロープのやりとりだけで完結するものが作れるんじゃないかな、たぶん。たったこれだけのアドレス書き換えをやるために milter を書くというのもずいぶんおおげさだと思うけれど。
_ エンベロープのみを扱える外部スクリプトということで、 access policy deligationを使うことも考えたけど、ダメだった(実際に試して失敗した)。REDIRECT な結果を返せばいいかと思ったけど、RCPT TO が複数あった場合にひとつしか指定されていないのと同じになってしまう。結果的に、ひとりにしかメールは届かず、残りは虚空に消える。本質的に転送であって書き換えじゃないからしかたない。qmail みたいに事前に RCPT TO をひとつずつにバラしておけば、この方法でも失われずにぜんぶ届くと思うけど、それはちょっと。
_ ちなみに、ここまであくまでひとつの postfix で完結させることを前提にやってきたけど、複数のインスタンスを起動するなら、こんなめんどくさいことは必要ない。使いたい IP アドレスごとにそれぞれ専用のインスタンスを起動しておいて、sender_dependent_relayhost_maps を使ってそれぞれのインスタンスにリレーすればいいだけ。使いたい IP アドレスがせいぜい5個とかその程度ならばこれで十分だろう。50個とか100個とかになるとそれだけのインスタンスをいちいち起動してられなくなるが、そんなに IP アドレスを使いわけることなんかふつーはないだろうし。
_ つーか、ソースいじるのがいちばん手っ取り早いかも。
_ コンビニで FRISK が1個100円で安売りしてた。箱買いしてきた。うまー。