複数のドメイン宛てのメールを、Exim4 MTA が稼働している 1 台のメールサーバでまとめて受けるような運用において、宛先アドレスのドメイン名に応じてエイリアスの設定を変えたり、Catch-All 機能を設定/解除できるようにするための覚書き。exim4 はズブの素人なので、すっごい遠回りしている可能性大。もしかしたら設定 1 つで対応できるのかもしれませんが…
自宅のメールサーバは Debian GNU/Linux (jessie) 上で Exim4 がほぼ素インストール状態で稼働しています。すると、例えば、example.com、example.org、example.net、…と複数のドメインの MX レコードをこの 1 台に向けていた場合、bob@example.com 宛てのメールも、bob@example.org 宛てのメールも、bob@example.net 宛てのメールも全て、bob アカウント宛てに届くことになります。ここで、bob@example.com 宛てのメールだけは alice に転送したいと思っても、/etc/aliases では対応できません。なぜなら、bob: alice と書いてしまうと、全ドメインのメールが alice に転送されてしまうからです。
User unknown でエラーを返す、といった設定をしたいとします。
最初に、ドメイン毎の aliases 設定を保存するためのディレクトリを作成しておきます。
$ sudo mkdir /etc/exim4/virtual
次に /etc/ecim4/exim4.conf.template を修正します。
#domainlist local_domains = MAIN_LOCAL_DOMAINS
domainlist local_domains = MAIN_LOCAL_DOMAINS:dsearch;/etc/exim4/virtual
:
:
### end router/300_exim4-config_real_local 周辺
:
vdom_aliases:
driver = redirect
allow_defer
allow_fail
domains = dsearch;/etc/exim4/virtual
data = ${expand:${lookup{$local_part}lsearch*{/etc/exim4/virtual/$domain}}}
pipe_transport = address_pipe
file_transport = address_file
:
### router/400_exim4-config_system_aliases 周辺
local_domains … 処理の対象となるドメイン名のリストを、/etc/exim4/virtual 以下に置かれている設定ファイルのファイル名一覧から生成します。この修正は必須ではありませんが、新しいドメインが増えた際、/etc/exim4/virtual 以下に、とりあえず空のファイルを置いておくだけで、新しいドメインを受信対象に指定できるので便利です。そうでない場合、/etc/exim4/update-exim4.conf.conf の dc_other_hostnames に新しいドメイン名を追記した後、都度、update-exim4.conf を実行した上で、サービスの再起動を行わねばなりません。domains … /etc/exim4/virtual 以下の置かれた設定ファイルのファイル名一覧から、処理対象となるドメイン名のリストを生成します。ドメイン名と同じファイル名の設定ファイルがない場合にはルールが適用されません。data … 受信したメール アドレスのドメイン名($domain)に対する設定ファイル(/etc/exim4/virtual/$domain)内を検索(lookup)して、元のアカウント名($local_part)に対応する値を取得(lsearch)します。もし、$local_part が見つからなければ、* がないか再検索します*1。expand: オペランドが指定されているので、見つかった文字列が再評価されて、:fail: や :blackhole: といった特殊な項目も正しく処理できるようになっています。
例として、example.com ドメイン宛てに届いたメールについて、エイリアスの設定や Catch-All 設定を行うには、/etc/exim4/virtual/example.com を作成します。この設定は、example.com ドメイン宛てに届いたメールにのみ適用されます。
bob: alice tom: :fail: Gone away, no forwarding address. *: root
エイリアスや Catch-All の設定を一つのファイルで行う設定例です。
### end router/300_exim4-config_real_local 周辺
:
vdom_aliases:
driver = redirect
allow_defer
allow_fail
domains = +local_domains
data = ${expand:${lookup{$local_part@$domain}lsearch*@{/etc/aliases}}}
pipe_transport = address_pipe
file_transport = address_file
:
### router/400_exim4-config_system_aliases 周辺
lsearch* が lsearch*@ となっている点が違います。まず、検索文字列そのもの(bob@example.com)で検索を行い、見つからなかった場合、次に検索文字列の @ 記号以前を * に置き換えた文字列(*@example.com)で検索を行います。更に見つからなかった場合、* 記号で再度検索します。設定ファイルは次の例のようになります。
tom@example.com: jack *@example.com: :fail: *: root
debnug_print の出力はどこで見れるの?⇒ /usr/sbin/exim4 の実行引数に、デバッグレベルを指定する。
/etc/exim4/virtual/exmple.com と /etc/exim4/virtual/exmple.org が同じ内容でれば、片方の設定ファイルへの symbolic link とすれば、同じ設定を共有できる。:fail: Original Message String とすると、カスタム文字列付きで reason: 550 Original Message String エラー メールを返すことができる。:blackhole: とすると、送信元にエラー メールを返さずに、メールを捨てる。:defer:、:unknown: というのもあるが、何が起こるのかよく判らなかった。