Postfix軍団と内部フロー

2025/10/23
Postfixは、単体の大きなプログラムではなく、小さなプログラム集団です。

master というプログラムがPostfixの司令塔であり、その下にエキゾチックな専門プログラムがいます。
masterをオーケストラの指揮者に例えることもできるし、軍隊の中隊長クラスの指揮官に例えることもできるでしょう。

masterの下には、どんなプログラムがいるでしょうか。代表的なものを紹介します。

受信時の内部処理フロー(smtpd → cleanup)

名称役割
smtpdローカルキュー(/var/spool/postfix/maildrop)から新しいメッセージを拾い、cleanupに渡す。
cleanupメールを標準フォーマットに整形し、ヘッダー追加・検証・フィルタ適用後、キューに登録。
qmgrメールキューの管理。送信順序の制御、宛先ごとの再試行管理。
  1. 外部ポート25(or587)をmasterがlisten。接続要求を受けると、その通信を処理する子プロセス(例:smtpd)をforkして起動します。
  2. smtpd がメールデータをmaster経由で受信。SMTPセッションを受け付けます。メールデータ(DATAコマンド以降)を受け取り、Postfix内部形式に変換します。この段階では、まだファイルとしては保存されません。
  3. smtpd → cleanup への引き渡し。 smtpd は受け取ったメッセージを UNIXドメインソケット /var/spool/postfix/private/cleanup に書き込みます。
  4. cleanup デーモンは常にこのソケットを listen しており、smtpd からのメッセージを順次受け取ります。ファイルを経由せず、プロセス間通信(IPC)で直接渡される仕組みです。
  5. cleanup がメッセージを整形(正規化)しキューに登録。cleanup はメッセージのヘッダ整形、canonicalマップ適用、ヘッダ付与(Received:など)を行い、/var/spool/postfix/incoming/ ディレクトリにメールを一時ファイルとして保存
その後、キューマネージャ(qmgr)がそれを拾い、配送処理へ進みます。
qmgr は常駐しており、常に次のような動作をしています。
  1. /var/spool/postfix/incoming/ を監視して、新しいメール(キューファイル)を検出。
  2. それを /var/spool/postfix/active/ に移動(=配送準備完了)。
  3. メールの宛先ごとに、適切な配送プロセスを選択し、masterに作業依頼を通知(内部IPC-軽量pipe)
  4. masterは、qmgrからの内部IPC通知がきたら、その指示に従って、smtpdやlmtp、localなど用のプロセスを起動(spawn)
たとえば:
  1. ローカルユーザー宛 → local
  2. 仮想ユーザー宛 → virtual(Postfix単独運用の場合でり、あまり使われない)
  3. Dovecot LMTP 宛 → lmtp(外部からのメールはこれが主流)
  4. 外部ドメイン宛 → smtp
各配送プロセスが稼働している間も、qmgrは別の活動も平行し、smtpdやlmtpから完了通知IPCがきたらしたら、成功/失敗を記録します。
qmgrによる結果処理
  • 成功:キューファイルを削除
  • 一時エラー:/var/spool/postfix/deferred/ に移動し、後で再試行
  • 永久エラー:bounceデーモンを起動して不達通知を生成
master の役割はここまで
  • master は smtp プロセスの生死監視のみ行い、
  • プロセス終了コード(0=正常、≠0=異常)を確認して再起動の判断をします。
  • smtp が終了すると master は qmgr に「smtpプロセス終了」の通知を返すのみとなる。

送信時の内部フロー

Linux内部からの送信

  1. pickup ローカル送信(/var/spool/postfix/maildrop)を監視し、新規メールを検出。 sendmailコマンドやシステム通知が出力する場合。
  2. cleanup メールを正規化(ヘッダ付与、canonical/transportマップ展開、ポリシー適用)。キュー登録。 message-id付与などもここ。
  3. qmgr メールキューを管理し、配送順序を決定。配送先ごとにsmtp, local, virtualなど適切なトランスポートを選択。 scheduler の役割。
  4. smtp(または lmtp, virtual, local) 宛先に応じたトランスポートプロセスが実際の配送を実行。外部サーバーへSMTP送信。 smtp_tls_security_level などがここで有効。
  5. bounce(失敗時) 宛先サーバーが拒否・不達の場合に、バウンスメールを生成し、再びpickup経由で通知。 DSN (Delivery Status Notification) を生成。

MUAからの接続による送信時の内部フロー:Submission経由の送信

  1. 外部ポート587をmasterがlisten。接続要求を受けると、その通信を処理する子プロセス(例:smtpd)をforkして起動します。
  2. smtpd (submission) ポート587のデータ(MUAからのデータ)をmaster経由で受信。SASL認証・STARTTLS必須が必須。
  3. smtpd が SMTPハンドシェイク開始(EHLO 応答)
  4. smtpdが内部処理としてSTARTTLSを開始(TLS暗号化)
  5. smtpdが内部処理としてAUTH(SASL認証:PLAIN, LOGIN等)
  6. smtpdがメール内容の受信
  7. cleanup(上と同じ)
  8. qmgr (上と同じ)
  9. smtp 外部サーバーに転送