2019/07/28 CentOS7.2





Postfixでマルチインスタンスを構成する


Postfixをマルチインスタンスで動かすと、1台のサーバで複数のPostfixを別々のコンフィグで起動できます。




同じIPアドレスに対して違うポート番号で待ち受けたり、異なるIPアドレスへ別々のPostfixを割り当てたりできます。
メールリレーの途中に処理を挟み込みたいが、別サーバを用意するよりはリソースを節約できます。

Postfixマルチインスタンスは本家サイトにマニュアルがあります。これを情報の基本とします。
http://www.postfix.org/MULTI_INSTANCE_README.html




設定は、親main.cfを編集したり子main.cfを編集したりします。
どちらを編集しているか、間違えないように気を付けましょう。


1.SELinuxを無効にします

#setenfoce 0

再起動のためコンフィグも設定しておきます。
/etc/selinux/config
 SELINUX=disabled



2.コマンドを実行して、Postfixの設定を変更していきます


Postfixのマルチインスタンス設定には、コマンドが用意されてます。
コマンドを実行することにより、main.cfが書き換えられていき、ディレクトリ作成されます。
一つ一つのコマンドの内容は後述するので、前半では動作させるところまでをまとめます。

#postmulti -e init

 main.cfへ以下の設定が追加されます。
  multi_instance_wrapper = ${command_directory}/postmulti -p --
  multi_instance_enable = yes


#postmulti -I postfix-sub -e create

 ここで任意の子インスタンス名を指定します。
 この子インスタンス名は今後、ディレクトリ名や設定名になります。

 main.cfへ以下の設定が追加されます。
 multi_instance_directories = /etc/postfix-sub

 /etc/postfix-subディレクトリが作成され、中に子インスタンスのmain.cfとmaster.cfが生成されます。
 ディレクトリ/var/spool/postfix-subや/var/lib/postfix-sub が生成され、アクセス権が設定されます。



3.子インスタンスの設定ファイルを編集します

子master.cfを編集し、10025番ポートで起動するよう設定します。

/etc/postfix-sub/master.cf
#smtp      inet  n       -       n       -       -       smtpd (コメントアウト)
10025      inet  n       -       n       -       -       smtpd


子main.cfを編集し、IPアドレスに対してバインドするようにします。

/etc/postfix-sub/main.cf
#  master_service_disable = inet  (コメントアウト)



4.子インスタンスを有効化します

#postmulti -i postfix-sub -e enable

子インスタンスmain.cfに、以下が追加されます。
multi_instance_enable = yes

子インスタンスを有効にすることで、起動可能となります。
また親インスタンス起動時に子インスタンスも自動起動します。
このコマンドで複数の子インスタンスを有効、無効で使い分けることもできます。



5.子インスタンスの起動試験をします

#postmulti -i postfix-sub -p start
#postmulti -i postfix-sub -p status
#netstat -ant

正常に起動でき、ポート10025が開いていることを確認します。
この状態で子インスタンスを、メールサーバとして調整することになります。



6.再起動試験を行います

#service postfix restart
#postmulti -a -p status


親インスタンスの起動に伴い、子インスタンスも起動していればマルチインスタンス化は完了です。
netstatで10025番ポートが起動しているか、grepでmasterプロセスが複数起動しているか、などで確認できます。


マルチインスタンスでよく使うコマンド

masterプロセスがいくつ起動しているか確認する
#ps ax | grep master

設定してあるPostfixインスタンスを列挙します。「-」は親を、「y」はenable設定を意味します。
# postmulti -l -a

Postfixインスタンスの稼働状態を全て列挙します。
#postmulti -a -p status

指定したPostfixインスタンスのみ状態表示します。
#postmulti -i postfix-sub -p status

指定した子インスタンスのみ起動する
#postmulti -i postfix-sub -p start

インスタンスを起動/終了します。servicesコマンドを介さないのでSELinuxが有効なままでも動作します。
#postfix start
#postfix stop






各設定項目の解説


マルチインスタンスのための設定追加
#postmulti -e init

main.cfへ以下の設定が追加されます。
  multi_instance_wrapper = ${command_directory}/postmulti -p --
  multi_instance_enable = yes


子インスタンス設定の追加
子インスタンスのそれぞれ異なる名前が必要です。
#postmulti -I postfix-sub -e create

main.cfへ、子インスタンスが一つ追加されます。
  multi_instance_directories = /etc/postfix-sub

子インスタンス用ディレクトリが作成されます。
 /var/spool/postfix-subディレクトリが作成
 /var/lib/postfix-sub ディレクトリが作成
 /etc/postfix-subディレクトリが作成、コンフィグファイルがコピー

 /etc/postfix-subに生成されるのは、main.cfとmaster.cfのみ。
 main.cfの内容はほとんど新品同様です。
 ただマルチインスタンスに関する設定項目が追加されています。
 ・queue_directoryやdata_directoryなどのディレクトリが、postfix-subになっている
 ・子postfixとしての設定が追加されている
   master_service_disable = inet
  authorized_submit_users =
   multi_instance_name = postfix-sub


子インスタンスのmaster.cfの編集
/etc/postfix-sub/master.cf
#smtp      inet  n       -       n       -       -       smtpd (コメントアウト)
10025      inet  n       -       n       -       -       smtpd

同じIPで起動する場合は、ポートをずらしておく必要があります。
ここではsmtp、つまり25番ポートは親インスタンスに譲り、子インスタンスは10025番ポートで起動するよう設定します。
単に10025と設定してあるので、main.cfのinet_interfaces = localhostに従います。

もし特定のIPアドレスを持っているサーバで、別IPアドレスでサービスを提供するなら、以下のように記述します。
#smtp      inet  n       -       n       -       -       smtpd (コメントアウト)
192.168.1.100:10025      inet  n       -       n       -       -       smtpd



子インスタンスのmain.cfの編集
#master_service_disable = inet  コメントアウト

初期状態ではmaster_service_disableによりどのIPアドレスも使用しないよう設定されています。
子インスタンスを起動してもポート10025番が開かないのも、そのためです。
この行をコメントアウトします。
なぜこんな設定が入っているのか?
これはどうやら、 事故防止のための設定のようです。

設定者が未調整のPostfixを誤って再起動をする→子インスタンスがlocalhostで意図せず起動→25番が占有されてメインのPostfixがポート競合で起動失敗→メールサービス停止
(この行が存在しないと、Postfixは「子インスタンスはローカルアドレスで起動可能」となります)

master_service_disable = inet のmasterとは、子インスタンスのmasetrプロセスのことです。
master_service_disable = inet は「inetに対してmasterプロセスを起動しない」ということのようです。
inetにmasterサービスが割り当てられないということは、master.cfで宣言されているポート番号なども機能しないということです。

Postfixの本家マニュアルにこうあります http://www.postfix.org/MULTI_INSTANCE_README.html
「nullクライアントは通常、SMTPリスナーをまったく実行しない(master_service_disable = inet)か、ループバックインタフェースでのみ待機する(inet_interfaces = loopback-only)かのどちらかです」
つまり初期値ではnullクライアントとしての役割に設定しておくよ、ということです。

nullクライアントとは http://www.postfix.org/STANDARD_CONFIGURATION_README.html#null_client
「nullクライアントとは、メールを送信することしかできないマシンです。ネットワークからメールを受信せず、ローカルにメールを配信しません」



子インスタンスの有効化
#postmulti -i postfix-sub -e enable

/etc/postfix-sub/main.cfに以下の行が追加されます。
multi_instance_enable = yes

これにより、子インスタンス自身は、自分が親と同時に自動起動してよいインスタンスだと認識されます。
この設定がなくても、子インスタンスは以下コマンドで手動起動が可能です。

#postmulti -i postfix-sub -p start

試験する場合や、親インスタンスとまったく別のメール用途なら必ずしも親インスタンスと起動・終了を揃える必要はありません。そんな場合です。





トラブルの対処


エラー「mail for localhost loops back to myself」

Postfixnをマルチインスタンスするときは、なにかしらの目的があると思います。
本項のように送信用のメールを中継するだけならいいのですが、受信を目的とした場合、myhostnameには注意する必要があります。

メール経路のログで、次のような見慣れないメッセージが表示されたとします。

warning: relayhost configuration problem
to=<root@example.net>, relay=none, delay=0.02, delays=0.01/0.01/0/0, dsn=4.3.5, status=deferred (mail for localhost loops back to myself)

localhost、loop backtというログについて、Postfixマルチインスタンス特有のログかと疑ったりもしましたが、単に子インスタンスmain.cfのmydestinationにメールドメインが記載されていなかっただけでした。
ローカルからの転送なので普段とは拒否メッセージが異なっていたため調査に時間がかかりました。



servicesから起動すると失敗する・OS起動時に自動起動しない

#services postfix start
とすると、失敗という結果が出る、子インスタンスのポートが起動しない、という場合です。

コマンドで各インスタンスの起動状態を確認します。
# postmulti -a -p status

次に手動起動は可能か?
# postfix stop
# postfix start

手動起動でポート25とポート10025が正常起動していれば、手動起動は可能だがservicesコマンドを介する起動に失敗する → SELinuxが有効になっている、となります。

SELinuxが有効になっていると、services経由で/var/spool/postfix-subへの書き込みが拒否されるため、
起動に失敗します。
getenforceコマンドSELinuxの設定状態を確認します。

もちろんSELinuxを編集すれば解決するはずです。
親Postfixも子Postfixも実行ファイルは/usr/sbin/postfixで同一なので、/var/spool/postfix-subへ親と同じポリシーを与えれば書き込めるようになると思うのですが…

一応、SELinuxをPermittedにした場合のaudit.logを載せます。
type=AVC msg=audit(1564228663.666:56): avc:  denied  { unlink } for  pid=2419 comm="master" name="pickup" dev=dm-0 ino=259254 scontext=unconfined_u:system_r:postfix_master_t:s0 tcontext=system_u:object_r:postfix_spool_t:s0 tclass=fifo_file

type=SYSCALL msg=audit(1564228663.666:56): arch=c000003e syscall=87 success=yes exit=0 a0=7fe547df0da0 a1=192 a2=1 a3=7fff061802c0 items=0 ppid=1 pid=2419 auid=0 uid=0 gid=0 euid=89 suid=0 fsuid=89 egid=89 sgid=0 fsgid=89 tty=(none) ses=2 comm="master" exe="/usr/libexec/postfix/master" subj=unconfined_u:system_r:postfix_master_t:s0 key=(null)

type=AVC msg=audit(1564228663.667:57): avc:  denied  { create } for  pid=2419 comm="master" name="pickup" scontext=unconfined_u:system_r:postfix_master_t:s0 tcontext=unconfined_u:object_r:postfix_spool_t:s0 tclass=fifo_file

type=SYSCALL msg=audit(1564228663.667:57): arch=c000003e syscall=133 success=yes exit=0 a0=7fe547df0da0 a1=1192 a2=0 a3=7fff061802c0 items=0 ppid=1 pid=2419 auid=0 uid=0 gid=0 euid=89 suid=0 fsuid=89 egid=89 sgid=0 fsgid=89 tty=(none) ses=2 comm="master" exe="/usr/libexec/postfix/master" subj=unconfined_u:system_r:postfix_master_t:s0 key=(null)

type=AVC msg=audit(1564228663.667:58): avc:  denied  { read write } for  pid=2419 comm="master" name="pickup" dev=dm-0 ino=259254 scontext=unconfined_u:system_r:postfix_master_t:s0 tcontext=unconfined_u:object_r:postfix_spool_t:s0 tclass=fifo_file

type=AVC msg=audit(1564228663.667:58): avc:  denied  { open } for  pid=2419 comm="master" name="pickup" dev=dm-0 ino=259254 scontext=unconfined_u:system_r:postfix_master_t:s0 tcontext=unconfined_u:object_r:postfix_spool_t:s0 tclass=fifo_file

type=SYSCALL msg=audit(1564228663.667:58): arch=c000003e syscall=2 success=yes exit=17 a0=7fe547df0da0 a1=802 a2=0 a3=7fff061802c0 items=0 ppid=1 pid=2419 auid=0 uid=0 gid=0 euid=89 suid=0 fsuid=89 egid=89 sgid=0 fsgid=89 tty=(none) ses=2 comm="master" exe="/usr/libexec/postfix/master" subj=unconfined_u:system_r:postfix_master_t:s0 key=(null)

type=AVC msg=audit(1564228663.667:59): avc:  denied  { getattr } for  pid=2419 comm="master" path="/var/spool/postfix-sub/public/pickup" dev=dm-0 ino=259254 scontext=unconfined_u:system_r:postfix_master_t:s0 tcontext=unconfined_u:object_r:postfix_spool_t:s0 tclass=fifo_file

type=SYSCALL msg=audit(1564228663.667:59): arch=c000003e syscall=5 success=yes exit=0 a0=11 a1=7fff06180540 a2=7fff06180540 a3=7fff061802a0 items=0 ppid=1 pid=2419 auid=0 uid=0 gid=0 euid=89 suid=0 fsuid=89 egid=89 sgid=0 fsgid=89 tty=(none) ses=2 comm="master" exe="/usr/libexec/postfix/master" subj=unconfined_u:system_r:postfix_master_t:s0 key=(null)

type=AVC msg=audit(1564228663.668:60): avc:  denied  { setattr } for  pid=2419 comm="master" name="pickup" dev=dm-0 ino=259254 scontext=unconfined_u:system_r:postfix_master_t:s0 tcontext=unconfined_u:object_r:postfix_spool_t:s0 tclass=fifo_file

type=SYSCALL msg=audit(1564228663.668:60): arch=c000003e syscall=91 success=yes exit=0 a0=11 a1=192 a2=7fff06180540 a3=7fff061802c0 items=0 ppid=1 pid=2419 auid=0 uid=0 gid=0 euid=89 suid=0 fsuid=89 egid=89 sgid=0 fsgid=89 tty=(none) ses=2 comm="master" exe="/usr/libexec/postfix/master" subj=unconfined_u:system_r:postfix_master_t:s0 key=(null)

type=AVC msg=audit(1564228663.668:61): avc:  denied  { ioctl } for  pid=2419 comm="master" path="/var/spool/postfix-sub/public/pickup" dev=dm-0 ino=259254 scontext=unconfined_u:system_r:postfix_master_t:s0 tcontext=unconfined_u:object_r:postfix_spool_t:s0 tclass=fifo_file

type=SYSCALL msg=audit(1564228663.668:61): arch=c000003e syscall=16 success=yes exit=0 a0=11 a1=541b a2=7fff0618052c a3=7fff061802a0 items=0 ppid=1 pid=2419 auid=0 uid=0 gid=0 euid=89 suid=0 fsuid=89 egid=89 sgid=0 fsgid=89 tty=(none) ses=2 comm="master" exe="/usr/libexec/postfix/master" subj=unconfined_u:system_r:postfix_master_t:s0 key=(null)

type=AVC msg=audit(1564228663.668:62): avc:  denied  { unlink } for  pid=2419 comm="master" name="cleanup" dev=dm-0 ino=259255 scontext=unconfined_u:system_r:postfix_master_t:s0 tcontext=system_u:object_r:postfix_spool_t:s0 tclass=sock_file

type=SYSCALL msg=audit(1564228663.668:62): arch=c000003e syscall=87 success=yes exit=0 a0=7fe547df1230 a1=1 a2=0 a3=7fff06180340 items=0 ppid=1 pid=2419 auid=0 uid=0 gid=0 euid=89 suid=0 fsuid=89 egid=89 sgid=0 fsgid=89 tty=(none) ses=2 comm="master" exe="/usr/libexec/postfix/master" subj=unconfined_u:system_r:postfix_master_t:s0 key=(null)

type=AVC msg=audit(1564228663.669:63): avc:  denied  { create } for  pid=2419 comm="master" name="cleanup" scontext=unconfined_u:system_r:postfix_master_t:s0 tcontext=unconfined_u:object_r:postfix_spool_t:s0 tclass=sock_file

type=SYSCALL msg=audit(1564228663.669:63): arch=c000003e syscall=49 success=yes exit=0 a0=14 a1=7fff061805c0 a2=6e a3=7fff06180340 items=0 ppid=1 pid=2419 auid=0 uid=0 gid=0 euid=89 suid=0 fsuid=89 egid=89 sgid=0 fsgid=89 tty=(none) ses=2 comm="master" exe="/usr/libexec/postfix/master" subj=unconfined_u:system_r:postfix_master_t:s0 key=(null)

type=AVC msg=audit(1564228663.669:64): avc:  denied  { setattr } for  pid=2419 comm="master" name="cleanup" dev=dm-0 ino=259255 scontext=unconfined_u:system_r:postfix_master_t:s0 tcontext=unconfined_u:object_r:postfix_spool_t:s0 tclass=sock_file

type=SYSCALL msg=audit(1564228663.669:64): arch=c000003e syscall=90 success=yes exit=0 a0=7fe547df1230 a1=1b6 a2=6e a3=7fff06180340 items=0 ppid=1 pid=2419 auid=0 uid=0 gid=0 euid=89 suid=0 fsuid=89 egid=89 sgid=0 fsgid=89 tty=(none) ses=2 comm="master" exe="/usr/libexec/postfix/master" subj=unconfined_u:system_r:postfix_master_t:s0 key=(null)

type=AVC msg=audit(1564228663.672:65): avc:  denied  { read write } for  pid=2422 comm="qmgr" path="/var/spool/postfix-sub/public/qmgr" dev=dm-0 ino=259256 scontext=unconfined_u:system_r:postfix_qmgr_t:s0 tcontext=unconfined_u:object_r:postfix_spool_t:s0 tclass=fifo_file

type=SYSCALL msg=audit(1564228663.672:65): arch=c000003e syscall=59 success=yes exit=0 a0=7fe547df0a40 a1=7fe547df1850 a2=7fe547ded490 a3=7fff0617ff90 items=0 ppid=2419 pid=2422 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=2 comm="qmgr" exe="/usr/libexec/postfix/qmgr" subj=unconfined_u:system_r:postfix_qmgr_t:s0 key=(null)

type=AVC msg=audit(1564228663.675:66): avc:  denied  { read write } for  pid=2421 comm="pickup" path="/var/spool/postfix-sub/public/pickup" dev=dm-0 ino=259254 scontext=unconfined_u:system_r:postfix_pickup_t:s0 tcontext=unconfined_u:object_r:postfix_spool_t:s0 tclass=fifo_file

type=SYSCALL msg=audit(1564228663.675:66): arch=c000003e syscall=59 success=yes exit=0 a0=7fe547df0df0 a1=7fe547df0c10 a2=7fe547ded490 a3=7fff0617ff90 items=0 ppid=2419 pid=2421 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=2 comm="pickup" exe="/usr/libexec/postfix/pickup" subj=unconfined_u:system_r:postfix_pickup_t:s0 key=(null)









prev.gif