- ① SSH、ユーザー追加
- ② IPv4/IPv6追加、netplan、ufw
- ③ Apache2
- ④ Let's Encrypt
- ⑤ PHP
- ⑥ MariaDB
- ⑦ WordPress
- ⑧ Dovecot、Postfix
- ⑨ Vsftpd
- ⑩ Python
- ⑪ llama.cpp、ChromaDB
- ⑫ Anaconda、Keras、TensorFlow
- ⑬ Node.js
- ⑭ MongoDB
- ⑮ Mosquitto
- ⑯ RabbitMQ
- ⑰ 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/AAAA | mail.ドメインを新規追加 |
| PTR(逆引き) | ConoHa側でmail.ドメインへ設定 |
| MX(5ドメイン) | mail.ドメインへ向ける |
| TLS証明書 | gwaw.jpの証明書にmail.ドメインをSAN追加(Expand) |
| main.cf | myhostname、証明書パスを変更 |
03SPF・DKIM監査で判明した最大の発見
旧サーバーのSPFレコードを確認したところ、gwaw.jpはv=spf1 mx a ip4:(旧IP) -allという記述だった。
aメカニズムは「ドメインのAレコードが指すIP」を許可する意味だが、②の設計ではWeb用IPとメール送信元IPが別になるため、このままでは意図とズレる。
残り3ドメイン分のDKIM鍵を新規生成し、5ドメイン共通でSPF・DKIM・DMARC(p=noneで観測から開始)を整備した。
DMARCレポート受信用にlogin-user@ドメインを新規メールボックスとして作成。OpenDKIMのTrustedHostsも旧サーバーのIPから新サーバーの標準IPv4/IPv6へ更新した。
04Dovecot 2.4:設定書式が全面刷新されていた
新サーバーにdovecotを入れて設定ファイルを見比べたところ、旧サーバーとは構文そのものが別物だった。バージョンは2.4.2。
| ファイル | 主な変更 |
|---|---|
| 10-auth.conf | auth-system.conf.extを無効化、auth-passwdfile.conf.extのみ有効化 |
| auth-passwdfile.conf.ext | passdb { driver = passwd-file args = ... } → passdb passwd-file { default_password_scheme = CRAM-MD5 ... } |
| auth-static.conf.ext | uid/gid/home固定をuserdb static { fields { ... } }として復活(後述の理由) |
| 10-mail.conf | mail_location = maildir:~/Maildir → mail_driver = maildir / mail_path = ~/Maildir |
| 10-ssl.conf | ssl_cert/ssl_key(<付き) → ssl_server_cert_file/ssl_server_key_file(素のパス) |
| 10-master.conf | Postfix連携用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と出たことで発覚。
/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で弾かれた。
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の検査対象外にした。
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が無出力になるまで警告を解消