Postfix:メモ
Postfix 公式
Postfix で厄介なのは、所々で設定名と実態とが食い違っている点。
各種誤解による歴史的経緯が積み重なった結果と思われる。
また、エイリアスと本当の設定が区別なく混在している点。
smtp_* は(ほぼ)送信時の設定
smtpd_* は(ほぼ)受信時の設定
設定は1000近く存在するため、すべてを理解しようとすると数週間はかかるはず。
機能が正しく分かれていないため、設定を綺麗に分けたくても分けることができない。
現在の設定を表示する。
$ postconf
すべての設定を表示する。
$ postconf -v
デフォルトの設定(コンパイル時設定+現在環境)を表示する。
$ postconf -d
何をどれだけ設定すべきなのか?
順番に必須機能を追いながら考える。
設定ファイルは主に /etc/postfix/main.cf と /etc/postfix/master.cf の2つ。
main.cf の設定方式は典型的な key = value 形式。
複数行に書く場合は、次の行の先頭が空白であること。
定義を参照する場合は $設定名 で読み出せる。
設定ファイルのバージョン指定
code:main.cf.fragment.compatibility_level
#% compatibility_level = 0 compatibility_level = 3.7
compatibility_level をPostfix のバージョン(マイナーまで)合わせるのが現状では正しい。
(2023-02-18 時点で 3.7 が最新。Debian 11 のパッケージでは 3.5 になっていた。)
2 以下だと古いバージョンによる設定と認識されてしまう。
0 (デフォルト値)が最も古い設定になっている。(compatibility_level の設定が現れる前と認識される。)
この設定がないと、デフォルトの挙動まで変わってしまうので要注意。
ログをどこにどう残すか?
code:main.cf.fragment.logging
#% syslog_facility = mail #% syslog_name = ${multi_instance_name?{$multi_instance_name}:{postfix}} 最初のデーモンの起動
Ubuntu, Debian では /etc/init.d/postfix に起動スクリプトがある。
以下のコマンドで起動する。
$ service postfix start
systemd 系
$ systemctl start postfix
postfix.service が /etc/systemd の下あたりにあるはず。(シンボリックリンクになってる)
起動するデーモン
/etc/postfix/master.cf (以下 master.cf と記述)で起動するデーモンとポートを指定する。
code:/etc/postfix/master.cf.fragment
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (no) (never) (100)
# ==========================================================================
smtp inet n - y - - smtpd
#smtp inet n - y - 1 postscreen サーバーの待ち受けIPアドレスとポート番号
サーバーとして一般的な受信用SMTPサーバーと、送信用SMTPサーバーとがある。
どのIPアドレスで待ち受けをするか?
/etc/postfix/main.cf (以下 main.cf と記述) の inet_interfaces で待ち受けIPアドレスを指定する。
IPv6 と IPv4 のどちらを使うかを inet_protocols で指定する。:
特に気にしないのであれば all でよい。
code:/etc/postfix/main.cf.fragment.inet_interface
inet_protocols = all
inet_interfaces = all
受信用SMTPサーバーは smtp ポート 25
送信用SMTPサーバーは submission ポート 587 で待ち受けたい。
master.cf ファイルで設定する。
受信用SMTPサーバー
service になっているのがポート番号になる。
code:/etc/postfix/master.cf.fragment.smtp
# service type private unpriv chroot wakeup maxproc command + args
# ...
smtp inet n - y - - smtpd
送信用 SMTP サーバーでは、
受信用 SMTP サーバーとしての設定と少しだけ変えたいため、オプションを指定してずらすことになる。
今は詳細を書かない。
デフォルトではコメントアウトされているのでコメントを取り除く。
code:/etc/postfix/master.cf.fragment
# service type private unpriv chroot wakeup maxproc command + args
# ...
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
# -o smtpd_tls_security_level=encrypt
# ...
自ホスト名
myhostname
ここはホスト名の FQDN が設定されるべき。
自ドメイン名
mydomain
普通は myhostname から最初のサブドメインを取り外したものになる。それで良いなら設定は不要。
信頼できるネットワーク
mynetworks
ほぼデフォルトで構わないはず。
共用サーバーなどでサブネットマスクで隣のサーバーまで見えているようなケースでは書き直す必要がある。
このあたりは名前と実体が正しくつながっていない。
バナーの出力
smtpd_banner で設定する
デフォルトでは myhostname が使われる。
myhostname は設定用のエイリアスになっていて、これそのものが意味を持つわけではない。
以下を見れば分かる
$ postconf -v | grep myhostname
受信、リレーの可否設定
かなり複雑
smtpd_*_restrictions のシリーズが、イベント発生時のアクセス制御をする。
イベントごとに判定を用意している。これは「いつ」判定するかを制御する。「どこで拒否するか」のように見えるがそうではない。(これが混乱の元)
「SMTP アクセス制御リストの評価を遅らせる」にその事情が書かれている。
RCPT TO, ETRN の時まで判定を遅らせるのは、MTAクライアントがコケるため(?)
データ送信前の必要なパラメータがすべて揃うのが RCPT TO, ETRN 時。
ただし、やはり余計な気を回しすぎて失敗している例に見える。
フィルタリングの条件判定を間違えた結果に見える。
そもそも正しいフィルタリングをしていないケースを救えるわけがないが、救おうとしている。
「その後のすべてのコマンドを許す」ためのコマンドと「このコマンドだけは許す」ためのコマンドが別れていない。
現在の仕様を見る限りは「このコマンドだけは許す」が正しく見える。
NOT, AND, OR 条件を直接書くことができない。(致命的)
「Postfix SMTP アクセスポリシー委譲」を見れば分かるが、必要な情報をすべて確認用に引き渡している。
つまり、Postfix が色々間違えたフィルタリングの仕組みは、ポリシーチェックを外出しすれば正しく実行できる。
smtpd_client_restrictions
クライアントの接続時にアクセス制御をする。
smtpd_helo_restrictions
HELO コマンドの時にアクセス制御をする。
smtpd_sender_restrictions
MAIL FROM コマンドの時にアクセス制御をする。
smtpd_recipient_restrictions
RCPT TO コマンドの時にアクセス制御をする。
smtpd_data_restrictions
DATA コマンドの時にアクセス制御をする。
smtpd_end_of_data_restrictions
DATA コマンドの終端(.の受信)の時にアクセス制御をする。
smtpd_etrn_restrictions
ETRN コマンドの時にアクセス制御をする。
smtpd_relay_restrictions
リレー処理のときにアクセス制御をする。
table:search_result
PERMIT 許可
DEFER 一時拒否(4xx)
REJECT 拒否(5xx)
通常は以下のコードが使われる(状況によって異なる)
defer_code = 450
reject_code = 554
ローカル配送するかリレーするかの判定
Envelope To のドメイン名で、mydestination にあるものが自ホスト宛のメールと解釈される。($local_transport が適用される)
リレーを許可するかどうかの判定
relay_domains
送信先ドメイン名(Envelope To のドメイン名)を書く。
これは信頼できない送信元でも対象となる。
サブドメインが自動的に含まれてしまう。
リレーを許可する送信元IPアドレス
mynetworks で設定する。
これは smtpd_relay_restrictions での指定に使われる。
バーチャルドメインの場合
後で書く
バックエンド関連
proxy_read_maps
proxymap サービスにアクセスできるマップ
たぶんいじる必要がない。
メールの送信
sendmail コマンドで行う。
code:console
$ sendmail hisname@example.org
From: yourname@example.com
To: hisname@example.org
Subject: Hello!
Hello!
.
code:console
postdrop: warning: unable to look up public/pickup: No such file or directory
外部への配送の場合
Envelope To での配信判定
判定順
transport_maps どのドメインのメールをどのサーバーに送るかをマップで設定する。
relayhost
DNS MX
fallback_relay すべてのリレーに失敗した時にここに送られる。
Postfix が起動していない