Бэкап Zimbra, не зависящий от вендора: LDIF, дамп и IMAP-копия

Торговая компания в Королёве, 35 рабочих мест, 54 ящика и 1,4 ТБ почты. В феврале 2025 директор поставил задачу так: «хочу, чтобы почту можно было поднять где угодно и без чьей-либо лицензии». Схему собрали из четырёх независимых элементов. Разбираю, что закрывает каждый, сколько это стоит по диску и почему я не считаю такую конструкцию избыточной.

«А если завтра лицензии не будет?»

Вопрос, который мне за последние три года задавали чаще всех остальных вместе взятых. Формулировки разные: не продлят подписку, не пропустят платёж, вендор уйдёт, поменяют условия. Суть одна — люди перестали считать доступ к чужому продукту гарантированным.

К почте это относится острее, чем к чему-либо ещё. Файлы можно скопировать и открыть чем угодно. База 1С поднимается на любой платформе. А почтовый архив, снятый фирменным модулем в фирменном формате, читается только этим модулем и только на такой же версии продукта. Нет модуля — нет почты, хотя терабайт данных лежит перед вами на диске.

Проверить это у себя можно одним вопросом: если завтра у вас останется только содержимое бэкап-хранилища и обычный сервер с Linux — вы сможете поднять почту? Не быстро, не красиво, а вообще?

Ниже — схема, при которой ответ «да». Она собрана у конкретного клиента и работает с февраля 2025 года.

Февраль 2025, Королёв: что было до нас

Торговая компания, склад и офис на проспекте Космонавтов в Королёве, 35 рабочих мест. Возят электрокомпоненты, работают с сотней поставщиков, вся история заказов — в почте. Zimbra 9 в community-сборке на своей виртуалке, Ubuntu, гипервизор в арендованной стойке. Официальных бесплатных сборок девятки не существует — с этой версии вендор их не выкладывает, и в открытом доступе живут сборки энтузиастов. Клиент, сам того не планируя, уже зависел не от вендора, а от чужой доброй воли: это и стало половиной аргумента в разговоре про бэкап.

  • 54 ящика: 35 личных, 7 общих (zakaz@, sklad@, buh@ и четыре по направлениям) и 12 оставшихся от уволенных — их держат ради истории переписки;
  • store — 1,4 ТБ, индекс — 92 ГБ, база — 26 ГБ;
  • самый большой ящик — 187 ГБ, у руководителя отдела закупок;
  • бэкап на входе: ежесуточный снапшот виртуалки на хранилище того же гипервизора. И всё.

Предыдущий подрядчик схему считал достаточной, и формально он был прав: снапшоты снимались, места хватало, восстановление один раз даже проверяли. Но закрывала эта схема ровно один сценарий из четырёх возможных.

Директор сформулировал задачу коротко: чтобы почта поднималась где угодно и без чьей-либо лицензии. Под «где угодно» он имел в виду и другую платформу тоже — на случай, если Zimbra в какой-то момент перестанет быть вариантом.

Ложная версия, которую я сам держал несколько лет

Я долго считал, что снапшот виртуалки — это и есть нормальный бэкап почты. Быстро, дёшево, восстанавливается за 20 минут. Такую схему я ставил клиентам примерно до 2019 года и защищал её в спорах.

Разубедили меня два случая подряд, оба чужие, оба неприятные. В первом шифровальщик добрался до хранилища снапшотов, потому что оно было смонтировано на том же гипервизоре. Во втором отказал массив, и снапшоты умерли вместе с продуктивной машиной — они лежали на тех же дисках.

Снапшот отвечает ровно на один вопрос: «мы сломали сервер, железо живо». На остальные три он не отвечает вовсе.

СценарийСнапшотФайловый архив
Сломали конфиг, машина целаСпасает, 20 минутСпасает, дольше
Отказ хранилища гипервизораНе спасаетСпасает
Шифровальщик добрался до инфраструктурыОбычно не спасаетСпасает, если копия вне периметра
Нужно поднять почту на другой платформеБесполезенСпасает

Есть и техническая деталь, о которой редко говорят. Снапшот живой машины несогласован сам с собой: письма на диске, метаданные в базе и то, что в этот момент было в оперативной памяти, относятся к разным моментам времени. Обычно это сходит с рук. Иногда — нет, и тогда вы поднимаете сервер, у которого база знает про письма, которых на диске уже нет.

Элемент первый: каталог в LDIF

Самая дешёвая и самая недооценённая часть схемы. Каталог — это учётные записи, домены, алиасы, списки рассылки, классы обслуживания, права доступа, настройки аутентификации. Всё, что делает набор писем почтовой системой.

Хранится каталог в базе формата mdb, и вот главное свойство этого формата: он не чинится на месте. Никаким инструментом. При повреждении единственный путь — выгрузить содержимое в текстовый LDIF, создать новую пустую базу и залить дамп обратно.

su - zimbra
/opt/zimbra/libexec/zmslapcat /backup/ldap/$(date +%F)

# восстановление в новую базу (служба остановлена):
#   mv /opt/zimbra/data/ldap/mdb /opt/zimbra/data/ldap/mdb.old
#   mkdir -p /opt/zimbra/data/ldap/mdb/db
#   chown -R zimbra:zimbra /opt/zimbra/data/ldap/mdb
#   /opt/zimbra/libexec/zmslapadd /backup/ldap/2025-02-18/ldap.bak

Из этого следует простая вещь: если у вас в бэкапе лежат только файлы базы каталога, скопированные с работающего сервера, — у вас нет резервной копии каталога. У вас есть копия того же самого объекта, который может быть повреждён.

LDIF — обычный текст. Его читает любая версия Zimbra, любая версия OpenLDAP и вообще любой инструмент, умеющий этот формат. У клиента в Королёве файл весит 47 МБ. Сорок семь мегабайт против 1,4 ТБ почты — и без него все 54 учётки, домены и права придётся заводить руками.

# в crontab пользователя zimbra
15 2 * * * /opt/zimbra/libexec/zmslapcat /backup/ldap/$(date +\%F) >/dev/null 2>&1
20 2 * * * find /backup/ldap -maxdepth 1 -type d -mtime +45 -exec rm -rf {} +

Элемент второй: дамп базы — и осторожно с проверками

База держит метаданные: какое письмо в какой папке, кем прочитано, какие теги, какие флаги. Сами письма лежат отдельными файлами в /opt/zimbra/store. Одно без другого бесполезно.

Дамп снимается на остановленной службе. Не «желательно», а именно так: на живом сервере дамп получится несогласованным со store, и вы это обнаружите только при восстановлении. У клиента окно — 11 минут в воскресенье в 04:00. За год ни один человек его не заметил.

su - zimbra
/opt/zimbra/libexec/zmdbintegrityreport -v
zmcontrol stop
mysql.server start
mysqldump --all-databases \
    -S /opt/zimbra/data/tmp/mysql/mysql.sock \
    -u root -p$(zmlocalconfig -m nokey -s mysql_root_password) \
    | gzip -6 > /backup/db/zimbra-$(date +%F).sql.gz
mysql.server stop
zmcontrol start

Проверка целостности перед каждым дампом — обязательная точка. Смысл в том, чтобы не положить в архив уже повреждённую базу и не обнаружить это через полгода.

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

В версии 10.0.8 Network Edition этот инструмент неверно разбирает адреса файлов на вторичных томах в S3-совместимом хранилище и объявляет пропавшими все письма, которые там лежат. Если в этот момент запустить его с ключом --missing-blob-delete-item, он честно удалит из базы записи о совершенно живых письмах. Данные при этом станут недоступны пользователям.

# так — нельзя, если есть S3-том:
# zmblobchk --missing-blob-delete-item

# так — можно: явно ограничить проверку локальными томами
su - zimbra -c 'zmvolume -l'
su - zimbra -c 'zmblobchk --volumes 1,2 --export-dir /tmp/blobchk start'

Правило, которое я держу для себя: любая утилита с глаголом delete в названии ключа запускается только после того, как отчёт без этого ключа прочитан глазами. Целиком.

Элемент третий: поящичные архивы

Дамп базы плюс store восстанавливают сервер целиком. Но когда нужен один ящик — а нужен чаще всего именно один, — разворачивать всё это ради него не хочется. Поэтому рядом лежат отдельные архивы по ящикам.

#!/bin/bash
# /opt/zimbra/scripts/mbox-dump.sh, из-под zimbra
DST=/backup/mbox/$(date +%F); mkdir -p $DST
for m in $(zmprov -l gaa); do
  case $m in galsync*|ham.*|spam.*|virus-quarantine.*) continue;; esac
  /opt/zimbra/bin/zmmailbox -z -m $m -t 0 \
      getRestURL "//?fmt=tgz" > $DST/$m.tgz
done

Два момента, на которых спотыкаются почти все. Первый — ключ -t 0: без бесконечного таймаута выгрузка ящика на 187 ГБ обрывается на середине. Второй — служебные учётки вроде galsync, spam, ham и карантина: их не надо выгружать как обычные ящики, они создаются заново при установке.

Полный набор архивов у клиента занял 780 ГБ против 1,4 ТБ живого store — сжатие даёт примерно сорок пять процентов. Гоняем полный набор раз в неделю по ночам, шесть самых нагруженных ящиков — ежесуточно.

Формат tgz честно ограничен: это инструмент Zimbra для Zimbra. Развернуть такой архив в mailcow или Carbonio напрямую нельзя. Для этого в схеме есть четвёртый элемент.

Элемент четвёртый: живая IMAP-копия

Самая интересная часть. На отдельной машине, в другом дата-центре, стоит второй почтовый сервер, и на него ежесуточно доливается почта по IMAP. Не образ, не архив — работающий сервер с теми же письмами.

Инструмент — imapsync. Он работает поверх протокола, поэтому ему всё равно, что стоит с той и с другой стороны: Zimbra, mailcow, Carbonio, что угодно ещё, лишь бы говорило по IMAP.

imapsync --host1 mail.example.ru --user1 zakaz@example.ru \
         --password1 'ХХХ' --ssl1 \
         --host2 mail2.example.ru --user2 zakaz@example.ru \
         --password2 'YYY' --ssl2 \
         --useheader "Message-Id" --skipsize --nofoldersizes \
         --logfile /var/log/imapsync/zakaz.log

Пароли в командной строке видны в ps любому, кто есть на машине, поэтому в расписании они лежат в файлах: --passfile1 и --passfile2 вместо --password1/2. Учётки на приёмнике заводятся тем же LDIF, что и на источнике: раз в месяц я сверяю список ящиков на обеих машинах простым zmprov -l gaa с двух сторон и создаю недостающие — новый сотрудник иначе попадёт в реплику только после того, как кто-то про него вспомнит.

Два свойства делают его пригодным для роли реплики. Повторный запуск безопасен: письма сверяются по заголовкам Message-Id и Received, дубликаты не создаются. И по умолчанию инструмент ничего не удаляет на приёмнике — только добавляет. Значит, случайное удаление на боевом сервере не размножится на копию.

Оборотная сторона того же свойства: копия постепенно распухает. У нас за год приёмник вырос до 1,63 ТБ при 1,4 ТБ на источнике — разница как раз то, что люди удалили. Раз в полгода я это разгребаю вручную, и другого способа пока не придумал.

Первичная заливка 1,4 ТБ заняла 61 час, растянутых на пять ночей. Ежесуточная дельта проходит за 12–25 минут.

Проверьте у себя за 2 минуты

Четыре команды на боевом сервере. Ничего не меняют.

su - zimbra -c 'zmcontrol -v'
ls -lh /backup/ldap/ 2>/dev/null | tail -3
ls -lh /backup/db/ 2>/dev/null | tail -3
su - zimbra -c 'zmvolume -l'
Что получилосьЧто это значит
Выгрузки каталога в LDIF нетУчётки, домены и права держатся на одной копии базы mdb, которая не чинится на месте. Стоит эта страховка 47 МБ и одну строку в расписании.
Дамп базы есть, но снимается на работающей службеОн несогласован со store. Восстановится, но с расхождениями, которые вы увидите не сразу.
В бэкапе только снапшоты виртуалкиЗакрыт один сценарий из четырёх. При отказе хранилища или шифровальщике внутри периметра он не поможет.
Бэкап лежит на том же гипервизоре и том же массивеОбщая точка отказа. Именно так теряют всё сразу — я видел это дважды.
zmvolume -l показывает вторичный том в S3Не запускайте проверку целостности файлов с ключом удаления записей. В 10.0.8 NE это реально стирает живые письма из базы.
Копии на другой платформе нет вообщеПереезд куда-либо, кроме такой же Zimbra, начнётся с нуля и займёт недели, а не дни.

Сколько это стоит и почему я не считаю схему избыточной

Считаем честно. Диск под всю конструкцию у клиента в Королёве:

ЭлементОбъёмЧастота
Каталог в LDIF, 45 копий2,1 ГБежесуточно
Дамп базы, 14 копий67 ГБеженедельно
Поящичные архивы, 2 набора1,56 ТБеженедельно
IMAP-реплика на второй площадке1,63 ТБежесуточно

Итого около 3,3 ТБ хранилища при 1,4 ТБ живой почты. Настройка заняла у нас 9 часов, включая первичную заливку реплики, которая шла фоном. Обслуживание — примерно час в месяц: посмотреть журналы, разгрести разницу на реплике, проверить, что архивы не встали.

Теперь цена альтернативы. Компания на 35 человек, живущая заказами из почты, без переписки не работает вообще. Сутки простоя — это несогласованные отгрузки, потерянные заявки и звонки от поставщиков, на которые никто не может ответить. Директор оценил день в 400–450 тысяч рублей оборота, из которого маржа — тысяч восемьдесят. Три дня восстановления с нуля — это четверть миллиона и репутация, которую считать сложнее.

Против этого — 3,3 ТБ дисков и час в месяц. Мне такой обмен кажется очевидным, но я понимаю и обратную позицию: пока ничего не падало, любая схема выглядит избыточной. Проверяется это ровно один раз.

Где ломается самостоятельная сборка — я показал по ходу: несогласованный дамп на живой службе, копия базы каталога вместо LDIF, ключ удаления записей на S3-томе, оборванная выгрузка без бесконечного таймаута. Каждая из этих вещей выглядит мелочью и каждая обнаруживается только при восстановлении.

Хотите понять своё положение — пришлите вывод четырёх команд из блока проверки и одной строкой напишите, где физически лежит ваш бэкап. За день отвечу, какие из четырёх сценариев аварии у вас закрыты, а какие нет, и что дешевле всего добавить первым.

Частые вопросы

Зачем выгружать каталог отдельно, если он и так попадает в бэкап вместе с /opt/zimbra?

Потому что в бэкап попадают файлы базы формата mdb, а эта база не ремонтируется на месте. Если она повредилась — а повредиться она может и от переполнения, и от копирования на живой службе, — вы получите копию уже сломанного объекта. Единственный рабочий путь восстановления выглядит так: выгрузить содержимое в текстовый LDIF, снести повреждённую базу, создать новую пустую и залить дамп. Выгрузка в LDIF делается штатной командой zmslapcat, весит десятки мегабайт и читается любой версией. У клиента в Королёве файл — 47 МБ при 1,4 ТБ почты. Это самая дешёвая страховка во всей схеме.

Обязательно ли останавливать почту ради дампа базы?

Для согласованного дампа — да, и это единственное место в схеме, где нужен простой. Письма лежат отдельными файлами на диске, метаданные — в базе, и если снимать дамп на работающем сервере, эти две части будут относиться к разным моментам времени. При восстановлении вы получите базу, которая знает про письма, отсутствующие на диске, или наоборот. У торговой компании окно — 11 минут ночью в воскресенье, в 04:00. За год ни один сотрудник этого не заметил, а вопрос о согласованности закрыт полностью. Если простой невозможен категорически, остаётся поящичная выгрузка — она согласована по построению, но восстанавливается дольше.

IMAP-реплика — это же почти второй сервер. Не дорого ли?

Дороже остальных элементов, спорить не буду: нужна вторая машина и второй объём диска. Но она единственная закрывает сценарий «поднять почту на другой платформе». Все остальные элементы схемы — родные форматы Zimbra, и развернуть их можно только в Zimbra. Реплика работает поверх протокола IMAP, поэтому на её месте может стоять mailcow, Carbonio или что угодно ещё. Дополнительный бонус: она проверяется сама собой. Если письма туда приезжают и открываются, значит данные читаемы — вам не надо ставить отдельное учение, чтобы это выяснить. У клиента ежесуточная дельта проходит за 12–25 минут.

Почему imapsync, а не doveadm — он же быстрее?

Быстрее, но применим только когда обе стороны построены на Dovecot. Классическая Zimbra — не Dovecot, поэтому в паре «Zimbra → что-нибудь» работает именно imapsync поверх протокола. Doveadm становится актуален на следующем шаге, когда вы уже переехали и обе площадки, например, на mailcow: там разница в скорости заметная, потому что нет накладных расходов протокола на каждую операцию. Ещё одна деталь в пользу imapsync для роли реплики: он по умолчанию ничего не удаляет на приёмнике. Doveadm в режиме backup, наоборот, приводит приёмник в точное соответствие источнику — то есть удаление на боевом сервере повторится на копии, и это ровно то, чего от резервной копии не ждут.

Как проверить, что схема действительно работает, не устраивая полное учение?

Есть быстрая проба на 40 минут. Возьмите архив одного среднего ящика, разверните его во временную учётку и откройте письма разных лет — самое старое, самое новое и что-нибудь с крупным вложением. Отдельно откройте LDIF в текстовом редакторе и убедитесь, что там есть записи ваших доменов и хотя бы несколько учёток с полем userPassword. Отдельно распакуйте дамп базы и посмотрите, что он не обрывается на середине. Три проверки, каждая — минуты. Полное учение с разворотом сервера с нуля я всё равно рекомендую раз в год, но эти пробы ловят большинство проблем гораздо раньше.

Нужна помощь с проектом?

Специалисты АйТи Фреш помогут с архитектурой, DevOps, безопасностью и разработкой — 15+ лет опыта

📞 Связаться с нами
#Zimbra#бэкап#LDAP#imapsync#MariaDB
Комментарии 0

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

загрузка...

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

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

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

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