コンテンツにスキップ

SMTPとPostfix

PostfixはSMTPサーバーとSMTPクライアントの両方として動作し、受け取ったメッセージをキューへ入れて、宛先に対応する配送方法へ渡す。


SMTPは、クライアントがコマンドを送り、サーバーが3桁のステータスコードで応答するプロトコルである。

S: 220 mail.example.com ESMTP Postfix
C: EHLO client.example.net
S: 250-mail.example.com
C: MAIL FROM:<alice@example.net>
S: 250 2.1.0 Ok
C: RCPT TO:<bob@example.com>
S: 250 2.1.5 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: From: alice@example.net
C: To: bob@example.com
C: Subject: test
C:
C: message body
C: .
S: 250 2.0.0 Ok: queued as ...

EHLOはESMTPで利用可能な拡張機能を確認する。SMTP AUTHやSTARTTLSを利用できる場合は、応答の機能一覧にAUTHやSTARTTLSが現れる。

250は要求を受け入れたことを示す。4xxは再試行可能な一時エラー、5xxは再試行しても成功しない恒久エラーである。DATAに対する250は、最終的に受信者が読めたことではなく、そのSMTPサーバーが配送責任を引き受けてキューへ入れたことを示す。


masterはPostfix全体を管理し、master.cfに従って各サービスを起動する。外部からのSMTP接続はsmtpdが受ける。メッセージはcleanupで正規化され、qmgrがキューから配送先を選ぶ。外部MTAへの配送はsmtp、Dovecotへのローカル配送はlmtpが担当する。

SMTP client
-> smtpd
-> cleanup
-> incoming queue
-> qmgr
├─ smtp -> remote MTA
└─ lmtp -> Dovecot LMTP

Postfixが一つの常駐プロセスですべてを処理しないため、ログには同じメッセージについて複数のプロセス名が現れる。キューIDを追うと、受信から配送結果までを対応付けられる。


/etc/postfix/main.cfは、ホスト名、ローカルドメイン、配送先、TLS、SASLなどPostfixの動作パラメーターを設定する。設定はこのファイルへ直接記述し、postconf -nで既定値から変更されたパラメーターを確認する。

/etc/postfix/master.cfは、Postfixが起動するサービス、待受ポート、chrootなどのプロセス属性を定義する。各サービス行の下にある-o name=valueは、そのサービスに限ってmain.cfの値を上書きする。TCP 587のSubmissionだけでSMTP AUTHを有効にし、TCP 25のサーバー間SMTPでは無効にする構成を作れる。

compatibility_levelは、どのPostfixリリースで導入された既定動作を基準にするか指定する。プログラムのバージョンを変更する設定ではない。Debian 13のPostfix 3.10系では3.10を指定し、古いリリース向けの互換既定値を使わない。


待受インターフェースとIPプロトコル

Section titled “待受インターフェースとIPプロトコル”

inet_interfacesは、PostfixのSMTPサービスが待ち受けるローカルインターフェースを決める。allは使用可能なすべてのローカルインターフェースで待ち受ける。

inet_protocolsは、Postfixが接続を受けるときと別のMTAへ接続するときに使うIPプロトコルを決める。ipv4はIPv4だけ、allは利用可能なIPv4とIPv6を使用する。inet_protocolsを変更した後はPostfixを再起動する。


myhostnameはメールサーバー自身の完全修飾ドメイン名であり、SMTPバナーやPostfixが生成するメッセージに使われる。例はmail.example.comである。

mydomainは所属ドメインのexample.comである。myorigin = $mydomainにすると、ローカルコマンドから送信したメールの送信元ドメインとしてexample.comを使う。

mydestinationは、このPostfixが最終配送を担当するドメインの一覧である。ここにexample.comを含めると、そのドメイン宛てのメールをローカルユーザーへ配送する。

mydestinationへ他組織のドメインを誤って入れると、本来の配送先へ転送せず自分のローカル宛先として処理する。

alias_mapsは、ローカル配送時にpostmasterなどのエイリアスを検索するテーブルを指定する。alias_databaseは、newaliasesが索引を作成または更新するテーブルを指定する。

どちらもhash:/etc/aliasesにすると、Postfixは/etc/aliasesの内容を参照し、newaliasesは対応する索引ファイルを更新する。alias_mapsは配送時の検索、alias_databaseは更新対象という役割の違いがある。

mynetworksは、Postfixが信頼するクライアントのアドレス範囲である。この構成ではループバックだけを指定し、LAN全体を無条件に信頼しない。

smtpd_relay_restrictionsは、自サーバーが最終配送先ではないメールを誰に中継させるか決める。permit_mynetworksは信頼ネットワーク、permit_sasl_authenticatedは認証済み利用者を許可し、最後のreject_unauth_destinationはそれ以外の第三者中継を拒否する。この拒否がなければ、第三者が迷惑メール配送に利用できるオープンリレーになり得る。


mailbox_transport = lmtp:unix:private/dovecot-lmtpは、ローカルユーザーのメールボックス配送をPostfix自身のmailbox書き込みではなくDovecot LMTPへ渡す。

private/dovecot-lmtpは/var/spool/postfix/private/dovecot-lmtpを表す。Postfixのqueue directoryからの相対パスにすることで、chrootされたPostfixプロセスからも同じソケットを参照できる。

Dovecotを配送経路に含めることで、Dovecotが認識するメールボックス形式へ一貫して保存できる。PostfixとDovecotが別々に同じメールボックスへ異なる形式で書き込む構成にはしない。


Postfixがサーバーとして使う設定とクライアントとして使う設定

Section titled “Postfixがサーバーとして使う設定とクライアントとして使う設定”

PostfixのTLSパラメーターは、接続を受けるSMTPサーバー側がsmtpd_、他のSMTPサーバーへ接続するSMTPクライアント側がsmtp_で始まる。

smtpd_tls_security_levelは受信接続でSTARTTLSを提供または要求するか決める。smtp_tls_security_levelは送信先がSTARTTLSを提供したときに暗号化するか決める。同じ値を設定しても、制御する通信方向は異なる。


postqueue -pは未配送メッセージのキューを表示する。postqueue -fは配送を再試行する。キューが空ならMail queue is emptyと表示される。

DebianではPostfixのログをjournaldまたはrsyslogで確認する。journalctl -u postfixでサービス単位のログを確認し、メールログが設定されている環境では/var/log/mail.logも確認する。配送障害では、キューID、from=<...>、to=<...>、status=sentまたはstatus=deferredを対応付ける。