Postfixで受け取ったメールをそのまま正規表現+パイプで外部コマンドに渡した場合にエンベロープFrom/Toを取得
Postfixで、受け取ったメールを自作した外部コマンドに処理させたい。もちろん、設定を書けばそういう風にできる。メールの内容(ヘッダやボディ)が標準入力で入ってくるようになる。
でもエンベロープFromやエンベロープToはその標準入力には含まれない。環境変数で渡されてくる。
そんな中で今回は、普通にメールアカウントに対して送られてきたメールだけを処理するのではなく、どんなアドレス宛のメールを受け取ってもすべて外部コマンドに処理させるようにしたい。そういうときは正規表現で受け取るアカウントを設定できるんだけど、それをやると環境変数で渡されるエンベロープFromやToが、自サーバ内で生成したアドレスに書き換わっちゃうことがあるっぽい。
なので、そういうのを回避するやり方を調べたのでメモ。
つまり、
というのをやる方法ってこと。
/etc/postfix/main.cf
mydestination = $myhostname, localhost.$mydomain, localhost, regexp:/etc/postfix/mydestination.regexp virtual_alias_maps = regexp:/etc/aliases.regexp alias_maps = hash:/etc/aliases
これから使う3つのファイルを読み込む設定。
/etc/aliases
他を全部消して
all: "| /usr/local/bin/mailreceiver >/dev/null 2>&1"
これだけにする。
ここでは、「all」アカウントで受け取ることになったメールをパイプで /usr/local/bin/mailreceiver という外部コマンドで処理させるようにしている。
/usr/local/bin/mailreceiver
#! /usr/bin/ruby File.open("/var/mails/#{Time.now.to_i}_#{$$}.txt", 'w') do |f| f.puts ENV['SENDER'] f.puts ENV['ORIGINAL_RECIPIENT'] while str = gets f.print str end end
ここで実際に受け取ったメールを処理させる。好きなように書いていいけど、上記ではとりあえず、エポック秒とプロセスIDをファイル名として、そこにメールの内容を書き出すようなRubyスクリプトにしてみた。で、先頭の2行が、エンベロープFromとエンベロープToになるようにしている。
こんな感じで、環境変数のSENDERとORIGINAL_RECIPIENTから取り出せる。他にも環境変数はいろいろあるので、気になる人は全部出力してみるといい。例えばメールを送ってきた接続元のIPとかも取れる。
どうやら一般的にはSENDERとRECIPIENTという環境変数にエンベロープFrom/Toが入るらしいけど、自分の環境ではそうはならなかった。冒頭にも書いたように、たぶんmydestinationやaliasに正規表現を使っていると、内部的に転送みたいな扱いになって情報が書き換わってる気がする。例えばSENDERが「owner-(Toのローカル部)@localhost.localdomain」になったり、RECIPIENTが「all@localhost.localdomain」になったりする。
それで、上記のように設定したところ、SENDERとORIGINAL_RECIPIENTでそれぞれ取得できるようになった。
よくわかってない
いろいろ試したらこのやり方でできたっていうだけで、それぞれの設定の意味はよくわかってない。特にvirtual_alias_mapsとalias_mapsの関係がよくわからん。なので、なんかダメなことをやっちゃってるかも知れない。
なんかあったら教えてください。