UMGUM.COM (лучше) 

Bacula + LDAP backup ( Резервное копирование настроек и данных LDAP-инстанса с помощью Bacula в среде OS Linux. )

3 декабря 2018

OS: "Linux Debian 6/7/8/9", "Linux Ubuntu 14/16/18 LTS".
Application: LDAP-server "389-DS v1.3", "Bacula v5.2/7.4/9.0".

Задача: наладить резервное копирование настроек и "баз данных" LDAP-инстансов полностью, с последующей выгрузкой в централизованное хранилище под управлением "Bacula".

Программное обеспечение SLDAP (Standalone LDAP), предназначающееся для обслуживания "баз данных" LDAP (Lightweight Directory Access Protocol), родилось почти одновременно с "интернетом" (в 1992-м году в Мичиганском университете выпускается пререлиз, работающий со спецификацией LDAP-протокола ещё не утверждённой в RFC) и похоже, что его инструментарий и методы инициализации не сильно с тех пор развились - оно было простым и осталось таковым настолько, что даже начинает выглядеть корявым на фоне современных подходов к реализации интерфейсов и средств управления.


Обзор резервируемых ресурсов.

Если говорить о LDAP-сервере "389-DS (Directory Server)" разработки "RedHat", то параметры первого этапа запуска инстансов (их может быть несколько) сосредоточены в файлах конфигурации, именованных по принципу "dirsrv-INSTANCE_NAME", по умолчанию располагающихся в немного неподходящей для этого директории "/etc/default". Там всего несколько переменных окружения, указывающих на месторасположение исполняемых и конфигурационных файлов запускаемого сервиса, таких как:

# cat /etc/default/dirsrv-ldap.example.net

....
SERVERBIN_DIR=/usr/sbin ; export SERVERBIN_DIR
CONFIG_DIR=/etc/dirsrv/slapd-ldap.example.net ; export CONFIG_DIR
....

Запускающийся сервис LDAP-сервера "389-DS" руководствуется обширным набором параметров из конфигурационных LDIF-файлов, загружаемых из соответствующей инстансу директории, задаваемой переменной окружения "CONFIG_DIR". Данные "каталогов" как таковых обычно размещаются в директории "/var/lib/dirsrv/slapd-INSTANCE_NAME/db" (определяется параметром "nsslapd-directory").

С учётом крайней простоты реализации методик обработки и хранения данных LDAP-сервером "389-DS" для полноценного резервного копирования достаточно выгрузки конфигурационных файлов из двух мест (оба в структуре директории "/etc") и набора файлов "базы данных" как таковых. Но, разумеется, простое копирование файлов несёт в себе риск получения консистентного набора данных в резервной копии - а потому для таких операций повсеместно применяются вспомогательные инструменты.

Общие рассуждения о неприменимости готовых решений.

Если копнуть глубже, то в дистрибутивном наборе LDAP "389-DS" обнаружатся два скрипта, предназначающихся специально для резервного копирования - один на Bash (/usr/sbin/db2bak), а второй на Perl (/usr/sbin/db2bak-online). Причём Bash-скрипт может выгружать резервную копию только с полным выключением LDAP-сервиса, а вот Perl-скрипт может это делать и "на лету".

Однако в использовании этих двух готовых решений есть ряд неудобств - как часто бывает в "этих ваших линуксах". Во первых, Bash-скрипт "db2bak" представляет собой лишь простейшую обёртку для единственной команды "ns-slapd db2archive", которую мы и там можем отдать самостоятельно, избегнув применения лишней прослойки. Во вторых, Perl-скрипт "db2bak-online" требует предоставления ему в открытом виде логина и пароля для подключения к LDAP-сервису с полным доступом к иерархии данных резервируемого "каталога", и не предоставляет чёткой обратной связи о процессе резервного копирования (!), сразу после отдачи команды сообщая о её успешном завершении, вне зависимости от реального состояния дел (!), совершая все дальнейшие процедуры в фоновом режиме и выводя текущие статусные сообщения в журнал ошибок (!) - иначе говоря, вообще невозможно без дополнительных проверок узнать, сделана ли утилитой "db2bak-online" резервная копия.

Итого: применение встроенных средств резервного копирования LDAP "389-DS" нецелесообразно и даже небезопасно.

Выше упомянутая комбинация команд "ns-slapd db2archive" делает резервную копию посредством простого копирования всех используемых LDAP-инстансом файлов "баз данных". Если LDAP-сервис эксплуатируется в режиме частой записи, такой подход может быть небезопасным, так как при копировании файлов не учитывается возможное изменение уже скопированных до него. Ранее для подстраховки я применял кратковременное отключение LDAP-сервера на момент копирования, но на практике это приводит к проблемам (например, в одной из конфигураций на старте сервис иногда "падал" из-за ошибки в системной библиотеке SSL-шифрования), в следствии чего я пришёл к тому, что до тех пор, пока объёмы "базы данных" исчисляются десятками и сотнями мегабайт, вполне допустимо делать полную выгрузку данных в формате LDIF, который удобен тем, что при необходимости для устранения проблем неконсистентности в нём легко разобраться самыми простейшими инструментами работы с текстовыми файлами.

Скрипт резервного копирования "баз данных" LDAP.

LDAP-инстанс может поддерживать работу нескольких "баз данных". Для минимизации возни с настройкой параметров сбора данных, был написан простейший bash-скрипт, собирающий в кучку архивов всё, что нужно для полноценной резервной копии сервиса:

# vi /usr/local/bin/389-backup.sh

#!/bin/bash

# Проверяем наличие обязательного входящего аргумента
[ ! "${1}" ] && { echo "Usage: ${0} /dir/to/backup" ; echo "The directory for backup is not specified. Operation aborted." ; exit 1; }

# Подготавливаем директорию для резервной копии
BDIR=${1}
mkdir -p "${BDIR}"
chown -R dirsrv:dirsrv "${BDIR}"

# Вычленяем и перебираем наименования всех настроенных LDAP-инстансов
for DIR in `find /etc/dirsrv/ -mindepth 1 -maxdepth 1 -type d -name 'slapd-*' | xargs -n 1 basename` ; do

  # Вычленяем имя LDAP-инстанса
  INST="$(echo ${DIR} | sed -e 's/slapd-//g')"

  # Вычленяем и перебираем все "базы данных" в LDAP-инстансе
  for NSDB in `find /var/lib/dirsrv/${DIR}/db/ -mindepth 1 -maxdepth 1 -type d | xargs -n 1 basename` ; do

    # Выгружаем данные в формате LDIF и сразу их сжимаем
    ns-slapd db2ldif -m -D /etc/dirsrv/${DIR} -n ${NSDB} -a "${BDIR}/${INST}-${NSDB}.ldif"
    gzip "${BDIR}/${INST}-${NSDB}.ldif"
  done
done

# Дополняем комплект резервной копии архивом конфигурационных файлов
tar -czf "${BDIR}/etc-dirsrv.tar.gz" /etc/dirsrv 2>/dev/null

exit ${?}

Просто для вырабатывания хорошей привычки закрываем скрипт от посторонних:

# chown root:root /usr/local/bin/389-backup.sh
# chmod ug+x /usr/local/bin/389-backup.sh
# chmod o-rwx /usr/local/bin/389-backup.sh

При запуске резервного копирования достаточно указать, в какое место файловой системы положить резервную копию:

# /usr/local/bin/389-backup.sh /var/backups/test-slapd

Настройка резервного копирования посредством "Bacula".

Дополним описание настроек "Bacula", касающиеся резервного копирования клиентского LDAP-сервиса:

# vi /etc/bacula/client.d/ldap.example.net.conf

....
File Set {
  Name = "file-set-ldap.example.net"
  ....

  # Директории конфигураций и резервных копий сервиса LDAP
  File = "/etc/default/"
  File = "/etc/dirsrv/"
  File = "/var/backups/bacula-slapd/"
  ....
}
....

Job {
  Name = "ldap.example.net"
  Type = Backup
  ....

  # Запуск выгрузки резервных копий БД всех LDAP-инстансов "389-DS":
  # (Debian: основной конфигурационный файл "/etc/default/dirsrv-ldap.example.net")
  Run Script {
    Runs When = Before
    Fail Job On Error = No
    Command = "rm -rf /var/backups/bacula-slapd"
    Command = "mkdir -p /var/backups/bacula-slapd"
    Command = "chown -R dirsrv:dirsrv /var/backups/bacula-slapd"
    Command = "chmod -R go-rwx /var/backups/bacula-slapd"
    Command = "/bin/bash -c '/usr/local/bin/389-backup.sh /var/backups/bacula-slapd 1>/var/log/bacula-slapd.log 2>&1'"
  }
  #
  Run Script {
    Runs When = After
    Runs On Failure = yes
    Command = "rm -rf /var/backups/bacula-slapd"
  }
  ....
}

Не забываем проверять корректность конфигурации в целом средствами самого Bacula:

# bacula-dir -c /etc/bacula/bacula-dir.conf -t

О процедуре восстановления из "бэкапа".

Выше для выгрузки данных из LDAP мы применили утилиту "db2ldif". Для загрузки данных, сохранённых в формате LDIF, обратно в LDAP, предназначена похожая утилита "ldif2db". Принцип восстановления тривиален, вычитывается из прилагаемой к утилите документации и рассматривать его здесь нет смысла.


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )