Резервное копирование и восстановление почтовых ящиков в 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.
Большое Вам Спасибо! Очень помогло!
Всегда пожалуйста !
Спасибо за скрипт! А как бэкапите саму зимбру? Чтобы в случаее выхода сервера из строя можно было восстановить сервер
Добрый день ! Пользуйтесь на здоровье ! Саму зимбру никак не бекаплю, нет смысла, т.к. разворачивается она быстро, главное при переносе или пере установке это бекап ящиков, списков рассылки и само собой аккаунтов.
а списки рассылок и аккаунты ты тоже этим скриптом бэкапишь?