- Shell 77%
- Python 23%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .gitignore | ||
| collect-queue.sh | ||
| CUTOVER-CHECKLIST.md | ||
| DENCHOHO-GUIDE.md | ||
| DNS-RECORDS.md | ||
| FORTIGATE-PORT-FORWARDING.md | ||
| FORTIGATE-STATUS.md | ||
| MANUAL.md | ||
| migrate-to-mox.sh | ||
| MIGRATION-20261007.md | ||
| MIGRATION-COMPLETE.md | ||
| OLD-SERVER-INVENTORY.md | ||
| POP3-TO-IMAP-MIGRATION.md | ||
| queue-collect.conf | ||
| QUEUE-COLLECTION-DOCS.md | ||
| queue_to_maildir.py | ||
| README.md | ||
| SPAM-FILTER-GUIDE.md | ||
| TRANSITION-MANUAL.md | ||
Mox メール移行プロジェクト
概要
レガシー Postfix(old)からモダンな Mox(mox)へのメールインフラ移行。対象ホスト: mail.m-seed.biz / メールドメイン: m-seed.biz。
ステータス: ⚠️ フェーズA未完(残: 残りエイリアス8件、admin passwd未検証、TLS未取得、SPF/DKIM/PTR未確認) — ドメイン設定済み、エイリアス~42件追加、adminアカウントへ2257メッセージインポート済み。
1. ネットワーク構成
flowchart LR
subgraph OLDCONF ["旧構成(現行)"]
direction TB
W1([WAN]) --> F1["FT<br/>WAN 202.215.132.212<br/>LAN 192.168.99.1<br/>25/80/110/587→.2"]
F1 --> O2["192.168.99.2<br/>旧メール全部入り<br/>:25/:587/:110/:8080"]
O2 -- "80/443" --> N4["新ipf同居 NPM<br/>:80/:443"]
M100["192.168.88.100 mox<br/>孤立(外部到達なし)"]
N4 -- ":80" --> M100
end
subgraph NEWCONF ["新構成(移行後)"]
direction TB
W2([WAN]) --> F2["FT<br/>WAN 202.215.132.212<br/>LAN 192.168.99.1<br/>全転送先192.168.99.2"]
F2 --> N2["192.168.99.2 新ipf"]
N2 -- ":25/:587/:110<br/>変更なし" --> O110["192.168.88.110<br/>旧メール(移設後)"]
N2 -- ":143/:465/:993" --> M100B["192.168.88.100 mox<br/>IMAP/SMTP本番"]
N2 -- ":80/:443" --> N4B["NPM<br/>www・mail等"]
end
style OLDCONF stroke:#c62828,stroke-width:2px
style NEWCONF stroke:#2e7d32,stroke-width:2px
PVE ネットワーク設定(/etc/network/interfaces):
| ブリッジ | IP | 物理ポート | 用途 |
|---|---|---|---|
| vmbr0 | 192.168.99.99/24 | nic0 | 管理ネットワーク(PVE 専用、ゲートウェイ: 192.168.99.1) |
| vmbr00 | 192.168.99.250/24 | なし | 未使用 |
| vmbr66 | 192.168.66.1/24 | なし | 仮想ネットワーク(NAT 経由) |
| vmbr77 | 192.168.77.1/24 | なし | 仮想ネットワーク(NAT 経由) |
| vmbr88 | 192.168.88.1/24 | なし | 仮想ネットワーク(NAT 経由、mox/old コンテナ接続) |
Fortigate ポートフォワーディング(→ 新ipf: 192.168.99.2):
| WAN ポート | 転送先 IP | 転送先ポート | 用途 |
|---|---|---|---|
| 25 | 192.168.99.2 | 25 | SMTP 受信(他社サーバーから) |
| 587 | 192.168.99.2 | 587 | SMTP Submission(クライアント送信) |
| 465 | 192.168.99.2 | 465 | SMTPS(暗黙的TLS) |
| 110 | 192.168.99.2 | 110 | POP3(旧VM、半年間維持) |
| 993 | 192.168.99.2 | 993 | IMAPS(クライアント受信) |
| 143 | 192.168.99.2 | 143 | IMAP(STARTTLS) |
| 80 | 192.168.99.2 | 80 | ACME/Let's Encrypt 証明書取得 |
| 443 | 192.168.99.2 | 443 | HTTPS(webmail/ACME) |
新ipf転送ルール(99002-ms-ipf-router-npm、nftables正本 /etc/ipf/ipf.nft、管理CLI /usr/local/bin/ipf 2.3.7):
| 受信ポート | 転送先 | 用途 |
|---|---|---|
| 25 | 192.168.88.110:25 | SMTP(旧、変更なし) |
| 587 | 192.168.88.110:587 | Submission(旧、変更なし) |
| 110 | 192.168.88.110:110 | POP3(旧、半年維持) |
| 8080 | 192.168.88.110:8080 | www backend(旧apache) |
| 143 | 192.168.88.100:143 | IMAP(mox) |
| 465 | 192.168.88.100:465 | SMTPS(mox) |
| 993 | 192.168.88.100:993 | IMAPS(mox) |
| 80/443 | 自機NPM | HTTP/HTTPS(転送なし) |
注意:
- DNATは無条件ではなく
iifname eth0付き(外向き通信の巻き込み防止。2026-10-07障害の教訓) - SNATなし(生IP記録・fail2ban有効のため)。88.0/24外向きのみMASQUERADE
- 99.x同一セグメントからの99.2宛旧系ポートは非対称経路で不通に見える。99.xからはbackend直(88.110/88.100)を使うこと。外部経路は正常
サーバー構成
| ホスト名 | 別名 | IP | 役割 | OS / ソフトウェア | 環境 | ブリッジ | ステータス |
|---|---|---|---|---|---|---|---|
| 99002-ms-ipf-router-npm | ipf/npm | 192.168.99.2 + 192.168.88.2 | 転送+NPM+88系ルータ | Ubuntu 26.04 + nftables(ipf 2.3.7) + NPM(podman) | PVE CT | vmbr0+vmbr88系 | 稼働中(2026-10-07新設) |
| m-seed.biz | old | 192.168.99.110 + 192.168.88.110 | 移行元メールサーバー | Ubuntu + Postfix/Courier (Maildir) + apache:8080 | PVE VM | vmbr0系+vmbr88 | 稼働中;GW=88.2 |
| CT88100 | mox | 192.168.88.100 | 移行先メールサーバー | Debian/Ubuntu + Mox v0.0.17(/usr/local/bin/mox) |
PVE CT | vmbr88 | 稼働中;40個別アカウント+LE証明書取得済み;GW=88.2 |
注意: 192.168.99.0/24 には PVE 本体(192.168.99.99)・新ipf(192.168.99.2)・old(192.168.99.110)・その他管理機が接続。旧192.168.99.4(旧NPM)は廃止予定。
アクセス情報
ssh old # → 192.168.88.110(旧メール、root)
ssh mox # → 192.168.88.100(root、LC_ALL=C 必要)
ssh npm # → 192.168.99.2(新ipf、ipf/npm同一Box。ssh ipf も同じ)
管理者パスワードヒント: admin@123 — /etc/mox/adminpasswd に未検証のbcryptハッシュ存在。初回ログイン時に確認が必要。
2. 現在の状態
旧サーバー(old)
- MTA: Postfix、Maildir配信(
/home/<user>-m-seed/Maildir/配下) - ドメイン設定(
mydestination):
m-seed.biz,mail.m-seed.biz,mx.m-seed.biz,smtp.m-seed.biz,m-seed.sytes.net, localhost - 仮想エイリアスマップ:
hash:/etc/postfix/virtual(~51アクティブエントリ。miura-m-seed,ono-m-seed等のローカルユーザーにメールアドレスをマッピング) - メール量: ~664メッセージ(new 30 / cur 634)、~36ユーザーディレクトリ
- キャリア中継(cyberbb.com:587): 旧キャリア(docomo, ezweb, softbank, yahoo.co.jp)向け中継設定。契約満了で利用不可。Moxからは直接SMTP配信に切り替え。
- DKIM鍵:
/var/lib/dkim/m-seed.*に生成済み - POP3: ポート110で稼働中。mox 切り替え後も半年間維持予定(VM 削除時に ipf ルールを編集)
新サーバー(mox)
| 項目 | ステータス | パス |
|---|---|---|
| Moxバイナリ | インストール済み v0.0.17-go1.27.1(static ELF x86_64) | /usr/local/bin/mox |
| 設定ディレクトリ | 本番ドメイン登録済み | /etc/mox/domains.conf, /etc/mox/mox.conf |
| データディレクトリ | adminアカウント + 2257インポート済みメッセージ | /var/lib/mox/ — admin/msg/a (2257ファイル) + queue/acme/db |
| 管理者パスワードファイル | bcryptハッシュ存在(未検証) | /etc/mox/adminpasswd |
| DKIM鍵ペア | m-seed.biz 生成済み | /var/lib/dkim/m-seed.* |
| エイリアス | adminアカウントへ~42メールアドレス追加済み | /etc/mox/domains.conf |
| SMTPサービス | 稼働中 — モジュール起動済み、全ポートリスニング中(※要再確認) | N/A |
⚠️ 注意: SMTP稼働中表記とTLS未取得は矛盾する。全ポートLISTENは要再確認、ACME取得までは本番切替不可。
発見されたDNSレコード
# MXレコードは既に mail.m-seed.biz を指している ✓
$ host -t mx m-seed.biz
m-seed.biz mail exchanger 9 mail.m-seed.biz.
# DMARCポリシー存在(p=none:緩い)✓
$ host -t txt _dmarc.m-seed.biz
_dmarc.m-seed.biz "v=DMARC1; p=none;"
3. Mox の動作(ポートとプロトコル)
旧サーバー(SMTP 25/587, POP 110)との比較。
ポート一覧
| サービス | 旧サーバー | Mox | 備考 |
|---|---|---|---|
| SMTP(受信) | 25 | 25 | 他社からの受信用。旧サーバーと同等 |
| SMTP(送信) | 587 | 587 | STARTTLS。クライアント送信用。旧サーバーと同等 |
| SMTPS | — | 465 | 暗黙的TLS。旧サーバーには無かったポート |
| IMAP | なし | 143 | STARTTLS。旧サーバーはPOPのみ |
| IMAPS | なし | 993 | 暗黙的TLS。推奨ポート |
| POP3 | 110 | 非対応 | MoxはPOP3をサポートしていない |
| Web管理 | なし | 8080 | 内部用。外部公開時はリバースプロキシ推奨 |
動作フロー
受信フロー:
他社SMTP → (ポート25) → Mox → Maildir/DB → IMAPクライアント
送信フロー:
IMAPクライアント → (ポート587/465) → Mox → MXレコード経由 → 他社SMTP
旧サーバーとの主な違い
- POP3非対応 → クライアントは IMAP(993推奨)でのみ接続可能
- DANE/DMARC/SPF/DKIM 内蔵 → 旧サーバーより送受信のセキュリティが高い
- ACME自動TLS → Let's Encrypt 証明書が自動更新
- Web管理UI → ブラウザでドメイン/アカウント/キューを管理可能(英語のみ、日本語化非対応)
- Webメール(webmail) → ブラウザベースのメールクライアントも内蔵(英語のみ)
クライアント設定例(Thunderbird等)
受信: IMAP, mail.m-seed.biz:993, SSL/TLS, 認証: Plain/SCRAM
送信: SMTP, mail.m-seed.biz:465, SSL/TLS, 認証: Plain/SCRAM(代替587/STARTTLS可)
外部からは mail.m-seed.biz(公開IP)経由で Fortigate → 新ipf(192.168.99.2)→ 振分け → mox/旧サーバーへ到達。
旧VM(192.168.88.110)の POP3 は半年間維持。
移行時は POP3 クライアントを IMAP に変更する必要があります。詳細は POP3-TO-IMAP-MIGRATION.md を参照。
Web管理UIについて
Mox admin UI は 英語のみ で、i18n/日本語化機能は非対応です。代替案:
- ブラウザの自動翻訳(Chrome/Edge/Firefox で右クリック → 「日本語に翻訳」)
- CLI主体の運用(
moxコマンドで管理)
4. 移行計画
フェーズA — Moxサーバー準備 ✅ 完了
-
✅ 管理者認証確認(パスワードヒント
admin@123):ssh mox 'env LANG=C LC_ALL=C bash --login -c "\/usr\/local\/bin\/mox setaccountpassword test@test.com"' # または CLI失敗時は /etc/mox/adminpasswd を直接編集 -
✅ Mox設定へ本番ドメイン登録:
ssh mox ... "/usr/local/bin/mox config domain add m-seed.biz admin" -
✅ 旧サーバー
/etc/postfix/virtual対応のアカウント作成(~50ユーザー)。各アカウントに宛先アドレスと初期パスワード設定が必要。 -
✅ 既存MaildirをMoxアカウントへインポート:
ssh mox ... "/usr/local/bin/mox import maildir admin AllMail /var/lib/mox/data/import/AllMail" # 結果: 2257件インポート完了 -
送信トランスポート設定(cyberbb契約満了のためスマートホストなし、直接配信)
-
SMTPサービス起動:
mox serve -
TLS証明書設定(ACME: Let's Encrypt、ポート80/443)— MXレコードは既に本ホストを指しているためDNS伝播完了済み
- 順序はTLS取得→疎通→公開。STARTTLS/SMTPSが自己署名の期間を作らない。
フェーズB — 切り替え&テスト
mail.m-seed.bizのA → Fortigate公開IP(要実測)確認- DMARC/DKIM/SPFレコードの事前確認
- MXは既に mail.m-seed.biz:9 で設定済みのため変更なし。切替実体はFortigate VIP/ipf振分け。MX変更はしない
- 内部アドレスで送受信テスト → 外部ドメインへ拡大
- キュー/配信ログ監視;成功後(~1週間猶予期間)、旧Postfix廃止
5. 既知の問題&ブロック要因
| 問題 | 影響 | 回避策 |
|---|---|---|
| Mox管理者パスワード未検証 | webadminアクセス・アカウント作成不可 | CLI確認: /usr/local/bin/mox setaccountpassword root@m-seed.biz;または /etc/mox/adminpasswd のbcryptハッシュ手動更新 |
SSHロケール警告(LC_ALL cannot change locale ja_JP.UTF-8) |
出力が冗長だがブロックしない | 全リモートコマンドに LANG=C LC_ALL=C bash --login -c "..." ラッパー適用、または mox の .bashrc にexport追加 |
| 旧 cyberbb.com キャリア中継契約満了 | スマートホスト経由の送信ルート無効 | Moxからの直接SMTP配信に設定変更。CT88100 IPの逆引きDNS/SPF整合性確認 |
| 個別40アカウント未移行説(~42/~50の8件残り) | 解消済み | 2026-10-06に40件個別移行・欠け0確認済み(OLD-SERVER-INVENTORY.md参照) |
| 99.x同一セグメントからの99.2宛旧系ポート | 非対称経路で不通に見える | 99.xからはbackend直(88.110/88.100)を使う。外部経路は正常のため対応不要 |
mox.conf 修正履歴(2026-10-05)
moxが起動に失敗する問題を修正しました。
原因1: internal リスナーの IPs に 0.0.0.0/0(CIDR表記)を指定 → moxがホスト名として解決しようとして失敗
l=fatal m="http: listen" err="listen tcp: lookup 0.0.0.0/0: no such host"
原因2: internal リスナーの IPs に 0.0.0.0 を指定 → 0.0.0.0:80 が先にバインドされ、public リスナーの 192.168.88.100:80 と競合
l=fatal m="http: listen" err="listen tcp4 192.168.88.100:80: bind: address already in use"
修正: internal リスナーの IPs を 0.0.0.0 → 127.0.0.1 に変更(port 80 は public リスナーが 192.168.88.100 で独占、internalはlocalhostのみ)
結果: mox v0.0.17-go1.27.1 全サービス正常稼働。http://mox-admin.m-seed.biz/admin/ も200 OK。
mox.conf・TLS修正履歴(2026-10-06、m-seed.biz一本化)
テストドメインを除去し m-seed.biz のみにした。サーバー上の実ファイルを変更、バックアップは /etc/mox/mox.conf.bak と /etc/mox/mox.conf.pre-mseed-*。
Hostname: mox-admin.m-seed.biz→mail.m-seed.biz(EHLO・ACME対象の正本化)ContactEmail: admin@m-seed.bizに設定HostPrivateKeyFilesを新規生成hostkeys/mail.m-seed.biz.{rsa2048,ecdsap256}.privatekey.pkcs8.pemに設定- public TLSに
ACME: letsencrypt追加。注意: 静的KeyCertsとACMEは併存不可(listener public: cannot have ACME and static key/certificatesで起動ループする)。静的/etc/mox/cert.crt(自己署名)を除去して解消 - Let's Encryptで
CN=mail.m-seed.biz取得済み(2026-10-05〜2027-01-03)。993でTLS1.3確認 - HTTP-01経路: Fortigate→旧(.2:80/443)→NPM(.4)→新規proxy_host
mail.m-seed.biz→192.168.88.100:80(NPM DB直INSERT+手書き/opt/npm/data/nginx/proxy_host/4.conf。DB直書きではconf自動生成されないため。NPM UI編集で上書きされる注意) - NPMコンテナを
podman compose down/upで再建(netns破損対応)。DB・設定はvolume保持
注意: mox webadminはHostヘッダー検証あり — Hostname 変更後 http://mox-admin.m-seed.biz/admin/ が404になった。原因はmoxがHost≠Hostnameを404拒否するため。対策としてNPMの proxy_host/3.conf のlocationを展開し proxy_set_header Host mail.m-seed.biz; に単一化(重複指定するとGoが複数Hostヘッダーで400拒否する)。同ファイルもNPM UI編集で上書き注意。修正後200 OK(外部確認済み)。
運用ポリシー(2026-10-06確定)
- 障害時対応: 手厚いフェイルセーフは構築しない。Proxmoxバックアップ(日次×2世代)からのリストア起動で凌ぐ
- 障害対応費は別途(最低費用契約のため)
- バックアップ: Proxmox日次×2世代(VM単位、短期障害復旧用)。長期保存の正本はmox現用ストレージ。1通単位の復元は対象外
6. Mox CLIクイックリファレンス
# ヘルプ&バージョン
/usr/local/bin/mox help [$command ...] # サブコマンド一覧
/usr/local/bin/mox version # v0.0.17-go1.27.1
# 管理者パスワード管理
/usr/local/bin/mox setadminpassword # admin Web UIパスワード対話設定
/usr/local/bin/mox setaccountpassword $addr # メールアドレス指定でアカウントパスワード設定
# ドメイン/アカウント設定
/usr/local/bin/mox config describe-domains >domains.conf # 完全テンプレート出力
/usr/local/bin/mox config describe-static >mox.conf # 完全 mox.conf テンプレート
/usr/local/bin/mox config domain add [-disabled] $domain $account [$localpart]
/usr/local/bin/mox config account list # 既存アカウント一覧
/usr/local/bin/mox config alias list $domain # 特定ドメインのエイリアス
# メールインポート/エクスポート(重要コマンド)
/usr/local/bin/mox import maildir $accountname $mailboxname $maildirpath
# 例: mox import maildir admin AllMail /var/lib/mox/data/import/AllMail
/usr/local/bin/mox export maildir [-single] $dstdir $accountpath [$mailbox]
# サービス制御&キュー操作
/usr/local/bin/mox serve # MTA + IMAPサーバー起動
/usr/local/bin/mox stop # gracefulシャットダウン
/usr/local/bin/mox checkupdate # 新版確認
注意: 全SSHリモート実行は env LANG=C LC_ALL=C bash --login -c "..." ラッパーが必要です(ロケール不一致のため)。
7. ロケール警告の修正
両サーバーの /root/.bashrc または /etc/profile.d/locale.sh に以下を追記し、.profile の競合設定を削除:
export LANG=en_US.UTF-8 # 未インストールの ja_JP の代わりに en_US を使用
export LC_ALL=en_US.UTF-8
または、LANG=C LC_ALL=C を sshd_config の SetEnv でグローバル設定(侵入的)。推奨はシェルプロファイルへのexport追加。
日本語ロケールを完全にインストールする場合は apt-get install language-pack-ja も有効ですが、本番メールサーバーではOSレベルで日本語UTF-8レンダリングは不要なため、英語デフォルトで問題ありません。
8. 関連ドキュメント
| ファイル | 内容 |
|---|---|
MIGRATION-COMPLETE.md |
移行完了レポート |
OLD-SERVER-INVENTORY.md |
旧サーバー詳細インベントリ |
DNS-RECORDS.md |
DNSレコード一覧 |
MANUAL.md |
基本移行手順マニュアル |
migrate-to-mox.sh |
移行自動化スクリプト |
TRANSITION-MANUAL.md |
将来の移行準備マニュアル |
QUEUE-COLLECTION-DOCS.md |
キュー回収仕様書 |
collect-queue.sh |
キュー回収スクリプト |
queue_to_maildir.py |
キュー→Maildir変換スクリプト |
queue-collect.conf |
キュー回収設定ファイル |