mail-relay - UNIXからメールを送る際に、接続先SMTPサーバを指定したい

目的

以下の条件に合うように、

  1. 特定ドメインのアドレス(jp.example.com)宛のメールはサーバ1に送る。
  2. それ以外のメールはサーバ2に送る。

以下のメールサーバ(MTA)で、メール送信時のSMTP接続先を指定したい。

※なぜこの3つかというと、RHELが想定しているMTAがこの3つだから(参考: Product Documentation for Red Hat Enterprise Linux 8 - Red Hat Customer Portal; system-switch-mail コマンドで切り替え可能)。

結果

MTAの設定変更で実現できた。

MTA 特定ドメインのアドレスの接続先 それ以外のメールの接続先
sendmail(FC使用) mailertableファイルで設定 sendmail.mcファイルのSMART_HOSTで設定
postfix transportファイルで設定 relayhostファイルで設定
exim (未調査) (未調査)

注意:メールのFromかToどちらかが自社の有効なメールアドレスでないと、SMTPサーバがメールを無視してしまう場合があるので、気をつける。
これをlocalhostへの送信時に判別できるようにする方法も試みたが、うまくいかず断念。

以下、詳細。

背景と動機

例えば、社内の情報システムの設定が不思議なポリシーに従っていて、「社内LANからのDNSのMXレコードの問い合わせには、SMTPを受けつけないホストのIPアドレスを返す」という場合がある(なぜこういう設定なのか、意図がわからない…)。
この設定だと、社内の自分のメールアドレスへのメール送信すらできない。

具体的には、以下のような状況:

# MXレコードはとあるサーバを指している
% dig gmail.com MX
...
;; ANSWER SECTION:
gmail.com.              86223   IN      MX      200 bluejays.examle.com.
...
;; ADDITIONAL SECTION:
bluejays.example.com.   43200   IN      A       xxx.xxx.xxx.xxx
...

# このサーバのSMTPポートにアクセスできない
% telnet bluejays.example.com smtp
Trying xxx.xxx.xxx.xxx...
telnet: connect to address xxx.xxx.xxx.xxx: No route to host

# pingも通らない(昨日は通ったような気がするが…)
% ping -c1 xxx.xxx.xxx.xxx
PING xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx) 56(84) bytes of data.
...
1 packets transmitted, 0 received, 100% packet loss, time 0ms

この状況でUNIXマシンからmail(1)やsendmail(8)ではメールを送信すると、コマンドは終了するので一見メールが送れたように思えるが、実際はlocalhostでキューイングしているだけ、相手にはいつまでたっても届かない。

実際にメールを送ってみる(失敗編)

今、yamada.taroh@jp.example.com に送ることにする。
以下は、sendmailの場合を記述(コマンドの使い方は、postfixでもeximでも同じ)。

mail(1)の場合:

% printf "Subject: test mail\nFrom: yamada.taroh@jp.example.com\nTo: you\n\n" | mail -v yamada.taroh@jp.example.com
yamada.taroh@jp.example.com... Connecting to [127.0.0.1] via relay...
...

sendmail(8)の場合:

% printf "Subject: test mail\nFrom: me\nTo: you\n\n" | sendmail -v -f yamada.taroh@jp.example.com yamada.taroh@jp.example.com
yamada.taroh@jp.example.com... Connecting to [127.0.0.1] via relay...
...

どちらも、一見成功したように見えるが、メールのキューを確認してみると:

# さっき送ったはずのメールが、localhostのキューにたまっている
% sudo mailq
m385ZkxJ027070        7 Tue Apr  8 14:35 
                 (Deferred: Connection timed out with smtp.example.com.)
                                         
....
# 再送しても、失敗する
% sudo sendmail -q -v
Running /var/spool/mqueue/m386bs3I027745 (sequence 2 of 2)
... Connecting to bluejays.example.com. via relay...
... Deferred: Connection timed out with bluejays.example.com.

このままでは、メールは届かない。

設定方法

以下のサーバに繋ぎに行くように設定したい:

  1. jp.example.com宛のメールは 10.71.199.3 のIPアドレスに送る(社内メールの配送サーバ)
  2. それ以外のメールは、mail.jp.example.com に送る

(以降に具体的に設定を書いたが、http://www.networkworld.jp/server/-/23261.html を見た方が早いかもしれない)

sendmail の場合

RHELではCFが使われているので、その設定に従う。

特定ドメイン宛メールの設定
/etc/mail/mailertbleに以下の行を追加する
jp.example.com     smtp:[10.71.199.3]

※/etc/mail/sendmail.mc にて、access_db と mailertable のFEATURE が有効になっている(行が存在し、行頭にdnlが付いていない)ことを確認すること。

それ以外のメールの設定
/etc/mail/sendmail.mc の以下の行を編集
define(`SMART_HOST',`mail.jp.example.com')dnl

※もし行頭の "dnl"(m4のコメントマーク)が付いていたら削除する。

設定更新
rootで以下を実行する
# cd /etc/mail
# make
デーモン再起動
rootで実行
# /etc/init.d/sendmail restart
postfixの場合
特定ドメイン宛メールの設定
/etc/postfix/transport に以下の行を追加する
jp.example.com     smtp:[10.71.199.3]

※/etc/mail/sendmail.mc にて、access_db と mailertable のFEATURE が有効になっている(行が存在し、行頭にdnlが付いていない)ことを確認すること。

それ以外のメールの設定
/etc/postfix/main.cfに以下の行を追加する
relayhost = [mail.jp.example.com]
設定更新
rootで実行
# cd /etc/postfix
# postmap transport
デーモン再起動
rootで実行
# /etc/init.d/postfix restart

実際にメールを送ってみる(成功編)

今度は成功するはず。

mail(1)の場合:

% printf "Subject: test mail\nFrom: yamada.taroh@jp.example.com\nTo: you\n\n" | mail -v yamada.taroh@jp.example.com
yamada.taroh@jp.example.com... Connecting to [127.0.0.1] via relay...
...

sendmail(8)の場合:

% printf "Subject: test mail\nFrom: me\nTo: you\n\n" | sendmail -v -f yamada.taroh@jp.example.com yamada.taroh@jp.example.com
yamada.taroh@jp.example.com... Connecting to [127.0.0.1] via relay...
...

ここまでは先ほどと同じだが、メールのキューはからになっている:

# さっき送ったはずのメールが、localhostのキューにたまっている
% sudo mailq
/var/spool/mqueue is empty
                Total requests: 0

あとは、実際にメールを取り込んで確認する。

再度注意

社内LANからアクセスするSMTPサーバは、FromかToのいずれかが社内の有効なメールアドレスでないと、送信メールを無視してしまう。
「拒否」ではなく「無視」なのが分かりにくいところで、「コミットメールが届かない!」などの問題が起きたら、これを疑ってみること。

localhostでのSMTP受信制限(失敗)

上記の問題を把握しやすくするために、localhostでのSMTP受信時にこのチェックに挑戦する。

postfixでは、main.cf にて smtpd_recipient_restrictions を設定すれば、RCPT TO で許可するドメインを指定できる、と postconf(5)にはあるのだが、ここをhashで設定しても、rejectのみにしても、メールは送れてしまう。
よくわからなくなったので、この辺で断念。