Postfix (MTA) — 段階構築ガイド
作成: Shintaro / Acia
対象OS: Debian 13 (Sakura VPS)
表記方針: 変数を用いた抽象化を採用し、一貫性を保つ。
<DOMAIN>: 運用ドメイン(例:example.com)<MAIL_HOST>: メールホストのFQDN(例:mail.<DOMAIN>→mail.example.com)<MAIN_USER>: 常用ユーザ(例:main_user)
目的
教材・再現性を重視し、まず 非SSL で Postfix を最小構成で動作させたのち、段階的に TLS(Submission/SMTPS)+SASL(Dovecot連携) を導入する。
また、root/postmaster 宛メールの常用ユーザ転送を設定し、運用通知が見落とされないようにする。
構成方針
- Part 1(非SSL): MTA 基本動作(25/tcp)・ローカル配送・メールエイリアス設定
- Part 2(TLS拡張): Submission(587) / SMTPS(465)・SASL(Dovecot)・証明書導入(Apache 章で発行済みの SAN 証明書を共用)
- 認証や IMAP は 08_dovecot.md と連携して段階導入する
前提
- UFW/パケットフィルタは閉じたまま作業し、完成後に必要ポートのみ開放(攻撃面積最小化)
- 設定編集は vi 前提(
sudo vi <path>) - 証明書は 06_apache.md で Let’s Encrypt(webroot方式)により発行済み
- SAN:
<DOMAIN>,www.<DOMAIN>,<MAIL_HOST>(例:example.com,www.example.com,mail.example.com) - 実体パス:
/etc/letsencrypt/live/<DOMAIN>/{fullchain.pem,privkey.pem} - ログは systemd-journald が標準(
/var/log/mail.log非生成の可能性あり / rsyslog で復活可) - Postfix 3.9 以降では
smtpd_use_tlsは非推奨となり、**smtpd_tls_security_levelでの制御**が推奨される(本書はこの方針を採用)。
Part 1: 基本構築(非SSL)
1.1 インストール
sudo apt update
sudo apt install -y postfix mailutils
セットアップ画面では 「インターネットサイト」 を選択し、システムメール名は
<DOMAIN>を指定。
1.2 基本設定(/etc/postfix/main.cf)
sudo vi /etc/postfix/main.cf
以下を確認・必要に応じて追記:
myhostname = <MAIL_HOST>
mydomain = <DOMAIN>
myorigin = /etc/mailname
inet_interfaces = all
inet_protocols = ipv4
mydestination = $myhostname, $mydomain, localhost
home_mailbox = Maildir/
# エイリアスDB
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
補足:
mydomainは未指定でも$myhostnameから自動導出されるが、/etc/mailname(=myorigin)と整合を取るため 明示指定を推奨。mydestinationに$mydomainを含めないと、自ドメイン宛のローカル配送を受けないケースがある。home_mailbox = Maildir/を用いる場合、後段の Dovecot をmail_driver = maildir/mail_path = ~/Maildirに合わせる。
1.3 /etc/mailname の確認(Fromドメインの源泉)
cat /etc/mailname
# => <DOMAIN> が入っていること
- 外部送信時の From は原則
/etc/mailnameに従い、<USER>@<DOMAIN>となる。 - ローカル配送時の内部ログでは、
@server.<DOMAIN>や@<MAIL_HOST>が現れる場合がある(内部識別用途)。
1.4 メール転送(root / postmaster → 常用ユーザ)
sudo vi /etc/aliases
末尾に追記:
postmaster: <MAIN_USER>
root: <MAIN_USER>
反映:
sudo newaliases
# もしくは
sudo postalias /etc/aliases
注意: /etc/aliases は「エイリアス形式」(name: value)。postmap は汎用DB用のため、エイリアス生成は **newaliases / postalias** を使用。
1.5 起動・有効化
sudo systemctl enable --now postfix
sudo systemctl status postfix
1.6 稼働・設定確認(sudo 付与を徹底)
# 現在有効な main.cf の差分表示
sudo postconf -n | egrep 'myhostname|mydomain|myorigin|mydestination|home_mailbox'
# 整合チェック
hostnamectl # ホスト名(例:server.<DOMAIN>)
cat /etc/mailname # => <DOMAIN>
1.7 動作確認(ローカル配送)
echo "Test from Postfix (non-SSL)" | mail -s "Postfix Non-SSL Test" <MAIN_USER>
ログ確認(Debian 13 標準: journald)
sudo journalctl -u postfix -n 50
/var/log/mail.logが必要ならrsyslogを導入:
sudo apt install -y rsyslog
sudo systemctl enable --now rsyslog
# /etc/rsyslog.d/50-default.conf の mail.* 行がコメントアウトされていないことを確認
sudo systemctl restart rsyslog
sudo tail -n 50 /var/log/mail.log
1.8 Maildir と Dovecot の整合(予告)
- 本書は
home_mailbox = Maildir/を採用。 - Dovecot 側は
mail_driver = maildir/mail_path = ~/Maildirに合わせる(08_dovecot.md で実施)。
Part 2: TLS & Submission/SMTPS & SASL 拡張
2.0 前提(証明書・ホスト名・TLSポリシー)
- 証明書は Apache 章(06_apache.md)で取得した 1枚の SAN 証明書 を共用する。
- SAN:
<DOMAIN>,www.<DOMAIN>,<MAIL_HOST>(例:example.com,www.example.com,mail.example.com) - 実体パス:
/etc/letsencrypt/live/<DOMAIN>/{fullchain.pem,privkey.pem} - メールホスト FQDN は
<MAIL_HOST> = mail.<DOMAIN>とし、クライアントの接続先も<MAIL_HOST>を指定する。 - TLS セキュリティレベルの方針:
- 25/tcp(MTA 間):
may(opportunistic TLS) - 587/tcp(Submission):
encrypt(クライアント接続時は TLS 必須) - 465/tcp(SMTPS):
encrypt(wrapper TLS 前提)
2.1 追加パッケージ(SASL/Dovecot連携)
sudo apt install -y libsasl2-modules dovecot-core dovecot-imapd
Dovecot は SASL バックエンドとして利用(Dovecot 側の詳細は 08_dovecot.md)。
2.2 master.cf(Submission/SMTPS を有効化)
sudo vi /etc/postfix/master.cf
コメントアウト定義を有効化し、以下のように設定:
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
submission/smtps は「認証前提 + TLS必須」の入口として運用する。
2.3 main.cf(TLS/SASL 設定の追記)
sudo vi /etc/postfix/main.cf
以下を追記:
# TLS(サーバ証明書)— Apache/Dovecot と共用
smtpd_tls_cert_file = /etc/letsencrypt/live/<DOMAIN>/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/<DOMAIN>/privkey.pem
smtpd_tls_auth_only = yes
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
# 25/tcp(MTA 間)は opportunistic TLS
smtpd_tls_security_level = may
# 送信時TLS(outbound)
smtp_tls_security_level = may
smtp_tls_loglevel = 1
# SASL(Dovecot 連携)
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
Postfix 3.9 以降では
smtpd_use_tlsを指定するとsupport for parameter "smtpd_use_tls" will be removed警告が出るため、 本書では **smtpd_use_tlsは使用せずsmtpd_tls_security_levelで統一**する。 SASL 認証自体は Dovecot のservice auth { unix_listener /var/spool/postfix/private/auth ... }設定とセットで動作する(詳細は 08_dovecot.md Part 2 を参照)。
2.4 証明書 & 権限(Let's Encrypt)
- 証明書の実体:
/etc/letsencrypt/live/<DOMAIN>/{fullchain.pem,privkey.pem} - 実際の鍵ファイル(
/etc/letsencrypt/archive/<DOMAIN>/privkeyN.pem)は、通常-rw------- root:root(600)で作成される。 - Postfix/Dovecot は master プロセス(root 権限)が起動時に鍵を読み込むため、このパーミッションでも動作はする。
- ただし、将来のポリシー変更や AppArmor/SELinux 導入時の安定性を考慮し、
ssl-certグループ運用を前提とする。
Postfix / Dovecot を ssl-cert グループに参加させる:
sudo usermod -aG ssl-cert postfix
sudo usermod -aG ssl-cert dovecot
Apache/Dovecot/Postfix で証明書を共用する設計(06_apache.md 参照)。 鍵の実体パーミッションが 600 のままでも動作するが、 グループを付与しておくことで 640(root:ssl-cert) 運用へ移行した場合も安定して動作する。
2.5 反映・リスン確認
sudo postfix check && sudo systemctl reload postfix
ss -tulpen | egrep ':25|:465|:587'
2.6 検証
- Submission(587):
openssl s_client -starttls smtp -connect <MAIL_HOST>:587 -servername <MAIL_HOST>
TLSハンドシェイク完了後、対話的に以下を入力して応答を確認する:
EHLO test
250-AUTH PLAIN LOGIN など、AUTH メカニズムが広告されていることを確認。
- SMTPS(465):
openssl s_client -connect <MAIL_HOST>:465 -servername <MAIL_HOST>
- 送信テスト(swaks 例):
sudo apt install -y swaks
swaks --to you@example.net \
--server <MAIL_HOST> \
--auth-user USER --auth-pass PASS \
--auth PLAIN --tls
トラブルシュート(今回判明したポイント)
- **
smtpd_use_tlsの警告(Postfix 3.9 以降)** sudo postfix check実行時に
`support for parameter "smtpd_use_tls" will be removed; instead, specify "smtpd_tls_security_level"`
と警告が出る場合、`main.cf` から `smtpd_use_tls` 行を削除し、
本書のように `smtpd_tls_security_level` を利用する。
- 465/587 で TLS エラーが出る場合
wrong version number→ 587 で-starttls smtpを付け忘れていないか確認する。no peer certificate available→smtpd_tls_cert_file/smtpd_tls_key_fileのパスや権限を確認。write:errno=104→ 鍵が読めずプロセスが落ちている場合があるため、journalctl -u postfixを確認。
- 鍵の権限まわりで不安な場合
id postfix/id dovecotでssl-certグループ所属を確認。grep ssl-cert /etc/groupでメンバー一覧を確認。- Let’s Encrypt 更新後は 06_apache.md の deploy hook により Postfix/Dovecot が reload される。
運用ノート(Part 1/2 共通)
- まだ外部公開はしない段階では、UFW/パケットフィルタで 25/465/587/993 は閉のまま。
- トラブルシュート時は、sudo付きで以下を使用:
sudo postconf -n
sudo postfix check
sudo journalctl -u postfix -n 100
sudo postalias -q root /etc/aliases
- ログ例の
from=<user@server.<DOMAIN>>,to=<user@<MAIL_HOST>>は内部配送上の表記。
外部送信(submission)時は user@<DOMAIN> になる。
- UFW は 25/465/587 をサービス完成後に開放:
sudo ufw allow 25/tcp
sudo ufw allow 587/tcp
sudo ufw allow 465/tcp
- Fail2ban は 05 章参照(
[postfix]はfilter = postfix[mode=auth]を利用)。 - 送信ドメイン認証(SPF/DKIM/DMARC)は 09_mail-auth.md を参照。
- certbot 更新後の
postfix reloadは 06_apache.md の deploy hook でカバー可能。
変更履歴
| 日付 | 編集者 | 内容 |
|---|---|---|
| 2025-10-28 | Shintaro / Acia | Part 1 全面改訂:sudo 統一、mydomain/myorigin 整合解説、aliases 正式手順、journald/rsyslog 補足、Maildir/Dovecot 予告を追加。 |
| 2025-11-19 | Acia | Part 2 を TLS/SASL 設計と Apache 章の SAN 証明書前提に合わせて全面整理。<DOMAIN> 抽象化・<MAIL_HOST> 利用・TLSポリシー(25/587/465)を明記し、Dovecot SASL 連携との関係を追記。 |
| 2025-11-21 | Acia | Postfix 3.9 における smtpd_use_tls 非推奨を反映し、smtpd_tls_security_level ベースの記述に統一。Let’s Encrypt 鍵のパーミッションと ssl-cert グループ運用、openssl による検証手順・典型的なTLSエラーの対処を追記。 |