スマートフォン・タブレットからインターネットサーバーオペレーション

APPW.jp
 
ConoHa VPS移設記/2GB・3コア → 4GB・4コア/Ubuntu 26.04 LTS

⑧ Dovecot、Postfix

「十数年前から見様見真似でほぼ見直していない」というメールサーバー構成を棚卸ししたところ、 5ドメインのうち3ドメインにSPFもDKIMも存在しないという発見からスタートし、 Dovecot 2.4での設定書式の全面刷新、postscreenとGmail大量送信IPの相性問題まで、 今回の移設シリーズの中で最も長丁場になった回。

作業端末: iPad mini(Termius)+ DNSレジストラ管理画面

MIGRATION ROADMAP — 全17工程
  1. ① SSH、ユーザー追加
  2. ② IPv4/IPv6追加、netplan、ufw
  3. ③ Apache2
  4. ④ Let's Encrypt
  5. ⑤ PHP
  6. ⑥ MariaDB
  7. ⑦ WordPress
  8. ⑧ Dovecot、Postfix
  9. ⑨ Vsftpd
  10. ⑩ Python
  11. ⑪ llama.cpp、ChromaDB
  12. ⑫ Anaconda、Keras、TensorFlow
  13. ⑬ Node.js
  14. ⑭ MongoDB
  15. ⑮ Mosquitto
  16. ⑯ RabbitMQ
  17. ⑰ Supervisor

01Postfix設定の棚卸し

旧サーバーのmain.cf・master.cfは骨格自体しっかりしていた(仮想メールボックス構成、Dovecot経由SASL認証、submission/smtpsが認証必須で閉じられている)。 その上で見つかった主な論点は次の通り。

  • IPv4限定だった(inet_protocols = ipv4)→ 標準IPv6にPTRを設定した上でipv4, ipv6へ拡張
  • postscreen未使用 → リソース制約のあるVPSと相性が良いため新規追加
  • vmailのuid/gid=901固定 → 新サーバーで自動採番に任せず明示的に作成する必要あり
  • master.cfの未使用パイプ定義(uucp、ifmail、bsmtp、mailman等)→ 削除

02メールホスト名をwww.ドメインからmail.ドメインへ

旧サーバーのmyhostnameがwww.ドメインだった点を見直すことにした。1つの変更のようで、実際には連動する箇所が多い。

変更箇所内容
DNS A/AAAAmail.ドメインを新規追加
PTR(逆引き)ConoHa側でmail.ドメインへ設定
MX(5ドメイン)mail.ドメインへ向ける
TLS証明書gwaw.jpの証明書にmail.ドメインをSAN追加(Expand)
main.cfmyhostname、証明書パスを変更

03SPF・DKIM監査で判明した最大の発見

旧サーバーのSPFレコードを確認したところ、gwaw.jpはv=spf1 mx a ip4:(旧IP) -allという記述だった。 aメカニズムは「ドメインのAレコードが指すIP」を許可する意味だが、②の設計ではWeb用IPとメール送信元IPが別になるため、このままでは意図とズレる。

3ドメインにSPF・DKIMが存在しなかった appw.jp・ibe.tokyo・iseeit.jpの3ドメインは、MXレコードのみでSPFが未設定。OpenDKIMのKeyTable/SigningTableを確認したところ、DKIM鍵もgwaw.jpとsasagawa.tokyoの2ドメイン分しか存在しなかった。つまりこの3ドメインは10年以上、送信ドメイン認証が事実上ゼロだった可能性が高い。

残り3ドメイン分のDKIM鍵を新規生成し、5ドメイン共通でSPF・DKIM・DMARC(p=noneで観測から開始)を整備した。

DNS最終形(5ドメイン共通パターン)
MX ドメイン. 10 mail.ドメイン. TXT ドメイン. v=spf1 mx ip4:標準IPv4 ip6:標準IPv6 -all TXT default._domainkey.ドメイン. (DKIM公開鍵) TXT _dmarc.ドメイン. v=DMARC1; p=none; rua=mailto:login-user@ドメイン

DMARCレポート受信用にlogin-user@ドメインを新規メールボックスとして作成。OpenDKIMのTrustedHostsも旧サーバーのIPから新サーバーの標準IPv4/IPv6へ更新した。

04Dovecot 2.4:設定書式が全面刷新されていた

新サーバーにdovecotを入れて設定ファイルを見比べたところ、旧サーバーとは構文そのものが別物だった。バージョンは2.4.2。

後方互換なし Dovecot 2.4の公式リリースノートに明記されている通り、"old configuration files do not work without rewrite"。単純なコピーやdiffでの見比べは通用せず、旧設定の意味を1つずつ確認しながら新書式へ書き換える作業になった。
ファイル主な変更
10-auth.confauth-system.conf.extを無効化、auth-passwdfile.conf.extのみ有効化
auth-passwdfile.conf.extpassdb { driver = passwd-file args = ... } → passdb passwd-file { default_password_scheme = CRAM-MD5 ... }
auth-static.conf.extuid/gid/home固定をuserdb static { fields { ... } }として復活(後述の理由)
10-mail.confmail_location = maildir:~/Maildir → mail_driver = maildir / mail_path = ~/Maildir
10-ssl.confssl_cert/ssl_key(<付き) → ssl_server_cert_file/ssl_server_key_file(素のパス)
10-master.confPostfix連携用unix_listener /var/spool/postfix/private/dovecot-authを新規追加。新テンプレートに追加されたservice submission-loginはPostfixとポート衝突するため無効化

05実運用トラブルシューティング集

設定を書き終えても、実際に送受信テストをしてみないと見えない問題がいくつも出た。以下、発生順の記録。

userdb staticのhomeパスが誤っていた

最初userdb passwd-file { fields { uid:default = vmail ... } }という書き方を試したが、これは機能しなかった。 実際に動作する2.4系の構成では、uid/gid/homeが全ユーザー共通の固定値ならuserdb staticを使うのが正しいパターンだった。

さらに、そのhomeの組み立て方でも一度間違えた。Postfix側(vmailbox)はドメイン名/ローカル部分/Maildir/という階層だが、 最初はhome = /var/spool/vmail/%{user}(メールアドレス全体を1階層に)としてしまい、Postfixが書き込む場所とDovecotが読みに行く場所が食い違っていた。 doveadm mailbox status -u ユーザー messages INBOXでmessages=0と出たことで発覚。

auth-static.conf.ext(最終版)
userdb static { fields { uid = vmail gid = vmail home = /var/spool/vmail/%{user | domain}/%{user | username} } }

/var/spool/vmail自体の作成漏れ

scpで各ドメインのメールボックス実体をコピーした際、親ディレクトリ/var/spool/vmail自体の所有者をvmailにし忘れていた。 新規アドレス(login-user@ドメイン)の初回ログイン時にMaildir自動作成がPermission deniedで失敗して発覚。

vmailboxの.dbファイル再生成忘れ

新規メールアドレスをvmailboxに追記した後、テキストファイルは正しいのにpostmapでのハッシュDB再生成を忘れており、 Gmailからの返信が550 5.1.1 User unknown in virtual mailbox tableで弾かれた。

login-user@新サーバー
$ sudo postmap /etc/postfix/vmailbox $ sudo systemctl reload postfix

postscreenとGmailの大量送信IPが相性が悪い

Gmail宛送信は成功したが、Gmailからの返信は450 4.3.2 Service currently unavailableで複数回はじかれた。 ログを追うと3回とも異なる送信元IPからの接続で、これはpostscreenが「未知のIP」を初回だけ足止めする一方、 Googleの送信基盤が非常に多くのIPへ再送を分散させるため、いつまで経っても「既知のIP」にならず通過できないという既知の相性問題だった。

対策として、Googleが公開する送信元IP帯(dig +short txt _spf.google.comで取得)をpostscreenの検査対象外にした。

/etc/postfix/postscreen_access.cidr
74.125.0.0/16 permit 209.85.128.0/17 permit 2001:4860:4864::/56 permit 2404:6800:4864::/56 permit 2607:f8b0:4864::/56 permit 2800:3f0:4864::/56 permit 2a00:1450:4864::/56 permit 2c0f:fb50:4864::/56 permit

main.cfにpostscreen_access_list = permit_mynetworks, cidr:/etc/postfix/postscreen_access.cidrを追加。 他の大手プロバイダで同様の現象が出た場合も同じパターンで追加できる。

login-userのcrontabにMAILTOがなくSSHログイン時に通知が溜まっていた

⑦で組んだcrontabのうち、wp core update等6行だけ標準出力のリダイレクト先を指定し忘れており、 cronのデフォルト動作でwebm宛のローカルメールとして配送され続けていた。SSHログイン時の「You have new mail.」で発覚。 出力先をログファイルへ変更し、保険としてMAILTO=""も追加した。

postfix checkの警告群

警告対応
smtpd_use_tlsは非推奨smtpd_tls_security_levelと重複のため削除
milterdefaultactionは無効なパラメータ正しくはmilter_default_actionだが、あえて未設定のままにしてPostfix既定の安全側動作(tempfail)を活用
nonsmtpdmiltersは無効なパラメータ正しくはnon_smtpd_milters。修正しないとWordPress等ローカル生成メールにDKIM署名がかからない
resolv.confの所有者ズレscpコピー時の所有者残留。root:rootへ変更

06ここまでの状態

  • 5ドメイン共通でSPF・DKIM・DMARCを整備(うち3ドメインは今回初めて認証設定が入った)
  • Dovecot 2.4の新書式へ全ファイルを書き換え、実際にIMAP/POP3ログイン・受信を確認済み
  • postscreen導入+Google送信元IP帯のホワイトリストで、Gmailとの送受信を確認済み
  • sudo postfix checkが無出力になるまで警告を解消
← 前回: ⑦ WordPress 次回: ⑨ Vsftpd →

『ConoHa VPS移設記 ⑧ Dovecot、Postfix』を公開しました。