「同一マシン内で、待受けIPアドレスか待受けTCPポートが異なった複数のPostfixインスタンスを動作させ、役割分担を実現する」
更新 2022/05/07 smtp_bind_address=0.0.0.0について
更新 2022/07/18 配送エラー(dsn=4.4.1)と対処方法
Postfixは、同一マシンに、それぞれ異なる設定を持つ複数のインスタンスを動作させることができる。
これは、Postfixのマルチプルインスタンスモードで実現できる。
同一マシン内で複数インスタンスを扱うことで、例えば、
一方のインスタンスがSMTPでメールをクライアントから受け取り、
そこからSMTPプロキシなどを経て処理を経た後に、
他方のインスタンスにSMTPで入力することで、配送などの処理を継続させることが同一マシン内で可能になる。
クライアント→
[(eth0-インスタンスA)→ SMTPプロキシ(内部処理など)→ (lo-インスタンスB)] →外部SMTP
以下では、これまでのもともとのシングルインスタンス(メイン)に加えて、
さらに新しいインスタンス(サブ)を追加して構成する。
■Postfixの設定
マルチプルインスタンスに関する設定のみ抜粋している。
その他、たとえばリレーのための設定などは省略している。
○Postfixを複数インスタンスモードに切り替え
# postmulti -e init
これによって、main.cf に、次の
2行が追加された。(diff コマンドで変更前のmain.cfと比べた。)
multi_instance_enable = yes
multi_instance_wrapper = ${command_directory}/postmulti -p --
○インスタンスの作成
(とりあえず、一個のみ「追加」する)
-I オプションに続けて、
postfix- から始まる任意のインスタンス名を指定する。
# postmulti -I postfix-dept1-localnet -e create
これによって、main.cf に、次の1行が追加された。
multi_instance_directories = /etc/postfix-dept1-localnet
○上で作成したインスタンスの有効化
# postmulti -i postfix-dept1-localnet -e enable
この段階までで、新規に作成するインスタンスのためのファイルがディレクトリに作成されていた。
・/etc/postfix-dept1-localnet
main.cf master.cf
・/var/spool/postfix-dept1-localnet
active bounce corrupt defer deferred flush hold incoming maildrop pid private public saved trace
○各インスタンスの通信インターフェイスについての設定
各インスタンスは、待ち受け用として「異なるIPアドレス」か「異なるTCPポート」と結びついている必要がある。
・異なるIPアドレスを用いる場合
ここでは、eth0に、
192.168.250.48 が割り当てられているとする。
(メイン インスタンスの設定)
#
vi /etc/postfix/main.cf
inet_interfaces = localhost
(サブ インスタンスの設定)←追加分である
#
vi /etc/postfix-dept1-localnet/main.cf
inet_interfaces = 192.168.250.48
#(罠)コメントアウトすること ↓(さもなければ、25番ポートが開かない)
#master_service_disable = inet
・異なるTCPポートを用いる場合
たとえば、指定するインスタンスにおいて、25ではなく2525で待受けするには次の様に設定する。
# cd /etc/postfix-dept1-localnet
#
vim master.cf
(略)
#smtp inet n - n - - smtpd
2525 inet n - n - - smtpd
(略)
○Postfixを再起動して、設定を有効化
# service postfix restart
■動作確認
○インスタンスの確認
各インスタンスの情報を表示させる
# postmulti -l -a
- - y /etc/postfix
postfix-dept1-localnet - y /etc/postfix-dept1-localnet
(名前、グループ名、有効かどうか、設定ファイルディレクトリ)
1行目は、メインインスタンス
2行目は、名前付きのサブインスタンス
各インスタンスの状態を表示させる
# postmulti -p status
postfix/postfix-script: the Postfix mail system is running: PID: 16934
postfix-dept1-localnet/postfix-script: the Postfix mail system is running: PID: 17000
○開いているポートの確認
# netstat -plnt | grep :25
tcp 0 0 192.168..250.48:25 0.0.0.0:* LISTEN 17000/master
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 16934/master
tcp 0 0 ::1:25 :::* LISTEN 16934/master
○sendmailコマンドで、各インスタンスそれぞれについてメールを送出
(メイン インスタンス を使って送信)
# echo test | sendmail -C /etc/postfix -f [email protected] [email protected]
問題なく、メールを送信することができた。
(サブ インスタンス を使って送信)
# echo test | sendmail -C /etc/postfix-dept1-localnet -f [email protected] [email protected]
こちらは、エラーが発生した。
Feb 19 00:34:56 test postfix-dept1-localnet/sendmail[17043]: fatal: User root(0) is not allowed to submit mail
そこで、
次のパラメーターを、サブインスタンスの main.cf に次のコマンドで設定した。
authorized_submit_users = static:anyone
# postconf -c /etc/postfix-dept1-localnet -e authorized_submit_users=static:anyone
# service postfix restart
問題なくメールを送信できるようになった。
そのときのログ(/var/log/maillog)
Feb 19 00:51:23 test
postfix-dept1-localnet/pickup[17002]: xxxxxxxxxx: uid=0 from=<
[email protected]>
Feb 19 00:51:23 test
postfix-dept1-localnet/cleanup[17081]: xxxxxxxxxx: message-id=<
[email protected]>
Feb 19 00:51:23 test
postfix-dept1-localnet/qmgr[17003]: xxxxxxxxxx: from=<
[email protected]>, size=290, nrcpt=1 (queue active)
Feb 19 00:51:23 test
postfix-dept1-localnet/smtp[17083]: xxxxxxxxxx: to=<
[email protected]>, relay=smtp.example.com:25, delay=0.25, delays=0.03/0.02/0.04/0.16, dsn=2.0.0, status=sent (250 ok 1111111111 qp 44444)
Feb 19 00:51:23 test
postfix-dept1-localnet/qmgr[17003]: xxxxxxxxxx: removed
サブインスタンス名(postfix-dept1-localnet)で表示されていることがわかる。
このエラーが生じたように、サブインスタンスのために自動的に作成された main.cf は、
パッケージから展開されたオリジナルの main.cf(こちらはメインインスタンスが使用しているもの)とは、
少々異なっているようである。
必要に応じて、設定を調整する必要があるのだと思った。
★ところで、複数インスタンス構成で、送信時に次のエラーが発生し、
インターネット上のsmtpサーバにリレーできない場合があった。
Mar 13 05:00:01 mailsvr postfix-dept1-transfer/pickup[22237]: xxxC51xxxx: uid=0 from=<fromaddress@mydomain>
Mar 13 05:00:01 mailsvr postfix-dept1-transfer/cleanup[22242]: xxxC51xxxx: message-id=<[email protected]>
Mar 13 05:00:01 mailsvr postfix-dept1-transfer/qmgr[22238]: xxxC51xxxx: from=<fromaddress@mydomain>, size=289, nrcpt=1 (queue active)
Mar 13 05:00:01 mailsvr postfix-dept1-transfer/smtp[22244]: connect to smtp.relay.to[5.6.7.8]:587: Connection timed out
Mar 13 05:00:31 mailsvr postfix-dept1-transfer/smtp[22244]: xxxC51xxxx: to=<[email protected]>, relay=none, delay=30, delays=0.05/0.01/30/0, dsn=4.4.1, status=deferred (connect to smtp.relay.to[5.6.7.8]:587: Connection timed out)
このエラーに、随分悩まされたが解決方法がわかった。
複数インスタンスを構成している場合、それらを同時に存在させるために設定を工夫していた。
各インスタンスは、待ち受けポート番号あるいはアドレスを他のインスタンスとずらすことによって、
同時に存在できるようにしていた。
待受けアドレスを変更する場合には、既に述べた通り、
inet_interfaces の設定で行う。
この値は、デフォルトは、all になっているのでこの(Connection timed out)問題は生じない。
ところが、(先の理由などのために)
ここにIPアドレスを明示している場合に問題が生じる場合がある。
inet_interfaces に、IPアドレスを指定した場合、それがループバックアドレスでなければ、
そのIPアドレスを、SMTPクライアントのソースアドレスとして用いるのである。
この場合には、待受け時のアドレスの指定としてだけで用いられるのではないのだ。
そのため指定したアドレスでインターネットへの接続ができない場合、この(Connection timed out)問題が生じるのである。
したがって、解決方法は二つ考えられる。
一つは、
inet_interfaces で指定する値を次の様に変えることである。
inet_interfaces の値を、ループバックアドレス、インターネットに接続できるIPアドレスにする。
あるいは、all(デフォルト値)にする。
もう一つは、
そのインスタンスにおいてSMTPクライアントが使用するソースアドレスを、次の様にして明示することである。
# cd /etc/postfix-dept1-transfer
# vim master.cf
(略)
smtp unix - - n - - smtp
-o smtp_bind_address=1.2.3.4
(略)
(注意)先頭にある、「smtp inet n - n - - smtpd」 ではない!
上では、-o smtp_bind_address=1.2.3.4 を設定しているが、それだと「1.2.3.4」のインターフェスしか使用されない。
代わりに、「-o smtp_bind_address=0.0.0.0」 を設定すると、リレー先サーバーのネットワークに応じて適切なインターフェイス(IPアドレス)を自動選択された。
このようにしておくと、フォールバックリレーの設定でネットワークが異なるリレー先サーバーが指定されていたとしても、適切に通信が可能になる。
変更後、postfixを再起動した。
無事に、インターネット上にあるsmtpサーバへリレーすることができるようになった。
○外部ネットワークから、メールソフトを使って送信
こちらも問題なく、送信することができた。
既に確かめたように、192.168.250.48:25 を開いているのは、サブインスタンス(
postfix-dept1-localnet)である。
すなわち、このサブインスタンスがクライアント(192.168.250.47)からのメールを受け、取り扱うことになる。
そのときのログ(/var/log/maillog)
Feb 19 01:05:46 test
postfix-dept1-localnet/smtpd[17096]: connect from unknown[192.168.250.47]
Feb 19 01:05:46 test
postfix-dept1-localnet/smtpd[17096]: xxxxxxxxxx: client=unknown[192.168.250.47]
Feb 19 01:05:46 test
postfix-dept1-localnet/cleanup[17099]: xxxxxxxxxx: message-id=<
[email protected]>
Feb 19 01:05:46 test
postfix-dept1-localnet/qmgr[17003]: xxxxxxxxxx: from=<
[email protected]>, size=603, nrcpt=1 (queue active)
Feb 19 01:05:46 test
postfix-dept1-localnet/smtpd[17096]: disconnect from unknown[192.168.250.47]
Feb 19 01:05:46 test
postfix-dept1-localnet/smtp[17100]: xxxxxxxxxx: to=<
[email protected]>, relay=smtp.example.com:25, delay=0.3, delays=0.03/0.02/0.06/0.19, dsn=2.0.0, status=sent (250 ok 1111111111 qp 44444)
Feb 19 01:05:46 test
postfix-dept1-localnet/qmgr[17003]: xxxxxxxxxx: removed
◆その後、数年間運用していたがメール送信が滞ることがあった。(番外編)
調べてみると、次のエラーがログに記録されていた。
複数インスタンスの場合、下記の例のように、postfix-outgoing のように問題が生じているインスタンスを区別することができる。
Jul 18 07:36:15 MailServer
postfix-outgoing/error[12345]: **********: to=<
[email protected]>, relay=none, delay=0.09, delays=0.09/0/0/0,
dsn=4.4.1, status=deferred (delivery temporarily suspended: connect to
smtp.outgoing.example.com[*.*.*.*]:587: Connection timed out)
上記ログには、dsn=4.4.1 と記録され、Connection timed out になっていることがわかる。
次の配送先メールサーバーは、上の例では、smtp.outgoing.example.com である。
配送状況を示す dsn=4.4.1 は、この配送先メールサーバーが一時的なエラーを返しているということを意味する。その結果、タイムアウトになっているのだ。
思い当たったのは、インターネットに接続しているルーターのグローバルIPアドレスがしばしば変化することである。
たまたま割り当てられたグローバルIPアドレスが以前にスパムメールの配信元として使われていたことがある可能性を考え、次の対処を行った。
<対処手順 その1>
1、グローバルIPアドレスの更新を行った。
そこで、ルーターを再起動することで、自動的に割り当てられるグローバルIPアドレスを別のものに更新した。
ISP(プロバイダ)によってはこの方法ではアドレスは変わらないところもあるので注意が必要である。
2、キューをフラッシュして再送信した。
キューの確認
#
postqueue -c /etc/postfix-outgoing -p
(省略)
********** 516 Sat Jul 18 07:13:44 [email protected]
(lost connection with smtp.example.com[*.*.*.*] while receiving the initial server greeting)
[email protected]
-- 424 Kbytes in 8 Requests.
キューフラッシュ
#
postqueue -c /etc/postfix-outgoing -f
キューの再確認
#
postqueue -c /etc/postfix-outgoing -p
Mail queue is empty
キューが空になったので、配送先サーバーにメールが受け取られたと判断した。
メールログにも、次の表示を確認できた。
dsn=2.0.0, status=sent
<対処手順 その2>
続いて、フォールバック用のSMTPサーバーを設定しておく。こちらの方法でも問題は解決できた。
同様の問題が発生するのに備えて、フォールバックSMTPサーバーの設定は必要だと思う。
次のように登録しておくと、relayhost のSMTPサーバーでの配送が失敗しても、
smtp_fallback_relay で指定しているSMTPサーバーで配送が試みられるようになる。
relayhost = smtp.outgoing.example.com:587
smtp_fallback_relay = another-smtp.example.com:587
それぞれのSMTPサーバーについて、認証設定も併せて必要になる。
登録方法、認証設定などについては次のページを参考にしてください。
http://akira-arets.blogspot.com/2015/05/postfix-266-x8664linux-centos-65-64bit.html
以上
<参考>
・Managing multiple Postfix instances on a single host/Using the postmulti(1) command
< http://www.postfix.org/MULTI_INSTANCE_README.html > 2016年2月19日
・Postfix Configuration Parameters/master_service_disable (default: empty)
< http://www.postfix.org/postconf.5.html#master_service_disable > 2016年2月19日
(マルチプルインスタンス構成の方法について主に参考になった文献)
・Configure Postfix with multiple instances on centos
< http://www.linuxpcfix.com/configure-postfix-with-multiple-instances-on-centos/ > 2016年2月18日
・Postfix Multi Instance Configuration
< http://steam.io/2013/11/05/postfix-multi-instance-configuration/ > 2016年2月18日
(以下の文献は作成の方法が異なっていた。)
・Postfix Multiple Instances
< http://edoceo.com/howto/postfix-multiple-instances > 2016年2月18日
・HowTo make two instance of postfix running on same machine
< http://linuxpoison.blogspot.jp/2008/02/howto-make-two-instance-of-postfix.html > 2016年2月18日
(Connection timed out 問題の解決で役に立った情報)
正解をググり当てるのが大変だった。 ↓この投稿が突破口となった。
・Postfix - specify interface to deliver outbound mail on
< http://serverfault.com/questions/234487/postfix-specify-interface-to-deliver-outbound-mail-on > 2016年3月13日
・Postfix main.cf file format / inet_interfaces (default: all)
< http://www.postfix.org/postconf.5.html#inet_interfaces > 2016年3月13日
・Postfix main.cf file format / smtp_bind_address (default: empty)
< http://www.postfix.org/postconf.5.html#smtp_bind_address > 2016年3月13日
・postfix multiple IP SMTP banner/Solution - Postfix version 2.7 or above required:
< https://serverfault.com/questions/650057/postfix-multiple-ip-smtp-banner > 2017年5月16日
・№2446 postfix 同一の宛先に送信しているのに成功と失敗する場合がある
< https://centossrv.com/bbshtml/webpatio/2446.shtml > 2020年7月18日