Миграция с Zimbra OSE 8.8.15 на Carbonio CE: как мы перевозим почту за выходные и не теряем ни одного письма

Миграция почты с Zimbra OSE 8.8.15 на Carbonio CE без потери писем

Почему «оставить как есть» — уже не вариант

Меня зовут Евгений Семёнов, я технический директор ITfresh. Мы занимаемся IT-аутсорсингом для юрлиц до 50 рабочих мест в Москве, держим свои серверы в дата-центре МТС — и почтовые переезды для нас регулярная работа, а не разовый подвиг. Эта статья — про самый частый маршрут последних двух лет: со старой Zimbra Open Source Edition на Carbonio Community Edition. Скажу честно: наш собственный почтовый сервер тоже годами доживал на связке «Zimbra OSE + CentOS 7», и переносили мы его по тому же плану, который разберу ниже. Так что все грабли в тексте — пройденные лично, а не пересказанные.

Теперь о том, почему тянуть больше нельзя. Zimbra OSE 8.8.15 официально мертва с 31 декабря 2023 года: обновлений безопасности для бесплатной ветки с тех пор нет и не будет. При этом дырки в ней находят исправно, и они не теоретические:

  • CVE-2023-37580 — XSS в классическом веб-клиенте, который эксплуатировался в реальных атаках ещё до выхода исправления: достаточно было заманить пользователя на подготовленную ссылку, чтобы увести сессию.
  • CVE-2024-45519 — удалённое выполнение команд через сервис postjournal; массовые попытки эксплуатации фиксируются с 28 сентября 2024 года. Патч 8.8.15 P46 вышел только для платных подписчиков — OSE-инсталляции остались с дырой навсегда.
  • CVE-2022-27924 — отравление memcached, позволявшее перехватывать учётные данные IMAP-пользователей вообще без взаимодействия с жертвой.

Добавьте сюда вторую половину проблемы: типовая Zimbra OSE стоит на CentOS 7, у которого собственный конец жизни наступил 30 июня 2024 года. То есть без патчей не только почтовый софт, но и ядро, OpenSSL, glibc — весь фундамент. Это двойной технический долг, и хорошая новость в том, что гасится он одной процедурой: миграция на Carbonio CE — это всегда переезд на новый сервер со свежей ОС (мы ставим Ubuntu 24.04), старую машину никто не «обновляет на месте». Один проект закрывает обе проблемы.

Когда мы советуем НЕ мигрировать: если у вас пять ящиков, сервер живёт в изолированной сети без публикации веб-клиента наружу и организация доживает последний год аренды — честнее закрыть 443-й порт снаружи, оставить только IMAP/SMTP через VPN и спокойно дожить. Миграция ради миграции никому не нужна. Но если почта опубликована в интернет и ящиков больше десятка — каждый месяц простоя решения работает против вас.

Хорошая новость: Carbonio — это всё ещё «Zimbra внутри»

Главный страх админа перед переездом — «придётся учить новую систему с нуля». Здесь он не оправдывается. Carbonio построен командой Zextras на той же архитектуре, что и Zimbra: внутри тот же OpenLDAP как хранилище аккаунтов, тот же Postfix на приёме, знакомая модель «класс обслуживания → домен → аккаунт». Утилита zmprov никуда не делась — в Carbonio она вызывается как carbonio prov, и практически весь ваш багаж однострочников переезжает вместе с вами. Даже zmmailbox и zmlocalconfig лежат на привычных местах, только префикс пути другой.

Актуальный релиз лета 2026 года — Carbonio CE 26.6.0 (нумерация вида ГГ.М, релизы выходят несколько раз в год). Ставится он на Ubuntu 22.04/24.04 и RHEL-совместимые дистрибутивы 8/9; мы выбираем Ubuntu 24.04 и готовим новый сервер строго по нашему регламенту установки — в этой статье я процесс установки не повторяю, считаем, что чистый Carbonio у вас уже поднят и смоук-тест пройден. Вот шпаргалка соответствий, которую мы выдаём инженерам на миграции:

Было в Zimbra OSEСтало в Carbonio CEКомментарий
/opt/zimbra/opt/zextrasструктура каталогов внутри узнаваемая
пользователь zimbraпользователь zextrassu - zextras перед админскими командами
zmcontrol start/stopsystemd-таргеты carbonio-*на Ubuntu 24.04 zmcontrol больше нет, только systemctl
zmprovcarbonio provподкоманды те же: ca, cd, ma, gaa
zmmailbox/opt/zextras/bin/zmmailboxREST-выгрузки календарей и контактов работают
админ-консоль на 7071админ-консоль на 6071интерфейс новый, логика прежняя
OpenLDAP с аккаунтамиOpenLDAP с аккаунтамисхема атрибутов почти полностью совместима

Что при этом не переносится и об этом стоит предупредить заказчика заранее: зимлеты (плагины старого веб-клиента — в новом интерфейсе их просто нет), кастомные темы и логотипы (брендирование делается заново), а также тонкие места sieve-фильтров — базовые правила «переместить в папку» переживают переезд, но конструкции, завязанные на специфику старого клиента, придётся перепроверить руками. Пользовательский интерфейс тоже другой: современнее и быстрее, но людям нужен один абзац инструкции и пара скриншотов, иначе понедельник утонет в звонках.

Схема миграции с Zimbra OSE на Carbonio CE: бесплатный путь через imapsync и платный через модуль Backup
Два пути между старым и новым сервером: скриптовый (LDAP + imapsync) и платный (модуль Backup)

Инвентаризация: без неё любой план миграции — фантазия

Первое, что мы делаем на старом сервере, — полная перепись хозяйства. За годы жизни Zimbra обрастает ящиками, о которых не помнит даже владелец бизнеса. Выгружаем всё в CSV прямо штатными средствами:

su - zimbra

# домены и списки рассылки
zmprov gad > /tmp/domains.txt
zmprov gadl > /tmp/lists.txt

# аккаунты: статус, квота, отображаемое имя, алиасы
for acc in $(zmprov -l gaa client.ru); do
  st=$(zmprov -l ga "$acc" zimbraAccountStatus | sed -n 's/^zimbraAccountStatus: //p')
  q=$(zmprov -l ga "$acc" zimbraMailQuota | sed -n 's/^zimbraMailQuota: //p')
  dn=$(zmprov -l ga "$acc" displayName | sed -n 's/^displayName: //p')
  al=$(zmprov -l ga "$acc" zimbraMailAlias | sed -n 's/^zimbraMailAlias: //p' | paste -sd'|')
  echo "$acc;$st;$q;$dn;$al" >> /tmp/accounts.csv
done

# фактически занятый объём по каждому ящику
zmprov gqu $(zmhostname) > /tmp/usage.txt

Файл usage.txt — ключ к планированию окна: он показывает реальные гигабайты по каждому ящику, и именно по нему считается, сколько будет идти первая синхронизация. Дальше три проверки, которые все пропускают, а потом страдают:

  • Кто чем подключается. Смотрим логи IMAP/POP3/ActiveSync за пару недель: сколько людей сидит в веб-клиенте, сколько в Outlook и Thunderbird, у кого почта на телефоне. От этого зависит объём «понедельничной» поддержки — толстые клиенты после смены сервера потребуют переввода пароля, а кто-то обнаружит настроенный в 2019 году POP3 с удалением писем с сервера.
  • Сервисные ящики. Сканер в бухгалтерии, отправка счетов из 1С, уведомления CRM и сайта, алерты железа — всё это шлёт почту через ваш сервер по SMTP и о смене адреса/пароля само не узнает. На каждой миграции находится минимум два таких «забытых» отправителя; ищем их по логам Postfix за месяц: grep 'sasl_username' /var/log/zimbra.log.
  • Мёртвые души. Закрытые сотрудники со статусом closed и ящики, куда год ничего не приходило. Решаем с заказчиком до переезда: переносить, архивировать в tgz или удалить. Каждый лишний ящик — лишние часы синхронизации.

Правило ITfresh: итог инвентаризации — один CSV-файл, согласованный с заказчиком под подпись: какие ящики едут, какие архивируются, какие умирают. Все дальнейшие скрипты миграции читают именно его. «Пересоздадим по памяти» — так теряются алиасы, на которые завязаны регистрации в госсервисах и банках.

Путь 1, бесплатный: пересоздание аккаунтов + imapsync

Это наш основной маршрут для типовых инсталляций до 50–70 ящиков. Ни рубля лицензий: всё делается штатными CLI обоих серверов и открытым инструментом imapsync, который Жиль Ламираль развивает уже третье десятилетие.

Шаг 1. Пересоздаём домены и аккаунты из CSV

На новом сервере скриптом прогоняем согласованный список: создаём домены, аккаунты, алиасы и списки рассылки. С паролями два варианта. Первый — одноразовые пароли с принудительной сменой: чисто, но добавляет нагрузку на понедельник. Второй, наш любимый, — перенос хэшей: Zimbra и Carbonio хранят пароль в LDAP-атрибуте userPassword в совместимых форматах (SSHA-семейство), поэтому хэш можно выгрузить со старого сервера и записать на новый — пользователи вообще не заметят подмены сервера:

# на старом (от zimbra): выгружаем хэш
zmprov -l ga user@client.ru userPassword
# userPassword: {SSHA512}k3mR...базо64...

# на новом (от zextras): создаём аккаунт и подкладываем хэш как есть
carbonio prov ca user@client.ru CHANGEme displayName "Иван Петров"
carbonio prov ma user@client.ru userPassword '{SSHA512}k3mR...'

Квоты, классы обслуживания и алиасы назначаем тем же циклом из CSV. Полчаса скриптовой работы — и новый сервер структурно идентичен старому.

Шаг 2. Гоним письма imapsync

Дальше — собственно письма. Наш рабочий шаблон запуска по списку:

while IFS=';' read -r user pw; do
  imapsync \
    --host1 oldmail.client.ru --user1 "$user" --password1 "$pw" --ssl1 \
    --host2 mail.client.ru   --user2 "$user" --password2 "$pw" --ssl2 \
    --automap --subscribeall \
    --useheader 'Message-Id' \
    --logdir /var/log/imapsync
done < migrate.list

Три флага здесь несут всю смысловую нагрузку. --automap сопоставляет служебные папки по их назначению, а не по имени — это спасает от классической беды кириллических инсталляций, когда «Отправленные» и Sent считаются разными папками и письма задваиваются по разным веткам. --useheader 'Message-Id' делает синхронизацию идемпотентной: повторный прогон докачивает только новое, уже перенесённые письма не дублируются — на этом свойстве построена вся схема «основной прогон + дельта» из раздела про день X. --subscribeall подписывает пользователя на все папки, иначе в IMAP-клиентах перенесённые ветки окажутся невидимыми. Запускаем в 3–4 параллельных потока (по потоку на группу ящиков) — дальше упираемся не в imapsync, а в диски старого сервера.

Шаг 3. Календари и контакты

imapsync переносит только почту: календари и адресные книги в Zimbra живут вне IMAP. Их вывозим через REST-интерфейс, который одинаково работает на обоих концах:

# на старом сервере: выгрузка
zmmailbox -z -m user@client.ru getRestURL "/Calendar?fmt=ics" > /migr/user-cal.ics
zmmailbox -z -m user@client.ru getRestURL "/Contacts?fmt=csv" > /migr/user-cont.csv

# на новом (от zextras): загрузка
zmmailbox -z -m user@client.ru postRestURL "/Calendar?fmt=ics" /migr/user-cal.ics
zmmailbox -z -m user@client.ru postRestURL "/Contacts?fmt=csv" /migr/user-cont.csv

Если у пользователя несколько календарей или адресных книг — каждую папку выгружаем отдельным вызовом по её имени. Повторяющиеся встречи и приглашения в ics-формате переживают переезд нормально; что теряется — так это статусы ответов участников по старым встречам, и это надо просто честно проговорить.

Хронометраж реального переезда: ~40 ящиков, 180 ГБ

Цифры одного из наших проектов прошлой осени, чтобы вы могли масштабировать на себя: инвентаризация и согласование списка — 3 часа в течение недели «до». Пересоздание структуры на новом сервере — 1,5 часа вместе с проверками. Первый полный прогон imapsync в четыре потока — около 14 часов, с вечера пятницы до утра субботы: упёрлись в старый RAID из ноутбучных дисков, а не в сеть. Календари и контакты — 2 часа вместе с выборочной сверкой. Дельта-прогон в воскресенье вечером — 40 минут. Сюрпризы тоже были: у двух ящиков нашлись письма с битыми заголовками 2012 года, которые старый сервер отдавал с ошибкой (лечится флагами обхода ошибок у imapsync с последующим точечным разбором лога), а один пользователь хранил 25 ГБ в «Корзине» — её мы с его согласия просто не повезли.

Путь 2, платный и быстрый: модуль Backup

У Zextras есть коммерческий модуль Backup, и у него есть режим восстановления из «внешнего» хранилища: на старом сервере с установленным модулем снимается полная резервная копия ящиков со всеми потрохами, затем на новом Carbonio она восстанавливается целиком. Ключевое отличие от imapsync — переезжают метаданные: тэги, флажки, статусы прочитанности во всех тонкостях, настройки папок, расшаренные права (кто кому открыл календарь и с какими правами), фильтры, подписи и настройки интерфейса. В скриптовом пути права на общие папки и календари приходится пересоздавать руками по описи — на 10 ящиках это мелочь, на 50 с развитой культурой шаринга — полдня кропотливой работы и главный источник обращений после переезда.

Когда мы советуем заплатить: ящиков больше 50–70, объёмы от полутерабайта, активно используются общие календари и делегирование, а окно на переезд жёсткое. Экономика простая: скриптовый путь на большой инсталляции — это 30–50 человеко-часов инженера с ставкой, которую вы знаете, плюс риск разбирательств «а у меня пропали тэги». Годовая подписка на модуль для полусотни ящиков часто оказывается сопоставима или дешевле — и при этом у вас остаётся сам модуль резервного копирования на будущее, что для почтового сервера в проде вообще-то не роскошь (почему мы считаем бэкап-контур обязательным — разбираем в статье об эксплуатации Carbonio CE).

Гибридная схема, которую мы применяем чаще всего на средних проектах: структуру и пароли переносим скриптами бесплатно, письма — imapsync, а платный модуль берём только если заказчику критичны расшаренные права и тэги. Решение принимается на этапе инвентаризации, когда видно реальное количество шарингов: zmmailbox -z -m user getFolderGrant-обходом по списку ящиков.

День X: последовательность переключения без потери писем

Таймлайн миграции почты за выходные: снапшот, синхронизация, смена MX, дельта-прогон, мониторинг
Выходные миграции по часам: от снапшота в пятницу до мониторинга в понедельник

«Не потерять ни одного письма» — это не лозунг, а следствие правильной последовательности. Вот наша, по шагам:

  1. Четверг: TTL вниз. На MX- и A-записях домена снижаем TTL до 300 секунд. Делать это надо минимум за сутки до смены, чтобы старое суточное значение успело истечь из кешей резолверов по всему миру.
  2. Пятница, вечер: снапшот и основной прогон. Снимаем снапшот/бэкап старого сервера (точка отката) и запускаем полный imapsync. Пользователи продолжают работать со старым сервером как обычно — синхронизация для них незаметна.
  3. Суббота: структура и сверка. Календари, контакты, подписи, проверка выборочных ящиков: количество писем по папкам на двух серверах должно сходиться с точностью до пришедших за ночь.
  4. Воскресенье, день: смена MX. Переключаем MX-запись на новый сервер. Благодаря низкому TTL мир узнаёт об этом за минуты, но «хвост» отправителей со старыми кешами и ретраями будет ещё долго стучаться по старому адресу — это нормально и предусмотрено следующим пунктом.
  5. Воскресенье, вечер: дельта и двоевластие. Финальный прогон imapsync докачивает всё, что пришло на старый сервер с пятницы (благодаря --useheader — только новое). После этого старый сервер переводим в режим релея: он ещё 72 часа принимает почту от «опоздавших» отправителей и тут же пересылает её на новый (в Zimbra это делается переключением транспорта домена на новый сервер). Ни одно письмо, прилетевшее в старый MX, не пропадает — оно доезжает до нового с задержкой в секунды.
  6. Понедельник, 8:00: инженер на связи. Не «посмотрим, как пойдёт», а выделенный человек на телефоне до обеда.

Чек-лист отката держим написанным заранее, а не сочиняем в панике: вернуть MX на старый сервер (при TTL 300 это минуты), выключить релейный режим, зафиксировать по логам, что успело прийти на новый сервер, и перелить эти письма обратным imapsync. За все годы откатываться нам пришлось один раз — и то из-за внезапно всплывшей интеграции, которую заказчик забыл показать на инвентаризации; сам откат занял 20 минут именно потому, что был расписан на бумаге.

Неделя после переезда: что мониторим и что чиним

Миграция заканчивается не в воскресенье вечером, а через неделю наблюдения. На новом сервере смотрим три вещи ежедневно:

  • Очередь Postfixpostqueue -p должна быть околонулевой. Растущая очередь в первые дни — почти всегда какой-нибудь получатель-домен, куда старый сервер ходил по особому маршруту, или greylisting на той стороне, помноженный на новый для получателей IP.
  • Отлупы в логах — грепаем reject и bounce: не завернул ли кто-то из крупных провайдеров ваш новый IP. SPF мы обновили при переезде, DKIM-ключ на новом сервере свой, но репутация IP нарабатывается — первые массовые рассылки счетов лучше отложить на несколько дней.
  • Хвост на старом сервере — сколько писем в сутки всё ещё прилетает в старый MX. К концу 72-часового двоевластия поток должен упасть до единичных писем от серверов с совсем ленивыми кешами.

Типовые обращения пользователей в первую неделю удивительно однообразны, и к ним можно подготовить готовые ответы заранее. «Пропало автодополнение адресов» — кеш недавних адресатов старого веб-клиента не переносится никаким путём, он наполнится заново за неделю-две переписки. «Пропала подпись» — подписи, хранившиеся на сервере, скриптовый путь не тащит: собираем их до переезда выгрузкой атрибута zimbraPrefMailSignature и заливаем на новый сервер тем же carbonio prov ma. «Не работает правило сортировки» — sieve-скрипт аккаунта (zimbraMailSieveScript) переносится тем же приёмом, но правила, ссылающиеся на несуществующие уже папки, молча отключаются — их проще перещёлкнуть в новом интерфейсе.

Старый сервер гасим не раньше чем через две недели тишины, и обязательно в правильном порядке: сначала снимаем финальный архив (tgz-выгрузка всех ящиков через REST плюс копия LDAP-дампа и /opt/zimbra/conf), кладём его в холодное хранилище с понятным сроком жизни — мы храним год, — и только потом выключаем виртуалку. Ещё месяц она лежит выключенной на датасторе и лишь затем удаляется. Диск дешевле, чем один-единственный вопрос «а поднимите письмо из марта» без ответа.

Смета миграции для директора

Финальный раздел — для тех, кто подписывает счёт. Оценки в человеко-часах из нашей практики, без экзотики:

Этап20 ящиков50 ящиковПростой для людей
Инвентаризация и согласование2–3 ч4–6 чнет
Новый сервер: установка и смоук-тест4–5 ч4–6 чнет
Структура, пароли, календари3–4 ч6–8 чнет
Синхронизация писем (машинное время)3–8 ч10–30 чнет
Переключение MX + дельта (выходные)2–3 ч3–5 чминуты
Неделя наблюдения и разбор обращений2–4 ч4–8 чнет

Обратите внимание на колонку простоя: практически весь проект идёт параллельно обычной работе, потому что первая синхронизация не мешает пользователям, а окно переключения укладывается в «тихие выходные». Реальный перерыв в приёме почты при описанной схеме — ноль: письма либо доезжают до нового MX, либо ретранслируются старым. Единственное, что пользователи замечают, — новый интерфейс в понедельник.

Теперь про деньги в сравнении с альтернативой «переехать в облачный офис». Подписка на облачную почту для 50 человек — это сотни тысяч рублей ежегодно, навсегда, плюс ваши данные на чужой стороне. Миграция на Carbonio CE — разовые 25–60 человеко-часов работ плюс сервер, который у большинства наших клиентов уже есть в виде гипервизора; дальше — только сопровождение, общее с остальной инфраструктурой. Окупаемость против облака у полусотни ящиков наступает в пределах первого года — подробные расчёты владения я приводил в обзорной статье серии. А если своего железа нет, мы размещаем такие серверы на наших мощностях в дата-центре МТС.

И последнее. Если после прочтения остаётся ощущение «понятно, но пусть это сделает кто-то, кто уже набил руку» — это ровно наша работа: за плечами и переезды клиентских Zimbra, и собственный сервер, переживший тот же маршрут. Напишите — посчитаем вашу конкретную инсталляцию по этой же смете. Смежные материалы: вариант с mailcow, если Carbonio для ваших задач избыточен, и остальные статьи блога.

Миграция почты под ключ

Перевезём вашу почту с Zimbra, Exchange или из облака на Carbonio CE без потери писем: инвентаризация, синхронизация, переключение за выходные и неделя сопровождения. Свои серверы в дата-центре МТС, 15+ лет практики.

✈️ Telegram @ITfresh_Boss 📞 +7 903 729-62-41
#миграция Zimbra #Carbonio CE #imapsync #Zimbra OSE EOL #CentOS 7 #перенос почты #регламент ITfresh
Комментарии 0

Оставить комментарий

загрузка...

Подпишитесь на рассылку ITfresh

Раз в неделю — практические гайды для руководителя IT и сисадмина: безопасность, 1С, миграции, резервные копии, лайфхаки из реальных проектов.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.