Резервное копирование и восстановление почтовых ящиков в 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 секунд

Вот такими способами можно легко делать резервные копии почтовых ящиков и с той же легкостью восстанавливать их из резервной копии.

 

Понравилась или оказалась полезной статья, поблагодари автора

 

 

ПОНРАВИЛАСЬ ИЛИ ОКАЗАЛАСЬ ПОЛЕЗНОЙ СТАТЬЯ, ПОБЛАГОДАРИ АВТОРА

БесполезноСлабоватоПриемлемоОтличноПревосходно (5 голос(ов), в среднем: 5,00 из 5)
Загрузка...

Всего комментариев: 28 Комментировать

  1. Сергей /

    У Вас реализованы готовые скрипты для бэкапирования отдельных почтовых ящиков zimba.
    Большое Вам Спасибо! Очень помогло!

    1. Жаконда / Автор записи

      Всегда пожалуйста !

      1. Василий /

        Спасибо за скрипт! А как бэкапите саму зимбру? Чтобы в случаее выхода сервера из строя можно было восстановить сервер

        1. Жаконда / Автор записи

          Добрый день ! Пользуйтесь на здоровье ! Саму зимбру никак не бекаплю, нет смысла, т.к. разворачивается она быстро, главное при переносе или пере установке это бекап ящиков, списков рассылки и само собой аккаунтов.

          1. Mr.Light /

            а списки рассылок и аккаунты ты тоже этим скриптом бэкапишь?

  2. Костя /

    Спасибо, отличный скрипт. А стоит ли останавливать сервис зимбры перед бекапом ящиков? Что-бы ничего не изменилось в момент бекапа.

    1. Жаконда / Автор записи

      Пожалуйста ! Ну бекап обычно делается ночью, а ночью обычно не работают, хотя могут и работать 🙂 Ну при желании конечно можно и останавливать зимбру, тут дело дальше как кому удобней

      1. Алексей /

        >>а ночью обычно не работают,
        Ну я бы так так не сказал, у нас например комерческие рассылки в ночь отрабатывают, в принципе как и многих.

  3. Алексей /

    Добрый день! Если я правильно понял, выше привеленные сценарии делают полный бекап всех/одного я щика соответственно. Не расматривали ли возможность инкрементного бекапа если полная копия уже существует? И еще один вопрос: сколько по времени занимает создание полной резервной копии, ну например 150 ящиков?

    1. Жаконда / Автор записи

      Добрый день ! Нет, инкрементный бекап не рассматривал, там в разы гемор добавляется и не факт что вообще получится скриптом делать его..

      По затраты времени создания бекапа, тут все индивидуально, все зависит сколько весит каждый ящик, если все 150 ящиков весят в среднем по 10Мб, то бекап их будет очень быстрый.. соответственно если больше то и время будет увеличиваться.

      1. Алексей /

        >>если больше то и время будет увеличиваться.
        Вот в том то и дело. Главным требованием руководства при создании сервера было сохранение всей почты за весь цикл жизни почтового домена, домен существует года с 10-11 точно ни знаю, сервер с 13, большая часть ящиков мигрировала от хостера. В итоге имеем порядка 20 ящиков объемом ~15-50 гб, всего порядка 150 ящиков в двух доменах на одном сервере. Теперь и не знаю что со всем этим делать.

        1. Алексей /

          Сейчас это все резервируется rsync-ом, но есть траблы с востановлением — занимает достаточно много времени.

          1. Жаконда / Автор записи

            Такие как у вас объемы ящиков, уверен никакой инструмент не будет сохранять быстро..

  4. Pavel /

    После обновления с 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)

    Что может быть, не подскажите?

    1. Жаконда / Автор записи

      Судя по ошибке проблема в сертификате. Попробуйте его пересоздать.

      1. Pavel /

        /opt/zimbra/bin/zmcertmgr deploycrt пересоздал сертификаты заново — и все заработало.
        Спасибо за скрипт

  5. Жаконда / Автор записи

    Ув. roman@kovenya.ru, я не могу разместить ваши посты. Рад что вы модернизировали скрипт под свои нужны, но данный блог про мои труды.

    1. orangefruit /

      Печаль. Надо пилить свой блог =) Тем не менее присмотритесь к моим решениям, возможно найдёте для себя что-то интересное.

      1. Жаконда / Автор записи

        Спасибо, мой вариант скрипта писался строго под мои нужны и он меня более чем устраивает на данный момент 😉 У меня нет сложностей расширить его в случае надобности.

  6. gr /

    А есть вариант восстановления списка ящиков?

    1. Жаконда / Автор записи

      Есть конечно, в статье он описан

  7. gr /

    не совсем правильно выразился наверное, восстановление архивов почты по списку ящиков. не одного почтового ящика, а нескольких ..

    1. Жаконда / Автор записи

      Такого скприта я не писал, т.к. не видел в нем надобности для себя. Но все возможно, восстанавливать к примеру из списка..

  8. Евгений /

    У вас был опыт восстановления из бекапа почтового ящика более 1 гигабайта?
    Столкнулся с проблемой что зимбра рабивает инбокс на несколько инбоксов с индексом и пользователь ругается, что все разбилось по папкам.

  9. Egor /

    В скрипте восстановления есть 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)

    Автору спасибо большое за скрипты

    1. Жаконда / Автор записи

      Спасибо! Исправления внес!

    2. nt /

      здесь тоже ошибка.
      «//?fmt=tgz&resolve=replace»

      вот так будет правильней:
      «//?fmt=tgz&resolve=replace»

      😉

  10. Александр /

    При восстановление выдает такую ошибку:
    ERROR: zclient.IO_ERROR (Read timed out) (cause: java.net.SocketTimeoutException Read timed out)
    В чем может быть причина?

Оставить ответ

18 − 11 =

© IT-блог Жаконды All Rights Reserved.
Яндекс.Метрика