Резервное копирование и восстановление почтовых ящиков в Zimbra Collaboration 8.6
В этой статье мы разбирали как развернуть Zimbra Collaboration 8.6
на Ubuntu 14.04 Trusty Tahr
. В бесплатной версии почтового сервера нет удобного функционала по бекапу и восстановлению почтовых ящиков. А создание бекапов, есть неотъемлемая часть работы любого системного администратора. Да и наличие бекапа всегда нас спасет в трудную минуту.
Создавать бекапы и восстанавливать их же будем посредством bash-скриптов
. Создавать и восстанавливать почтовые ящики мы будем на горячую так сказать, без остановки почтового сервера.
Резервное копирование всех почтовых ящиков
Создаем текстовый файл и делаем его исполняемым:
nano backup_all_mailbox.sh sudo chmod +x backup_all_mailbox.sh
В созданный скрипт вписываем следующее (в параметрах настроек скрипта указываем данные свои):
#!/bin/bash ##################### # Настройки скрипта # ##################### # Путь к месту бекапа Path_backup="/home/jakonda/bkzm" # Временный файл для работы Source_list="/home/jakonda/temp" # Название домена Domain="jakondo.ru" # Значение текущей даты Current_date=$(date +%d-%m-%Y) # Лог-файл Log=$Path_backup"/"$Current_date"/log" echo "#####################################################" echo "# Резервное копирование всех почтовых ящиков Zimbra #" echo "#####################################################" echo "" echo "Время начала бекапа всех почтовых ящиков - $(date +%T)" echo "Начало бекапа - $(date +%T)" > $Log # Запоминаем время начала бекапа Begin_time=$(date +%s) echo "" # Определяем список всех имеющихся почтовых ящиков echo "Формируем список всех почтовых ящиков для бекапа..." /opt/zimbra/bin/zmprov -l gaa $Domain > $Source_list if [ $? -eq 0 ]; then echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]" echo "Формирование списка почтовых ящиков успешно выполнено." >> $Log echo else echo -n "$(tput hpa $(tput cols))$(tput cub 6)[FAIL]" echo "Формирование списка почтовых ящиков не удалось выполнить. Завершение работы (Неудача)." >> $Log exit echo fi # Проходимся по всем ящикам в полученном списке и делаем бекап каждого echo "Выполняем резервное копирование всех почтовых ящиков" echo "----------------------------------------------------" mkdir -p $Path_backup/$Current_date/ echo "Создание каталога $Current_date для размешения бекапа." >> $Log for mailbox in $( cat $Source_list); do echo "Резервирование почтового ящика - $mailbox" /opt/zimbra/bin/zmmailbox -z -m $mailbox getRestUrl "//?fmt=tgz" > $Path_backup/$Current_date/$mailbox.tgz if [ $? -eq 0 ]; then echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]" echo "Бекап почтового ящика $mailbox успешен" >> $Log echo else echo -n "$(tput hpa $(tput cols))$(tput cub 6)[FAIL]" echo "Бекап почтового ящика $mailbox не удачно" >> $Log echo fi done # Вычисление времени работы бекапа почтовых ящиков End_time=$(date +%s) Elapsed_time=$(expr $End_time - $Begin_time) Hours=$(($Elapsed_time / 3600)) Elapsed_time=$(($Elapsed_time - $Hours * 3600)) Minutes=$(($Elapsed_time / 60)) Seconds=$(($Elapsed_time - $Minutes * 60)) echo "Затрачено времени на резервное копирование : $Hours час $Minutes минут $Seconds секунд" echo "Затрачено времени на резервное копирование : $Hours час $Minutes минут $Seconds секунд" >> $Log
В ходе выполнения скрипта, сначала формируется список всех почтовых ящиков имеющихся в указанном домене, затем по каждому почтовому ящику создается бекап, в конце создается лог файл. Пример вывода работы скрипта:
##################################################### # Резервное копирование всех почтовых ящиков Zimbra # ##################################################### Время начала бекапа всех почтовых ящиков - 05:36:51 Формируем список всех почтовых ящиков для бекапа... [OK] Выполняем резервное копирование всех почтовых ящиков ---------------------------------------------------- Резервирование почтового ящика - galsync@jakondo.ru [OK] Резервирование почтового ящика - jakonda1@jakondo.ru [OK] Резервирование почтового ящика - jakonda2@jakondo.ru [OK] Затрачено времени на резервное копирование : 0 час 0 минут 22 секунд
Лог файл выглядит вот так:
Начало бекапа - 07:50:26 Формирование списка почтовых ящиков успешно выполнено. Создание каталога 24-01-2017 для размешения бекапа. Бекап почтового ящика galsync@jakondo.ru успешен Бекап почтового ящика jakonda1@jakondo.ru успешен Бекап почтового ящика jakonda2@jakondo.ru успешен Затрачено времени на резервное копирование : 0 час 0 минут 21 секунд
Теперь можно скрипт закидывать в cron
и быть спокойным что у нас всегда будет под рукой бекап почтовых ящиков.
Резервное копирование конкретного почтового ящика
Выше мы рассмотрели как бекапить все имеющиеся почтовые ящики в домене, а если нам нужно создать бекап только одного почтового ящика, то мы для удобства работы немного изменим скрипт. Создаем текстовый файл и делаем его исполняемым:
nano backup_single_mailbox.sh sudo chmod +x backup_single_mailbox.sh
В созданный скрипт вписываем следующее (в параметрах настроек скрипта указываем данные свои):
#!/bin/bash ##################### # Настройки скрипта # ##################### # Путь к месту бекапа Path_backup="/home/jakonda/bkzm" # Название домена Domain="jakondo.ru" # Значение текущей даты Current_date=$(date +%d-%m-%Y) # Лог-файл Log=$Path_backup"/"$Current_date"/log_single" echo "################################################" echo "# Резервное копирование почтового ящика Zimbra #" echo "################################################" echo "" # Запрос ввода имени почтового ящика read -p "Введите название почтового ящика: " Mail_name echo "Время начала бекапа почтового ящика ($Mail_name@$Domain) - $(date +%T)" # Запоминаем время начала бекапа Begin_time=$(date +%s) echo "" # Выполняем бекап указанного почтового ящика echo "Выполняем резервное копирование почтового ящика $Mail_name@$Domain" mkdir -p $Path_backup/$Current_date/ echo "Запрос на бекап почтового ящика $Mail_name@$Domain" >> $Log echo "Начало бекапа - $(date +%T)" >> $Log /opt/zimbra/bin/zmmailbox -z -m $Mail_name"@"$Domain getRestUrl "//?fmt=tgz" > $Path_backup/$Current_date/$Mail_name"@"$Domain.tgz if [ $? -eq 0 ]; then echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]" echo "Бекап почтового ящика $Mail_name@$Domain успешен" >> $Log echo else echo -n "$(tput hpa $(tput cols))$(tput cub 6)[FAIL]" echo "Бекап почтового ящика $Mail_name@$Domain не удачно" >> $Log # Удаляем неудачный файл rm $Path_backup/$Current_date/$Mail_name"@"$Domain.tgz echo fi # Вычисление времени работы бекапа почтовых ящиков End_time=$(date +%s) echo "Конец бекапа - $(date +%T)" >> $Log Elapsed_time=$(expr $End_time - $Begin_time) Hours=$(($Elapsed_time / 3600)) Elapsed_time=$(($Elapsed_time - $Hours * 3600)) Minutes=$(($Elapsed_time / 60)) Seconds=$(($Elapsed_time - $Minutes * 60)) echo "Затрачено времени на резервное копирование : $Hours час $Minutes минут $Seconds секунд" echo "Затрачено времени на резервное копирование : $Hours час $Minutes минут $Seconds секунд" >> $Log
В ходе выполнения скрипта запрашивается у пользователя имя почтового ящика и создается бекап указанного почтового ящика, в конце создается лог файл. Пример вывода работы скрипта:
################################################ # Резервное копирование почтового ящика Zimbra # ################################################ Введите название почтового ящика: jakonda2 Время начала бекапа почтового ящика (jakonda2@jakondo.ru) - 10:00:53 Выполняем резервное копирование почтового ящика jakonda2@jakondo.ru [OK] Затрачено времени на резервное копирование : 0 час 0 минут 7 секунд
Лог файл выглядит вот так:
Запрос на бекап почтового ящика jakonda2@jakondo.ru Начало бекапа - 10:00:53 Бекап почтового ящика jakonda2@jakondo.ru успешен Конец бекапа - 10:01:00 Затрачено времени на резервное копирование : 0 час 0 минут 7 секунд
Мы получили удобный в работе скрипт по созданию бекапа отдельно взятого почтового ящика.
Восстановление почтового ящика из резервной копии
Для того что бы восстановить из бекапа почтовый ящик, я ниже представлю скрипт, через который это будет удобно делать. В скрипте реализовано как ввод за какую дату использовать для восстановления бекап, так же указание имени почтового ящика. Если за указанную дату и указанный букап существует, то он автоматически восстановится.
Так же учтен такой момент, как наличие почтового аккаунта в Zimbra, т.е. допустим уже удален почтовый аккаунт, но есть бекап почтового ящика удаленного аккаунта. Если просто восстановить из бекапа почтовый ящик, то толку не будет, нужно предварительно создать аккаунт и только потом восстанавливать из бекапа ящик. Скрипт делает это в автоматическом режиме, т.е. он проверяет наличие аккаунта и если он есть, то просто восстанавливает ящик, а если его нет, то он создается и следом восстанавливается ящик.
Создаем текстовый файл и делаем его исполняемым:
nano restore_single_mailbox.sh sudo chmod +x restore_single_mailbox.sh
В созданный скрипт вписываем следующее (в параметрах настроек скрипта указываем данные свои):
#!/bin/bash ##################### # Настройки скрипта # ##################### # Путь где хранятся бекапы Path="/home/jakonda/bkzm" # Название домена Domain="jakondo.ru" echo "#########################################" echo "# Восстановление почтового ящика Zimbra #" echo "#########################################" echo "" # Запрос даты, за какое число нужно восстановить бекап read -p "Введите дату за какое число восстановить из бекапа (прим. 01-01-1985): " Date # Проверим наличия бекапов за указанную дату if ! [ -d $Path/$Date ]; then echo 'Нет бекапов на указанную дату... Завершаем работу скрипта.' exit fi # Лог-файл Log=$Path"/"$Date"/log_single_restore" # Запрос имени почтового ящика, который нужно восстановить read -p "Введите имя почтового ящика (без указания домена): " MailBox # Проверяем есть ли бекап почтового ящика с указанным именем MailBox=$MailBox"@"$Domain if ! [ -f $Path/$Date/$MailBox.tgz ]; then echo 'Нет бекапа указанного почтового ящика... Завершаем работу скрипта.' exit fi echo "Время начала восстановление почтового ящика ($MailBox) - $(date +%T)" # Запоминаем время начала восстановления Begin_time=$(date +%s) echo "" >> $Log echo "Начало процесса восстановления - $(date +%T)" >> $Log echo "" # Проверяем существует ли восстонавливаемый почтовый ящик echo "Проверяем существует ли почтовый ящик $MailBox в Zimbra" Result=$(/opt/zimbra/bin/zmprov getMailboxInfo $MailBox) if [ $? -eq 0 ]; then echo -n "$(tput hpa $(tput cols))$(tput cub 6) [OK]" echo "Почтовый ящик $MailBox существует, восстанавливаем его..." >> $Log echo echo "Почтовый ящик $MailBox существует, восстанавливаем его..." echo else echo -n "$(tput hpa $(tput cols))$(tput cub 6) [FAIL]" echo "Почтовый ящик $MailBox не существует, создаем его..." >> $Log echo echo "Почтовый ящик $MailBox не существует, создаем его..." echo # Запрос имени почтового ящика, который нужно восстановить read -p "Введите ФИО владельца почтового ящика $MailBox (Иванов Иван Иванович): " FIO Result=$(/opt/zimbra/bin/zmprov ca $MailBox Aa1234567 displayName "$FIO") if [ $? -eq 0 ]; then echo -n "$(tput hpa $(tput cols))$(tput cub 6) [OK]" echo "Почтовый ящик $MailBox успешно создан, продолжаем восстановление его..." >> $Log echo echo "Почтовый ящик $MailBox успешно создан, продолжаем восстановление его..." echo else echo -n "$(tput hpa $(tput cols))$(tput cub 6) [FAIL]" echo "Почтовый ящик $MailBox не удалось создать, завершаем работу скрипта." >> $Log echo echo "Почтовый ящик $MailBox не удалось создать, завершаем работу скрипта." echo exit fi fi # Выполняем восстановление указанного почтового ящика echo "Восстановление почтового ящика $MailBox" Result=$(/opt/zimbra/bin/zmmailbox -z -m $MailBox -t 0 postRestURL «//?fmt=tgz&resolve=replace» $Path/$Date/$MailBox.tgz) if [ $? -eq 0 ]; then echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]" echo "Восстановление почтового ящика $MailBox успешено" >> $Log echo else echo -n "$(tput hpa $(tput cols))$(tput cub 6)[FAIL]" echo "Восстановление почтового ящика $MailBox не удачно" >> $Log echo fi # Вычисление времени работы бекапа почтовых ящиков End_time=$(date +%s) echo "Конец восстановления - $(date +%T)" >> $Log Elapsed_time=$(expr $End_time - $Begin_time) Hours=$(($Elapsed_time / 3600)) Elapsed_time=$(($Elapsed_time - $Hours * 3600)) Minutes=$(($Elapsed_time / 60)) Seconds=$(($Elapsed_time - $Minutes * 60)) echo "Затрачено времени на восстановление : $Hours час $Minutes минут $Seconds секунд" echo "Затрачено времени на восстановление : $Hours час $Minutes минут $Seconds секунд" >> $Log
В ходе выполнения скрипта запрашивается сперва дата бекапа, затем имя почтового аккаунта (без указания домена), следом идет проверка существования аккаунта в Zimbra
(в случае его отсутствия, он создается) и производится восстановление почтового ящика, в конце создается лог файл. Пример вывода работы скрипта (при условии что аккаунт в Zimbra
отсутствует):
######################################### # Восстановление почтового ящика Zimbra # ######################################### Введите дату за какое число восстановить из бекапа (прим. 01-01-1985): 24-01-2017 Введите имя почтового ящика (без указания домена): jakonda_test Время начала восстановление почтового ящика (jakonda_test@jakondo.ru) - 03:18:18 Проверяем существует ли почтовый ящик jakonda_test@jakondo.ru в Zimbra [FAIL] ERROR: account.NO_SUCH_ACCOUNT (no such account: jakonda_test@jakondo.ru) Почтовый ящик jakonda_test@jakondo.ru не существует, создаем его... Введите ФИО владельца почтового ящика jakonda_test@jakondo.ru (Иванов Иван Иванович): Иванов Иван Иванович Почтовый ящик jakonda_test@jakondo.ru успешно создан, продолжаем восстановление его... [OK] Восстановление почтового ящика jakonda_test@jakondo.ru [OK] Затрачено времени на восстановление : 0 час 0 минут 43 секунд
Лог файл выглядит вот так:
Начало процесса восстановления - 03:18:18 Почтовый ящик jakonda_test@jakondo.ru не существует, создаем его... Почтовый ящик jakonda_test@jakondo.ru успешно создан, продолжаем восстановление его... Восстановление почтового ящика jakonda_test@jakondo.ru успешено Конец восстановления - 03:19:01 Затрачено времени на восстановление : 0 час 0 минут 43 секунд
Вот такими способами можно легко делать резервные копии почтовых ящиков и с той же легкостью восстанавливать их из резервной копии.
ПОНРАВИЛАСЬ ИЛИ ОКАЗАЛАСЬ ПОЛЕЗНОЙ СТАТЬЯ, ПОДДЕРЖИ АВТОРА ДОНАТОМ
Скрипт на создание отрабатывает, создает бэкап. После удалая ящик, запускаю скрипт на восстановление удаленного ящика, но выскакивает ошибка ./restore_single_mailbox.sh: line 72: /home/…./bkzm/01-12-2023/domain.ru.tgz: Permission denied. В админке при этом создается пустой почтовый ящик. Zimbra 8.8.15 , подскажите куда копать
права на файл бекапа проверьте, ругается на это явно —
Permission denied
При восстановление выдает такую ошибку:
ERROR: zclient.IO_ERROR (Read timed out) (cause: java.net.SocketTimeoutException Read timed out)
В чем может быть причина?
В скрипте восстановления есть 2 ошибки:
1. Переменную Path_backup нужно исправить на Path
2. Если архив под восстановление больше 4 Гб , то спустя минут 15 выводит ошибку ERROR: zclient.IO_ERROR (Read timed out) (cause: java.net.SocketTimeoutException Read timed out)
Решение , добавить в скрипте восстановление параметр -t 0 , чтобы получилось
Result=$(/opt/zimbra/bin/zmmailbox -z -m $MailBox -t 0 postRestURL «//?fmt=tgz&resolve=replace» $Path/$Date/$MailBox.tgz)
Автору спасибо большое за скрипты
Спасибо! Исправления внес!
здесь тоже ошибка.
«//?fmt=tgz&resolve=replace»
вот так будет правильней:
«//?fmt=tgz&resolve=replace»
😉
У вас был опыт восстановления из бекапа почтового ящика более 1 гигабайта?
Столкнулся с проблемой что зимбра рабивает инбокс на несколько инбоксов с индексом и пользователь ругается, что все разбилось по папкам.
не совсем правильно выразился наверное, восстановление архивов почты по списку ящиков. не одного почтового ящика, а нескольких ..
Такого скприта я не писал, т.к. не видел в нем надобности для себя. Но все возможно, восстанавливать к примеру из списка..
А есть вариант восстановления списка ящиков?
Есть конечно, в статье он описан
Ув. roman@kovenya.ru, я не могу разместить ваши посты. Рад что вы модернизировали скрипт под свои нужны, но данный блог про мои труды.
Печаль. Надо пилить свой блог =) Тем не менее присмотритесь к моим решениям, возможно найдёте для себя что-то интересное.
Спасибо, мой вариант скрипта писался строго под мои нужны и он меня более чем устраивает на данный момент 😉 У меня нет сложностей расширить его в случае надобности.
После обновления с 8.6 на 8.7 при выполнении /opt/zimbra/bin/zmmailbox -z -m $Mail_name»@»$Domain происходит ошибка
ERROR: zclient.IO_ERROR (invoke sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target, server: localhost) (cause: javax.net.ssl.SSLHandshakeException sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target)
Что может быть, не подскажите?
Судя по ошибке проблема в сертификате. Попробуйте его пересоздать.
/opt/zimbra/bin/zmcertmgr deploycrt пересоздал сертификаты заново — и все заработало.
Спасибо за скрипт
Добрый день! Если я правильно понял, выше привеленные сценарии делают полный бекап всех/одного я щика соответственно. Не расматривали ли возможность инкрементного бекапа если полная копия уже существует? И еще один вопрос: сколько по времени занимает создание полной резервной копии, ну например 150 ящиков?
Добрый день ! Нет, инкрементный бекап не рассматривал, там в разы гемор добавляется и не факт что вообще получится скриптом делать его..
По затраты времени создания бекапа, тут все индивидуально, все зависит сколько весит каждый ящик, если все 150 ящиков весят в среднем по 10Мб, то бекап их будет очень быстрый.. соответственно если больше то и время будет увеличиваться.
>>если больше то и время будет увеличиваться.
Вот в том то и дело. Главным требованием руководства при создании сервера было сохранение всей почты за весь цикл жизни почтового домена, домен существует года с 10-11 точно ни знаю, сервер с 13, большая часть ящиков мигрировала от хостера. В итоге имеем порядка 20 ящиков объемом ~15-50 гб, всего порядка 150 ящиков в двух доменах на одном сервере. Теперь и не знаю что со всем этим делать.
Сейчас это все резервируется rsync-ом, но есть траблы с востановлением — занимает достаточно много времени.
Такие как у вас объемы ящиков, уверен никакой инструмент не будет сохранять быстро..
Спасибо, отличный скрипт. А стоит ли останавливать сервис зимбры перед бекапом ящиков? Что-бы ничего не изменилось в момент бекапа.
Пожалуйста ! Ну бекап обычно делается ночью, а ночью обычно не работают, хотя могут и работать 🙂 Ну при желании конечно можно и останавливать зимбру, тут дело дальше как кому удобней
>>а ночью обычно не работают,
Ну я бы так так не сказал, у нас например комерческие рассылки в ночь отрабатывают, в принципе как и многих.
У Вас реализованы готовые скрипты для бэкапирования отдельных почтовых ящиков zimba.
Большое Вам Спасибо! Очень помогло!
Всегда пожалуйста !
Спасибо за скрипт! А как бэкапите саму зимбру? Чтобы в случаее выхода сервера из строя можно было восстановить сервер
Добрый день ! Пользуйтесь на здоровье ! Саму зимбру никак не бекаплю, нет смысла, т.к. разворачивается она быстро, главное при переносе или пере установке это бекап ящиков, списков рассылки и само собой аккаунтов.
а списки рассылок и аккаунты ты тоже этим скриптом бэкапишь?