Инструмент для переезда почты с одного сервера на другой — imapsync. Он подключается по IMAP к обеим сторонам и переносит содержимое ящика с сохранением структуры папок, дат и флагов прочитанности.
Оговорюсь честно о жанре. У меня в материалах по фактическому переносу ничего не зафиксировано: инструмент был выбран и запланирован, а деталей реальной операции я не записал. Поэтому здесь будет порядок действий и то, что я думаю про планирование такой работы, — но не рассказ о проблемах, которых у меня не было. Придумывать инцидент ради красивой истории смысла нет.
Коротко
imapsyncходит по IMAP с обеих сторон, сохраняя папки, даты и флаги.- Планировать стоит как операцию в два прохода, а не в один.
- Время простоя определяется не объёмом почты, а разницей между проходами.
Почему в два прохода, а не в один
Это единственное, что я считаю по-настоящему важным в планировании такого переезда.
Соблазн очевидный: назначить время, остановить старую почту, перелить всё, включить новую. На ста сорока ящиках это означает простой длиной во весь объём переноса — то есть часы, в течение которых почта не работает ни там, ни там.
Правильнее по-другому. Первый проход делается заранее, по живым ящикам, пока люди продолжают работать на старом сервере. Он долгий, но никого не трогает: imapsync просто читает и копирует.
Второй проход — короткий добор в момент переключения. Он переносит только то, что накопилось с первого прохода.
Отсюда простое следствие: время простоя равно не объёму почты, а разнице между двумя проходами. Чем ближе первый проход к моменту переключения, тем короче второй. Это то, чем можно управлять, в отличие от общего объёма.
Как это выглядит на практике
Один ящик:
# пароли — в файлы, а не в командную строку
umask 077
secrets=$(mktemp -d)
trap 'rm -rf "$secrets"' EXIT
printf '%s' 'ПАРОЛЬ_ПРИЛОЖЕНИЯ' > "$secrets/src"
printf '%s' 'ПАРОЛЬ' > "$secrets/dst"
docker run --rm -v "$secrets:/secrets:ro" gilleslamiral/imapsync imapsync \
--host1 imap.yandex.ru --port1 993 --ssl1 \
--user1 user@example.com --passfile1 /secrets/src \
--host2 mail.example.com --port2 993 --ssl2 \
--user2 user@example.com --passfile2 /secrets/dst \
--automap --justfolders # сначала только папки, потом без этого ключа
Пароль, переданный аргументом --password1, виден любому пользователю машины через ps и оседает в истории оболочки — сама документация imapsync честно об этом предупреждает. Поэтому пароль лучше класть в файл с правами только для владельца (umask 077 — до создания файла, не после) и передавать его через --passfile1/--passfile2.
Ключ --justfolders в первом запуске — недорогая страховка. Он переносит только структуру, без содержимого: если в именах папок или в правах что-то не так, вы узнаете об этом за секунды, а не в середине многочасового переноса.
Пакетно, из CSV вида user;pass_yandex;pass_new:
umask 077
secrets=$(mktemp -d)
trap 'rm -rf "$secrets"' EXIT
while IFS=';' read -r u p1 p2; do
printf '%s' "$p1" > "$secrets/src"
printf '%s' "$p2" > "$secrets/dst"
docker run --rm -v "$secrets:/secrets:ro" gilleslamiral/imapsync imapsync \
--host1 imap.yandex.ru --ssl1 --user1 "$u" --passfile1 /secrets/src \
--host2 mail.example.com --ssl2 --user2 "$u" --passfile2 /secrets/dst \
--automap > "log_${u}.txt" 2>&1
done < users.csv
Тот же приём, что и с одним ящиком, только внутри цикла: пароли по каждому ящику по очереди попадают в два файла в каталоге с правами 700, а не передаются аргументом. trap на выход подчищает каталог с паролями, даже если цикл прервётся посреди ста сорока ящиков, — на этом гоняется он часами, и оставлять secrets-каталог на диске до ручной уборки не стоит.
Отдельный лог на каждый ящик — не педантизм. При ста сорока ящиках общий лог превращается в нечитаемое полотно, и вопрос «а у этого человека всё перенеслось» останется без ответа.
CSV с паролями удалить сразу после миграции. Это файл, в котором лежат пароли ко всем ящикам компании сразу — и он имеет обыкновение задерживаться в домашнем каталоге на годы. Удалять надо не «потом», а в тот же день, когда перенос закончен.
В самом mailcow есть Sync jobs — тот же imapsync, но из веб-интерфейса. Для второго, добирающего прохода перед переключением MX это удобнее: задание настраивается один раз и запускается повторно.
Что стоит держать в голове
Доступ по IMAP на обеих сторонах должен быть проверен до дня X. Не «должен работать», а проверен — на реальном ящике, с реальным паролем. Пароли приложений и двухфакторная аутентификация на стороне облака умеют преподносить сюрпризы именно в тот момент, когда проверять уже поздно.
Структура папок переносится как есть — вместе со всеми её особенностями. Если у людей глубокая вложенность и длинные имена, они переедут в точности такими же. Это само по себе не проблема переноса, но может стать проблемой позже, уже на стороне почтовых клиентов. У меня стала — но это отдельная история, и она не про imapsync.
Порядок ящиков имеет значение. Начинать стоит не с директора, а с того, кто готов потерпеть, если что-то пойдёт не так. Первый ящик — это всегда проверка процедуры, а не перенос почты.
Чего здесь нет
Не будет рассказа о том, сколько заняло, что сломалось и как чинилось. Не потому что всё прошло гладко или негладко, а потому что у меня нет записей, а по памяти такие вещи восстанавливаются неточно — и неточность потом живёт в статье как факт.
Если по итогу переноса появится что рассказать по фактам, напишу отдельно.