Бэкап и восстановление OpenLDAP
OpenLDAP держит десятилетия корпоративной аутентификации: пользователей, группы, ACL, привязку к Samba или почте — и всё это в одной базе, которую многие бэкапят неправильно. Копируют файлы /var/lib/ldap «на живую» и получают битую mdb-базу, либо забывают про cn=config и после восстановления теряют все схемы и правила доступа. В этой статье — рабочая схема бэкапа и пошаговое восстановление, которое реально проверено на боевом сервере.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Почему OpenLDAP бэкапить сложнее, чем кажется
У OpenLDAP на современных дистрибутивах (Debian/Ubuntu с backend mdb, конфигурация через slapd.d) на самом деле не одна база, а минимум две логически разных сущности:
- Данные каталога — сами записи: пользователи, группы, организационные юниты. Это то, что лежит в
dc=example,dc=com(или как у вас называется суффикс). - Конфигурация сервера (
cn=config, она жеolcDatabase) — схемы (schema), индексы, ACL, список бэкендов, настройки TLS, оверлеи вродеmemberofилиppolicy. Начиная с версии 2.4 это тоже LDAP-дерево, а не текстовыйslapd.conf.
Если скопировать только каталог /var/lib/ldap, вы восстановите пользователей, но без правильной схемы и ACL сервер либо не запустится, либо откроет доступ не туда, куда нужно. Если скопировать только /etc/ldap/slapd.d, у вас будет конфигурация без единой записи пользователя.
Дальше — формат хранения. У mdb (memory-mapped database, стандарт с версии 2.4.23+) файлы data.mdb — это не текст, а B-дерево в бинарном виде, привязанное к странице памяти. Копировать его cp на работающем сервере — гарантированный риск получить несогласованный снапшот: LDAP в этот момент может писать транзакцию, а вы скопируете файл в промежуточном состоянии. Правильный путь — не трогать файлы БД напрямую, а выгружать содержимое через slapcat в LDIF (LDAP Data Interchange Format) — текстовый, переносимый и не зависящий от версии backend.
Что должно попасть в бэкап
Полный бэкап OpenLDAP — это три независимых артефакта:
| Что | Команда | Зачем |
|---|---|---|
| Данные каталога | slapcat -n 1 | Все записи: пользователи, группы, OU |
Конфигурация cn=config | slapcat -n 0 | Схемы, ACL, оверлеи, индексы, TLS-настройки |
| TLS-сертификаты и ключи | cp -a /etc/ldap/certs (путь зависит от дистрибутива) | Без них после восстановления ldaps:// не поднимется |
Индекс базы (n 0, n 1 и т.д.) можно уточнить командой:
slapcat -n 0 -F /etc/ldap/slapd.d -b "cn=config" | grep olcSuffix
ls -la /etc/ldap/slapd.d/cn=config/olcDatabase*
Обычно olcDatabase={0}config — это сама конфигурация, olcDatabase={-1}frontend — фронтенд без данных, а следующий по номеру ({1}mdb или {2}mdb) — ваш реальный backend с данными. Не полагайтесь на «у всех так же» — проверьте на своём сервере, номера смещаются, если раньше был подключен, например, модуль back_monitor.
Полезно дополнительно сохранить список загруженных модулей и оверлеев — при восстановлении на новый сервер их придётся ставить теми же пакетами:
slapcat -n 0 | grep -E "olcModuleLoad|olcOverlay"
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверАвтоматический бэкап через slapcat и cron
Ниже — скрипт, который выгружает данные и конфигурацию в LDIF, сжимает и хранит N последних копий локально (дальше их нужно выгружать за пределы сервера — об этом ниже).
#!/bin/bash
# /usr/local/bin/ldap-backup.sh
set -euo pipefail
BACKUP_DIR="/var/backups/openldap"
DATE=$(date +%F_%H%M)
KEEP_DAYS=14
mkdir -p "$BACKUP_DIR"
# Данные каталога
slapcat -n 1 -l "$BACKUP_DIR/data_$DATE.ldif"
# Конфигурация cn=config
slapcat -n 0 -l "$BACKUP_DIR/config_$DATE.ldif"
# Сертификаты (путь скорректируйте под свой дистрибутив)
tar -czf "$BACKUP_DIR/certs_$DATE.tar.gz" -C /etc/ldap certs 2>/dev/null || true
# Сжимаем LDIF
gzip "$BACKUP_DIR/data_$DATE.ldif"
gzip "$BACKUP_DIR/config_$DATE.ldif"
# Чистим бэкапы старше KEEP_DAYS
find "$BACKUP_DIR" -type f -mtime +"$KEEP_DAYS" -delete
echo "OpenLDAP backup done: $DATE"
chmod 700 /usr/local/bin/ldap-backup.sh
Cron — раз в сутки ночью, плюс можно добавить прогон перед любыми изменениями схемы вручную:
# crontab -e (root)
15 2 * * * /usr/local/bin/ldap-backup.sh >> /var/log/ldap-backup.log 2>&1
Важный нюанс: slapcat читает файлы БД напрямую, а не через сетевой протокол LDAP, поэтому он должен запускаться от пользователя, у которого есть доступ на чтение к /var/lib/ldap — обычно это root или openldap, и slapd в этот момент может продолжать работать (slapcat безопасен на «горячей» базе, в отличие от прямого копирования файлов). Если для вас критична секундная консистентность между несколькими скоординированными изменениями — можно на секунду поставить сервис на паузу через systemctl stop slapd, но в 99% случаев это не нужно.
Шифрование и хранение вне сервера
LDIF-дамп базы пользователей — это по сути слепок паролей (в виде хэшей {SSHA} или {ARGON2}), email, телефонов и структуры организации. Хранить его в открытом виде, тем более на том же сервере, что и сам LDAP, — плохая идея: один скомпрометированный сервер — и утекла вся база сотрудников.
Практическая схема:
- Шифруйте архив перед отправкой вовне — например, GPG с публичным ключом offline-хранилища:
gpg --encrypt --recipient backup@yourcompany.com \
--output data_$DATE.ldif.gz.gpg data_$DATE.ldif.gz
- Выгружайте на отдельный сервер или в объектное хранилище инструментом, который сам умеет шифрование и дедупликацию — restic или BorgBackup справляются с LDIF так же хорошо, как с любыми другими файлами. Если ещё не определились между ними, у нас есть отдельное сравнение — restic и BorgBackup: что выгоднее и когда.
- Держите бэкап-сервер физически (или хотя бы логически, в другом облаке/дата-центре) отдельно от продакшн-LDAP. Если у вас ещё не поднят отдельный узел под архивы — вариант выбора описан в статье VPS для бэкапов и архива: что выбрать и как настроить.
Не пренебрегайте и правами доступа на самом сервере: каталог /var/backups/openldap должен быть 700, владелец — root, никаких общих групп.
Пошаговое восстановление из бэкапа
Восстановление делается «в холодную» — с остановленным slapd, потому что и slapadd, и прямая пересборка индексов требуют эксклюзивного доступа к файлам БД.
1. Останавливаем slapd:
systemctl stop slapd
2. Разворачиваем конфигурацию. Если восстанавливаете на чистый сервер — сначала переустановите пакет slapd, затем очистите дефолтный slapd.d и загрузите свой:
rm -rf /etc/ldap/slapd.d/*
slapadd -n 0 -F /etc/ldap/slapd.d -l config_DATE.ldif
3. Разворачиваем данные каталога:
rm -rf /var/lib/ldap/*
slapadd -n 1 -F /etc/ldap/slapd.d -l data_DATE.ldif
Если slapadd ругается на дубликат entryUUID или entryCSN — это нормально, эти атрибуты уже есть в LDIF из прошлого дампа, флаг -w (warnings only, не прерывать при некритичных ошибках) обычно решает проблему:
slapadd -w -n 1 -F /etc/ldap/slapd.d -l data_DATE.ldif
4. Восстанавливаем права владения — самая частая причина, почему сервер после восстановления не стартует:
chown -R openldap:openldap /var/lib/ldap
chown -R openldap:openldap /etc/ldap/slapd.d
(имя пользователя/группы может быть ldap вместо openldap — смотрите, от какого юзера обычно работает slapd на вашем дистрибутиве: ps aux | grep slapd).
5. Восстанавливаем сертификаты, если разворачиваете на новый сервер:
tar -xzf certs_DATE.tar.gz -C /etc/ldap
chown -R openldap:openldap /etc/ldap/certs
6. Запускаем и проверяем:
systemctl start slapd
systemctl status slapd
ldapsearch -x -H ldap://localhost -b "dc=example,dc=com" "(objectClass=*)" dn
Если поиск возвращает записи и в журнале (journalctl -u slapd -n 50) нет ошибок про ACL или схему — восстановление прошло успешно.
Проверка восстановления и репликация как страховка
Бэкап, который никогда не разворачивали в тестовой среде, — это не бэкап, а надежда. Раз в квартал стоит поднимать отдельный тестовый сервер (можно временный, на минимальном тарифе) и полностью проходить процедуру восстановления по шагам выше — только так вы узнаете, что архив реально рабочий, а не битый файл трёхмесячной давности.
Второй уровень защиты — репликация syncrepl. Это не замена бэкапу (репликация мгновенно тиражирует и случайное удаление записи), но она снижает риск простоя: если основной сервер упал физически, вторичный уже поднят и содержит актуальные данные. Минимальная конфигурация consumer-узла в cn=config:
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcSyncrepl
olcSyncrepl: rid=001 provider=ldap://ldap-master.example.com
bindmethod=simple binddn="cn=replicator,dc=example,dc=com"
credentials=REPL_PASSWORD searchbase="dc=example,dc=com"
type=refreshAndPersist retry="60 10 300 +" interval=00:00:05:00
Для полноценной отказоустойчивости отдельный узел под реплику лучше держать не в той же локации, что мастер — сравнение площадок под такие задачи есть в статье лучший VPS для бэкапов в России и в её аналогах для США и Великобритании.
Если LDAP у вас — часть более широкой SSO-инфраструктуры (например, backend для Keycloak или FreeIPA), процедуру бэкапа стоит синхронизировать по времени с бэкапом самого SSO-слоя, чтобы при восстановлении оба каталога были согласованы по состоянию на один момент — подробнее об этом в статье бэкап и восстановление Keycloak.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли просто скопировать файлы /var/lib/ldap вместо slapcat?
На выключенном сервисе — можно, но это привязывает бэкап к конкретной версии backend (mdb) и не защищает от переноса на другую версию OpenLDAP. LDIF через slapcat переносим между версиями и дистрибутивами и остаётся читаемым текстом для аудита.
Нужно ли останавливать slapd для снятия бэкапа?
Нет, slapcat читает файлы БД напрямую и безопасен на работающем сервере — LMDB (backend mdb) поддерживает согласованное чтение без блокировки записи. Останавливать сервис нужно только при *восстановлении*.
Как часто бэкапить OpenLDAP?
Минимум раз в сутки для большинства организаций; если каталог активно меняется (много новых сотрудников, автоматическая синхронизация с HR-системой) — имеет смысл через inotifywait на файлы БД триггерить дополнительный внеплановый дамп при явных изменениях, либо просто увеличить частоту cron.
Что делать, если после slapadd сервер не стартует с ошибкой прав доступа?
В 90% случаев это chown — процесс slapd работает от отдельного системного пользователя (openldap или ldap в зависимости от дистрибутива), а после slapadd от root файлы принадлежат root. Проверьте владельца командой ls -la /var/lib/ldap и сравните с тем, от чьего имени запущен slapd.
Безопасно ли хранить LDIF-дамп без шифрования, если сервер и так за файрволом?
Нет. LDIF содержит хэши паролей и полную оргструктуру — при утечке (компрометация бэкап-сервера, ошибка в правах S3-бакета) это готовая база для брутфорса и социальной инженерии. Шифрование архива — не опция, а обязательный шаг.
Как проверить, что бэкап конфигурации cn=config действительно рабочий, не разворачивая его?
Прогоните LDIF через slapschema или хотя бы визуально сверьте, что в дампе присутствуют ваши кастомные olcAccess и olcOverlay — если их нет, дамп снят не из той базы (перепутан номер -n).
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →