LDAP Backup and Restore

Mark Lin
LifeOps — One problem at a time.
4 min readAug 7, 2019
Photo by Finding Dan | Dan Grinwis on Unsplash

LDAP is first developed by University of Michigan in 1992 which is around the same time I got onto internet. There are multiple time our roads crossed path, LDAP and I, and each time I reluctantly learned just enough to get by. Things like “ou=users,dc=example,dc=com” looks non-sense compare to unix’s simple username and group. It uses file based database which I have no idea how to access. Its config can either be in file or in the database itself or in LDIF format. All just very confusing to mere mortal like me.

As years went by, LDAP never goes away and its use cases grew into networking, server, web and backend for federated login. But I never had to deal with it directly until now. Because now we work with many start-up clients, it’s inevitable that LDAP is needed somewhere. Typically, we would recommend service like Jumpcloud to provide not just LDAP, but also general login service for all purpose. As much as I dislike, we sometimes had to setup LDAP, which is why this article is for.

Setting up OpenLDAP isn’t hard, just apt-get/yum/apk/docker appropriate package/image name, and you get openLDAP in seconds. What’s hard is configuration for such beast. In this article, we document method to move client’s production LDAP data to locally ran dockerized OpenLDAP for development.

Understanding OpenLDAP

Configuration is usually in /etc/ldap or /etc/openldap. Inside the directory, there could be ldap.conf which is used by ldap client. There could be slapd.conf which would be used to configure OpenLDAP server. Configuration of server is also stored in config database which can be dumped out.

Back Up

To get a complete copy of OpenLDAP server, we need its configuration and data. slapcat is used to dump the database and require server to be stopped. For non-stopping backup, use ldapsearch.

slapcat -b cn=config > config.ldif

Will dump config database into config.ldif. For data, it was dumped with following command to dump all the data.

slapcat -l data.ldif

Restore

In config.ldif, which is used to push configuration into new OpenLDAP server, be careful with module path. Across different platform or installation method, module path could be in different place. From my dump, the location of module is loaded from /usr/lib64/openldap

dn: cn=module{0},cn=config
objectClass: olcModuleList
cn: module{0}
olcModulePath: /usr/lib64/openldap
olcModuleLoad: {0}ppolicy.la
olcModuleLoad: {1}pw-sha2.la

However, in the docker image we are using, olcModulePath shouldn’t be set, otherwise it won’t be able to find the modules. Also, sometimes some modules are compiled into the code in some distribution. When needed module is not loaded, one will see similar error such as following during import

root@be6d0e31569f:/data/backup# /sbin/setuser openldap slapadd -c -F /etc/ldap/slapd.d -n 0 -l ./config.ldif
5d435be4 lt_dlopenext failed: (ppolicy.la) file not found
slapadd: could not add entry dn=”cn=module{0},cn=config” (line=46):
Unrecognized database type (monitor)
5d435be4 olcDatabase: value #0: <olcDatabase> failed init (monitor)
slapadd: could not add entry dn=”olcDatabase={1}monitor,cn=config” (line=1814):
5d435be4 <= str2entry: str2ad(olcDbCheckpoint): attribute type undefined
slapadd: could not parse entry (line=1834)
5d435be4 <= str2entry: str2ad(olcPPolicyDefault): attribute type undefined
slapadd: could not parse entry (line=1876)
_#################### 100.00% eta none elapsed none fast!
Closing DB…

Which meant some modules such as ppolicy.la aren’t loaded so OpenLDAP couldn’t understand some of the settings from ldif file. In our case, we have to change the module lines to following

dn: cn=module{0},cn=config
objectClass: olcModuleList
cn: module{0}
olcModuleLoad: {0}ppolicy.la
olcModuleLoad: {1}pw-sha2.la
olcModuleLoad: {2}back_mdb.la
olcModuleLoad: {3}back_monitor.la

in order for new OpenLDAP server to have all the needed modules.

To restore the data, we use following docker compose file to run a ldap server and phpldapadmin.

version: ‘3’
services:
ldap:
image: osixia/openldap-backup:1.2.4
ports:
— 389:389
phpldapadmin:
image: osixia/phpldapadmin:0.8.0
ports:
— 8888:80
links:
— ldap
environment:
— PHPLDAPADMIN_HTTPS=false
— PHPLDAPADMIN_LDAP_HOSTS=ldap

then use following script to start the container and copy data files and bootstrap script into container and run it.

#!/usr/bin/env bashdocker-compose -f ldap.yml up — build -dsleep 5docker cp data/config.ldif ldap_ldap_1:/data/backup/
docker cp data/data.ldif ldap_ldap_1:/data/backup/
docker cp load-data.sh ldap_ldap_1:/data/backup/
docker exec ldap_ldap_1 /data/backup/load-data.sh

load-data.sh stops ldap service, wipe out all the existing config and data, and load the provided config and data.

#!/usr/bin/env bash# Procedure to update ldap-backup container config
sv stop /container/run/process/slapd
echo “Remove existing data”
rm -rf /etc/ldap/slapd.d/*
rm -rf /var/lib/ldap/*
echo “Add config”
/sbin/setuser openldap slapadd -c -F /etc/ldap/slapd.d -n 0 -l /data/backup/config.ldif
echo “Add data”
/sbin/setuser openldap slapadd -c -F /etc/ldap/slapd.d -n 1 -l /data/backup/data.ldif
sv start /container/run/process/slapd

And that’s it, now you have a OpenLDAP container with your data.

--

--