After banging my head on my desk for a couple of days trying to figure out how to get two OpenLDAP servers to mirror each other, I decided to create this post to detail how I got it working.
None of the tutorials I found had it quite right. Let’s get right into it.
First, I expect that you have two servers already up and running with ssh access.
I’m also expecting that you’re logged in as root. I’ll not be using a sudo prefix on these commands. You can gain a root prompt with sudo by running ‘sudo -s’:
user@host1$ sudo -s
[sudo] password for user:
root@host1#
Note: If at any time you want to completely start over, just run this command on both servers:
# apt remove --purge slapd -y; rm /var/lib/ldap/*
Step one: Configuring the host names
For this example, i’ll use hostX.location.example.com as the template for your FQDN’s. This will get translated automatically into the structure of your LDAP later on.
You have two servers: host1.location.example.com at 10.10.10.1 and host2.location.example.com at 10.10.10.2
Your /etc/hosts files should be edited to look like this:
#host1
127.0.0.1 localhost
10.10.10.1 host1.location.example.com host1
10.10.10.2 host2.location.example.com host2
#host2
127.0.0.1 localhost
10.10.10.2 host2.location.example.com host2
10.10.10.1 host1.location.example.com host1
Step Two: Install OpenLDAP
On both servers, run this to install OpenLDAP:
# apt install slapd ldap-utils
When asked for a password to use with the ldap admin account, use the same one on both servers. Write it down or copy/paste it from somewhere. You’ll need it later. This process will not take long. When it’s done, you’ll have two separate OpenLDAP installations. The installation will create an ldap tree that matches your domain configuration. In this case it will translate ‘location.example.com’ to ‘dc=location,dc=example,dc=com’ and the admin account will be ‘cn=admin,dc=location,dc=example,dc=com’.
You can confirm this by running ‘slapcat’ from the command line. This will dump the tree to the screen for you to look at:
root@host1# slapcat
dn: dc=location,dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: location.example.com
dc: location
structuralObjectClass: organization
creatorsName: cn=admin,dc=location,dc=example,dc=com
entryUUID: 4aad3c38-bae8-1036-8303-954f43b481de
createTimestamp: 20170421141226Z
entryCSN: 20170421141226.542122Z#000000#000#000000
modifiersName: cn=admin,dc=location,dc=example,dc=com
modifyTimestamp: 20170421141226Z
contextCSN: 20170421141335.948963Z#000000#001#000000
contextCSN: 20170421141314.583141Z#000000#002#000000
dn: cn=admin,dc=location,dc=example,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
structuralObjectClass: organizationalRole
creatorsName: cn=admin,dc=location,dc=example,dc=com
userPassword:: e10234hf0eyh230h23sdjksd03r2fhdfgasdldefg023=
entryUUID: 4aad4b92-bae8-1036-8304-953420fh1de
createTimestamp: 20170421141226Z
entryCSN: 20170421141226.542544Z#000000#000#000000
modifiersName: cn=admin,dc=location,dc=example,dc=com
modifyTimestamp: 20170421141226Z
You can change this layout, and a couple of other things, by running ‘dpkg-reconfigure slapd’, but that is beyond the scope of this howto.
Step three: Configure Mirroring
Now that both OpenLDAP servers are up and running, lets get the mirroring working. This is done it two parts.
Part A: Mirroring the configuration tree
Instead of editing the /etc/slapd.conf file like in the old days, new versions of OpenLDAP store their configuration in the LDAP directory itself. This means that once it’s set up, even configuration and schema changes will be mirrored. It’s a fantastic thing, but it’s a bit, well, weird to set up if you’re coming from the file editing days.
I’m not going to do much explanation of how this works. It’s boring and all you really want is to get this up and running so you have a redundant LDAP database, right?
Create a file called ‘syncconfig.ldif’ in roots home directory. It should look like this:
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: {1}syncprov.la
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: THE_PASSWORD_YOU_SAVED
dn: cn=config
changetype: modify
replace: olcServerID
olcServerID: 1 ldap://host1.location.example.com/
olcServerID: 2 ldap://host2.location.example.com/
dn: olcOverlay=syncprov,olcDatabase={0}config,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=001 provider=ldap://host1.location.example.com/ binddn="cn=config"
bindmethod=simple credentials=THE_PASSWORD_YOU_SAVED
searchbase="cn=config" type=refreshAndPersist
retry="5 5 300 5" timeout=1
olcSyncRepl: rid=002 provider=ldap://host2.location.example.com/ binddn="cn=config"
bindmethod=simple credentials=THE_PASSWORD_YOU_SAVED
searchbase="cn=config" type=refreshAndPersist
retry="5 5 300 5" timeout=1
-
add: olcMirrorMode
olcMirrorMode: TRUE
Now copy that to both servers, and on both servers run:
# ldapadd -Y EXTERNAL -H ldapi:/// -f syncconfig.ldif
WARNING! These ldif files should have NO TRAILING WHITESPACE after any line. If there is any trailing whitespace, the above command will fail with errors like:
ldapadd: wrong attributeType at line 5, entry "cn=module{0},cn=config"
You may want to restart your OpenLDAP daemons:
# /etc/init.d/slapd restart
They should come up without any errors.
Congrats! Now your configuration will automatically sync between your servers. Any config changes we make from one of the hosts will propagate to the other.
Part B: Mirroring the dc=location,dc=example,dc=com tree
Now that this is working, we setup the syncing of the ‘dc=location,dc=example,dc=com’ tree. To do this, we create another file called ‘synctree.ldif’. It should look like this:
dn: olcOverlay=syncprov,olcDatabase={1}mdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=001 provider=ldap://host1.location.example.com/ binddn="cn=admin,dc=location,dc=example,dc=com"
bindmethod=simple credentials=THE_PASSWORD_YOU_SAVED
searchbase="dc=location,dc=example,dc=com" type=refreshAndPersist
retry="5 5 300 5" timeout=1
olcSyncRepl: rid=001 provider=ldap://host2.location.example.com/ binddn="cn=admin,dc=location,dc=example,dc=com"
bindmethod=simple credentials=THE_PASSWORD_YOU_SAVED
searchbase="dc=location,dc=example,dc=com" type=refreshAndPersist
retry="5 5 300 5" timeout=1
-
add: olcMirrorMode
olcMirrorMode: TRUE
Since the config is synced, we only need to run this on one of the servers:
# ldapadd -Y EXTERNAL -H ldapi:/// -f synctree.ldif
You don’t need to restart the daemons after this, but why not…. and that’s it! Now the configuration AND the ‘dc=location,dc=example,dc=com’ trees are synced.