いま目の前にある移行プロジェクトに、不安を感じているのではないでしょうか。メッセージを一通も失わず、フォルダー構造も壊さず、すでに自社で所有しているデータを移すだけなのに、サードパーティ業者へ$15/userの「移行ライセンス料」を支払うこともなく、サーバーAからサーバーBへメールを移行する必要があります。
そこで必要になるのがimapsyncです。このガイドでは、ユーザーのメールボックスを混乱させずにimapsyncを使用する方法を詳しく説明します。
imapsyncとは何か(そして何ではないか)
imapsyncは、二台のIMAPサーバー間でメールボックスを同期するコマンドラインユーティリティです。プロキシとして両方のサーバーへ同時に接続し、移行元からメッセージを読み取り、移行先へ追加します。処理状態を追跡し、中断からの再開に対応しながら、フォルダー構造、フラグ、メッセージ本文を保持します。
バックアップツールではなく、SMTPリレーでもありません。Googleカレンダー、Outlookの連絡先、Exchangeのトランスポートルールには一切触れません。扱うのはIMAPだけです。移行元サーバーがファイアウォールで遮断されているかオフラインなら、imapsyncからは接続できません。それで終わりです。
メールボックス間の移行における業界標準となった理由は、状態を保持する仕組みにあります。移行の成功とは、単にテキストを移すことではありません。次の三つを維持する必要があります。
- コンテンツ: RFC 822形式のメッセージ本文、添付ファイル、MIMEエンコーディングなど、メッセージに含まれるすべての情報。
- メタデータ: フラグです。
\Seen(既読)、\Answered(返信済み)、\Flagged(フラグ付き)。これらを引き継がないと、初日に4,000通の新しい未読メールが届いたように全ユーザーから見えてしまいます。 - 構造: フォルダー階層です。
INBOX/Clients/ProjectAは新しいサーバーでも同じ階層で表示される必要があります。フォルダー名にピリオドを含む、文字どおりのINBOX.Clients.ProjectAという単一フォルダーにまとめられてはいけません。
imapsyncは、正しく設定すれば、この三つをすべて維持できます。難しいのはその設定であり、このガイドではそこを解説します。
避けられない制約: imapsyncは、Gmailのレート制限やMicrosoftのAPIスロットリングを自動的には把握しません。最大速度で実行すれば、IPアドレスをブロックされる可能性があります。また、データを自らプッシュすることもありません。ある場所へデータを移すには、移行先から取得する必要があります。さらに、デフォルトでは移行先のデータを削除しません。これは安全機能ですが、注意を怠ると問題の原因にもなります。詳しくはフェーズ6で説明します。
プロトコル自体について詳しく知りたい場合は、独自ドメインでメールを設定する方法をご覧ください。
フェーズ1: 詳細な事前調査、この工程を省略しない
初心者はすぐにコピーを始めます。プロは最初に環境を監査します。何を移行するのか把握していなければ、必ず失敗します。しかも、修正するには遅すぎる日曜の午前2時に失敗するものです。
1. 巨大なメールボックスを見つける
45GBのメールボックスを持つユーザーがいるとします。CEOかもしれませんし、2011年からsales@エイリアスを管理している人物かもしれません。500MBのユーザーと同じバッチで移行しようとすると、そのバッチは停滞します。どこまで進んだのか分からないまま、停止したように見えるターミナルを眺めることになります。
最初に事前スキャンを実行します。
imapsync \
--host1 imap.source.com --user1 user@source.com --passfile1 /secret/pass1 \
--host2 imap.dest.com --user2 user@dest.com --passfile2 /secret/pass2 \
--dry --justfoldersizes
このコマンドを使えば、メッセージを一通も変更することなく、フォルダーごとの容量を確認できます。10GBを超えるメールボックスには個別の対応が必要です。タイムアウトを長く設定し、専用の実行時間帯を確保して、処理を注意深く監視してください。
2. 放置データの問題
どの企業にも休眠アカウントがあります。退職後もメールがどこかへ転送され続けている元従業員のアカウントや、実際にはプリンターや古いCRM連携用の共有受信トレイである「サービスアカウント」などです。棚卸しでこれらを見落とすと、DNSを切り替えた時点でデータが取り残されます。
移行元のユーザー一覧と、実際の現役ユーザーを照合してください。bob@company.comが三年前に退職しているなら、いま決めます。メールボックスを移行するのか、EMLとしてエクスポートして保管するのか。切り替え前に決めなければ、最悪のタイミングでプレッシャーを受けながら判断することになります。移行前の完全な棚卸しテンプレートについては、クライアントメール管理ガイドをご覧ください。
3. 正しい指標はアイテム数
ギガバイト単位の容量をそのまま信用してはいけません。移行元サーバーAで10GBと表示されるメールボックスが、まったく同じデータでも移行先サーバーBでは11GBと表示される場合があります。これは不具合ではありません。サーバーごとにストレージ容量の計算方法が異なるためです。ExchangeはRecoverable Itemsフォルダー、通称「Dumpster」を含めます。Gmailはラベル間でメッセージを重複排除します。
重要な指標はアイテム数です。移行元が14,200通で、移行先も14,200通なら完了です。バイト数の差が10%未満なら正常な範囲です。10%を超える場合は、完了と判断する前に原因を調査してください。
フェーズ2: 安全な移行ワークフロー
移行における最大の失敗は、金曜の夜にすべてを一度に移し、月曜の朝までに終わることを祈る「一斉移行」です。50GBのメールを500KB/sに制限して転送するなら、計算上、間に合いません。月曜になっても利用できず、CEOに受信トレイが空である理由を説明する羽目になります。
プロが採用するのは、段階的な移行です。ユーザーがまだ旧システムを利用している間に大部分を移し、切り替え時には最後のわずかな差分だけを転送します。
ステップ1: ドライラン
一バイトでも移す前に、接続できることを確認します。--dryと--justfoldersを組み合わせてください。データをコピーせずに実行をシミュレーションし、フォルダー構造を確認できます。
imapsync \
--host1 imap.gmail.com --user1 user@source.com --passfile1 /secret/pass1 \
--host2 imap.trekmail.net --user2 user@dest.com --passfile2 /secret/pass2 \
--dry --justfolders
確認する点は二つです。認証に成功したか、フォルダー名がどのように表示されるかを見ます。移行元に[Gmail]/Sent Mailがあれば、移行先のSent Itemsへマッピングする必要があります。本番の切り替え中に初めて気付く事態は避けてください。
ステップ2: 一括同期(事前移行)
ユーザーが旧システムで作業を続けている間に、切り替えの1から2週間前に実行します。目標は、重要な切り替え時間帯に入る前にデータの90から95%を移しておくことです。
imapsync \
--host1 imap.source.com --user1 user@source.com --passfile1 /secret/pass1 \
--host2 imap.dest.com --user2 user@dest.com --passfile2 /secret/pass2 \
--usecache --skipsize --maxsize 25000000
--usecacheは必須です。移行状態をローカルに保存します。以降の実行ではこのキャッシュと比較して変更だけを処理するため、すべてのメッセージを最初から調べ直すことはありません。このオプションがなければ、毎回完全なスキャンになります。
--maxsize 25000000は、最初の実行時に25MBを超えるメッセージを除外します。大容量の添付ファイルは、タイムアウトや接続切断の最大の原因です。タイムアウトを延長した専用の実行で、あとから移行します。
ステップ3: 差分同期
切り替えの数日前に、もう一度実行します。imapsyncはキャッシュを読み、移行先にすでに10,000通あることを確認してそれらを省略し、一括同期後に届いた50から100通の新しいメッセージだけをコピーします。この処理は数時間ではなく、数分で完了するはずです。
ステップ4: 切り替え
いよいよ切り替えです。次の順序で実施してください。
- DNS TTLを下げる: 切り替えの48時間前に、MXレコードのTTLを300秒に設定します。直前まで待つと、一部のリゾルバーが古いMXを最大24時間キャッシュし、切り替え後も旧サーバーにメールが届く可能性があります。
- MXレコードを切り替える: 新しいホストを参照するように変更します。
- 主要なリゾルバーへの反映が落ち着くまで60分待ちます。
- 最後の差分同期を実行する: imapsyncを最後にもう一度実行し、DNSの反映中に旧サーバーへ届いたメッセージを取り込みます。
DNS切り替え時間帯の詳しい手順と、反映中に監視すべき点については、独自ドメインでメールを設定する方法をご覧ください。
フェーズ3: フラグ、フォルダー、送信済みフォルダーの落とし穴
IMAPサーバーごとに仕様上の違いがあります。その違いを吸収しなければ、ユーザーは構造が壊れたメールボックスを目にすることになり、当然ながら移行担当者の責任を問います。
区切り文字の問題
これは、実際に遭遇するまでほとんど語られない、最も一般的な技術的問題です。
IMAPサーバーによって、フォルダー階層を区切る文字が異なります。
- Dovecotは通常ピリオドを使用します:
INBOX.Clients.ProjectA - Exchange/Outlookはスラッシュを使用します:
INBOX/Clients/ProjectA - 区切り文字を使わず、IMAPの
NAMESPACEコマンドに依存するサーバーもあります
確認せずに移行すると、imapsyncが移行先に文字どおりINBOX.Clients.ProjectAという名前のフォルダーを作る場合があります。三階層の入れ子構造ではなく、名前にピリオドを含む単一のフラットなフォルダーです。全ユーザーのフォルダー構造が完全に崩れて見えます。
解決策は--regextrans2です。正規表現を使って移行中にフォルダーパスを書き換えます。100ユーザーのバッチを実行する前に、必ず一つのテストアカウントで--dryを使い、フォルダー作成を確認してください。
送信済みフォルダーの混乱
サーバーごとに送信済みフォルダーの名前が異なります。これは小さな不便ではありません。無視すれば、ユーザー体験を大きく損ないます。
| メールプラットフォーム | 送信済みフォルダー名 |
|---|---|
| Gmail / Google Workspace | [Gmail]/Sent Mail |
| Outlook / Exchange | Sent Items |
| cPanel / Courier | Sent |
| ドイツ語のサーバー | Gesendete Elemente |
| スペイン語のサーバー | Enviados |
これらをマッピングしないと、ユーザーには二つの送信済みフォルダーが表示されます。現在使用中のSent Itemsと、過去の送信履歴がすべて入ったSent Mailという新しい残存フォルダーです。ユーザーは必ず気付き、不満を抱きます。
明示的にマッピングしてください。
--regextrans2 's/^\[Gmail\]\/Sent Mail/Sent Items/'
これはimapsyncに対し、「移行元フォルダーが[Gmail]/Sent Mailで始まる場合は、移行先でSent Itemsに名前を変更する」と指示します。確定する前に、フォルダーマップ全体を--dryで実行し、すべてのマッピングが正しく適用されることを確認してください。
GmailのAll Mailに関する落とし穴
Gmailには[Gmail]/All Mailというフォルダーがあります。ラベルに関係なく、すべてのメールのコピーが入っています。Gmail内部の全件表示がIMAPフォルダーとして公開されたものです。
All MailとInboxとSent Mailをすべて移行すると、移行先で各メールが二回または三回重複します。10GBのメールボックスが30GBになります。すべてのメッセージが複数回表示され、深刻な混乱を招きます。
必ず除外してください。
--exclude "All Mail"
移行する明確な理由がない限り、[Gmail]/Spamと[Gmail]/Trashも除外します。古い迷惑メールまで移行したい人はいません。
フェーズ4: パフォーマンス調整とスロットリング
GoogleやMicrosoftへ大量のデータを一気に送り込むことはできません。これらの基盤は、大量のIMAP通信をサービス拒否攻撃と同じように扱います。サービス側から見れば、両者の区別がつかないためです。
制限超過のペナルティ
レート制限を超えると、Gmailの場合は通常、毎秒約1通または毎時500MBですが、サーバーがHTTP 429、NO [OVERQUOTA]、または単にBADエラーを返し始めます。そのまま続けると、アカウントが24時間ロックされます。避けたいサポート問い合わせです。
調整用オプション
--maxmessagespersecond 1 # Hard speed limit: 1 email per second
--maxbytespersecond 500000 # Bandwidth cap: 500KB/s
--timeout 120 # Network timeout in seconds (default is often too short for big attachments)
--reconnectretry1 3 # Retry on source connection drops
--reconnectretry2 3 # Retry on destination connection drops
毎秒1通では、非常に遅く感じます。実際に遅いのですが、安定して進み、最後まで完了します。3時間目にブロックされるような強引な実行は、いつまでも完了しません。
MSP向けの注意: 複数クライアントの移行を並行して行う場合、同じ移行元サーバーに対して同時実行しないでください。開始時刻をずらします。並行する各処理に、それぞれのスロットリング枠が必要です。
TrekMailへの移行であれば、当社のIMAP取り込み機能は多数の同時接続を処理できます。GoogleやMicrosoftなどの移行元側よりも、移行先側では高い速度を設定できます。
フェーズ5: 認証、モダン認証という難関
password123を平文ファイルに保存する時代は終わりました。GoogleとMicrosoftはどちらもIMAPのBasic認証を廃止しています。通常のログイン情報を使っても認証エラーになり、何が間違っているのか悩むだけで一時間を費やすことになります。
アプリパスワード(中小規模向け)
単一ドメインの移行では、多くの場合、アプリパスワードが最も早い方法です。16文字の文字列で、2FAを迂回して従来のIMAPクライアントで使用できます。
- 移行元アカウント(Gmail、Workspaceなど)にログインする
- 2要素認証が有効でなければ有効にする(アプリパスワードの生成に必要)
- セキュリティ設定 → アプリパスワードへ移動する
- 「Mail」、「Other device」用のパスワードを生成する
- 生成された文字列をimapsyncの
--passfileに指定する
コマンドラインではなく、chmod 600を設定したファイルに保存します。Bashの履歴に認証情報が残ると、いずれ重大な問題になります。
OAuth2(MSPおよびエンタープライズ向け)
500ユーザーを移行するMSPが、500個のアプリパスワードを手作業で生成するのは現実的ではありません。OAuth2が必要です。複雑ではありますが、大規模移行では唯一現実的な選択肢です。
- 移行元テナントにアプリケーションを登録する(MicrosoftはAzure AD、GoogleはGoogle Cloud Console)
- テナント全体のメールボックスへの完全なアクセス権を付与する(Global Adminの承認が必要)
- ユーザーごとにRefresh Tokenを生成するか、サービスアカウントによる代理アクセスを使用する
--oauthaccesstoken1を使ってimapsyncにトークンを渡す
Azure ADやGCPでアプリケーション権限を誤って設定すると、すべてのメールボックスでアクセス拒否になるか、さらに悪い場合は、意図した範囲より広い権限を付与してしまいます。「Grant admin consent」をクリックする前に、権限スコープを慎重に確認してください。
大規模移行の実践的な考え方については、クライアントメール管理のガイドをご覧ください。
フェーズ6: よくある障害と復旧方法
どれほど綿密な計画でも問題は起きます。最初からやり直すことなく、原因を読み解いて修正する方法を説明します。
1. UIDVALIDITYの問題(最悪のシナリオ)
すべてのIMAPフォルダーには、UIDVALIDITYという一意の識別子があります。imapsyncはこれを使って、コピー済みのメッセージを追跡します。移行元サーバーのフォルダーが削除されて再作成された場合や、サーバーのインデックスが破損して再構築された場合、このIDが変わります。
症状: imapsyncは新しいUIDVALIDITYを検出すると、まったく新しいフォルダーだと判断し、すべてを再取得します。そのフォルダー内の全メッセージが重複します。大規模環境では、数百のメールボックスに数千件の重複が生じます。
対処: 一時ディレクトリ内のローカルキャッシュファイルを削除し、--useheaderを指定して再実行します。
--useheader
これにより、imapsyncはフォルダーUIDではなく、各メールのMessage-IDヘッダーを比較します。このヘッダーは不変かつ一意です。処理は遅くなりますが、重複を避けやすくなります。移行元サーバーのインデックスが変更された疑いがある場合に適した方法です。
2. 破損したメッセージとゼロバイトのメッセージ
古いサーバーには「ゴースト」メッセージが蓄積します。本文のないヘッダーや、正確に0バイトのファイルです。多くは、失敗したインポート、配送処理の異常終了、または保守が長年先送りされた非常に古いサーバーが原因です。
症状: imapsyncがメッセージを取得しようとすると、サーバーが120秒間応答せず、その後接続を切断します。同じメッセージでこの動作が何度も繰り返されます。
対処:
--minbytes 10
10バイト未満のメッセージをすべて省略するよう、imapsyncに指示します。通常のメールが10バイト未満になることはまずありません。実質的には空ファイルを除外するフィルターで、多くの移行に適用できます。
3. 削除済みメールが復活する問題
月曜に一括同期を実行し、火曜にユーザーが移行元から50通のメールを削除し、水曜に差分同期を実行したとします。
デフォルトでは、imapsyncはメールを追加するだけです。移行元で削除されたメールを移行先から削除しません。これは意図された動作であり、多くの用途では正しい選択です。ただし、削除した50通のメールが新しいメールボックスに再び現れます。ユーザーからは「消したはずのメールが戻ってきた」と報告されます。
解決策は--delete2ですが、細心の注意が必要です。
--delete2
このオプションは、「移行元に存在しないメッセージを移行先から削除する」とimapsyncに指示します。
MXを切り替える前の事前移行フェーズでのみ使用してください。切り替え後に実行すると、MXがすでに移行先を指しているために移行先へ届いた新着メールは、古い移行元に存在しないという理由で削除されます。メールを失うことになります。切り替え後は--delete2を使用しないでください。
4. 大容量添付ファイルでの接続切断
40MBのPDF添付ファイルにより、タイムアウトが短いIMAP接続が停止する場合があります。サーバーがメッセージを送信中にネットワークが一時的に不安定になり、95%の時点で接続が切れ、imapsyncはエラーを記録して次へ進みます。その結果、移行先には不完全なメッセージが残ります。
対処: 大容量添付ファイルを処理する際は、--timeoutを300秒に延長します。一括同期では--maxsize 25000000を使用して対象から外し、あとでスロットリングを緩和してタイムアウトを延長した専用処理を実行する方法も検討してください。
検証: 成功を証明する方法
スクリプトは終了し、ターミナルにも完了と表示されました。しかし、CEOのメールがどこかのnullルートへ消えていないと、どう確認すればよいのでしょうか。
1. サマリーブロックを確認する
imapsyncは毎回、実行終了時にサマリーを出力します。重要なのは次の三つの数値です。
- Transferred: 最後の差分同期では0になるはずです。ゼロでなければ、まだ移行できていないメッセージがあります。
- Skipped: 移行元の総数と一致するか、それ以上になるはずです。移行先にすでにあるメッセージを示します。
- Errors: 0になるはずです。ゼロ以外のエラー数があれば、完了と判断する前に調査が必要です。
2. 抜き取り確認
新しく設定したIMAPクライアントで、新しいメールボックスにログインします。ローカルキャッシュを持つ既存のクライアントでは、確認の意味がありません。次の項目を確認します。
- 送信済みアイテム: 何年分もの送信メールが存在し、正しい階層に格納されているか
- 深い階層のサブフォルダー: 階層が正しく見えるか
- 最新のメール: 移行元に表示されるものと同じか
- フラグまたはスター付きメッセージ:
\Flagged属性が引き継がれているか
3. ログによる追跡
ユーザーからメールが見つからないと報告された場合、「失われたのだろう」と決めつける前にログを確認します。
grep -i "bob@sender.com" /var/log/imapsync/user@source.com.log
ログには、すべてのメッセージの処理結果が記録されています。Transferred、Skipped(移行先にすでに存在)、または具体的なエラーコードを伴うErrorです。Errorなら、どのメッセージ、どのフォルダー、どのエラーコードが原因だったかを正確に把握できます。推測ではなく、その情報を復旧の出発点にします。
4. アイテム数の監査
最後の健全性確認として、両方のサーバーを直接照会します。
# On source (example for Dovecot)
doveadm mailbox status -u user@source.com messages '*'
# Or use imapsync's own count
imapsync ... --dry --justfoldersizes 2>&1 | grep "Messages"
移行元と移行先のアイテム数を比較します。迷惑メールフォルダーの除外とGmailのAll Mailにおける重複排除を考慮すると、差は1から2%以内になるはずです。それを超える場合は、完了を承認する前にエラーログを調査してください。
別の選択肢: ターミナルを使わない
透明性が重要だと考え、このガイドを作成しました。imapsyncは、完全な制御を求め、Perlの依存関係、OAuth2アプリケーション登録、ログ調査といった手作業をいとわない運用担当者に適したツールです。
しかし、初めてのドメインを移行する創業者でも、200クライアントアカウントを移行する代理店でも、多くの担当者にとって、この設定にかかる時間はソフトウェア費用の節約分を上回ります。
| 方法 | 適している対象 | 何と何を引き換えるか |
|---|---|---|
| imapsync(自社運用) | システム管理者、完全な制御が必要な環境、特殊な移行元サーバー | ツール費用をゼロにする代わりに、時間と専門知識が必要 |
| TrekMail内蔵の移行機能 | 創業者、代理店、時間を重視する運用担当者 | 速度と簡便さを得る代わりに、細かなフラグ制御が減る |
| サードパーティの移行業者 | コンプライアンス要件と予算がある大企業 | SLA保証のために費用を支払う(多くの場合$15から$25/user) |
TrekMail内蔵の移行ツールはサーバー側で動作します。Outlookで三時間もフォルダーをドラッグする必要はなく、Perlの依存関係に悩まされることもありません。移行元(Gmail、cPanel、または標準的なIMAPサーバー)と認証情報を指定すれば、サーバーが転送を処理します。進捗はダッシュボードで確認できます。
料金体系も、一般的なものとは異なります。ユーザー単位の料金はありません。月額$3.50からの定額プランで、最大100ユーザーを50ドメインで利用でき、ストレージは全体で共有されます。そのため、40GBの添付ファイルを持つ役員が一人いても、全員分のアップグレードは不要です。ストレージをアカウント全体で共有するためです。
各プランに含まれる機能の比較は、TrekMailの料金をご覧ください。移行ツールの具体的な手順は、ドキュメントの移行を開始するガイドで説明しています。
imapsyncで自作スクリプトを実行する場合も、当社のプラットフォームを利用する場合も、目標は同じです。データを失わず、混乱を起こさず、ユーザー単位の手数料を支払うことなく、メールを移行することです。
ユーザー単位の料金をやめ、移行作業を任せたい方は、TrekMailを無料でお試しください。14日間のトライアルで、カードは不要です。