Configure OpenLDAP Multi-Master Replication on Linux
In this guide, we will configure Multi-master replication of OpenLDAP server on CentOS 7 / RHEL 7. This Multi-Master replication setup is to overcome the limitation of typical Master-Slave replication where only the master server does the changes in the LDAP directory.
READ: How to configure OpenLDAP Master-Slave Replication
In the Multi-Master replication, two or more servers act as master and all these are authoritative for any change in the LDAP directory. Queries from the clients are distributed across the multiple servers with the help of replication.

Environment
For Multi-Master replication, we are going to use three OpenLDAP servers. Details are below.
ldpsrv1.itzgeek.local (192.168.12.10) ldpsrv2.itzgeek.local (192.168.12.20) ldpsrv3.itzgeek.local (192.168.12.30)
Install LDAP
yum -y install openldap compat-openldap openldap-clients openldap-servers openldap-servers-sql openldap-devel
Start the LDAP service and enable it for the auto start at the system boot.
systemctl start slapd.service systemctl enable slapd.service
Configure LDAP Logging
Configure syslog to enable LDAP logging.
echo "local4.* /var/log/ldap.log" >> /etc/rsyslog.conf systemctl restart rsyslog
Configure OpenLDAP Multi-Master Replication
Copy the sample database configuration file to /var/lib/ldap directory and update the file permissions. You would need to perform below steps on all of your OpenLDAP servers unless otherwise stated.
cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG chown ldap:ldap /var/lib/ldap/*
We will enable the syncprov module.
vi syncprov_mod.ldif
Copy and paste the below lines to the above syncprov_mod.ldif file.
dn: cn=module,cn=config objectClass: olcModuleList cn: module olcModulePath: /usr/lib64/openldap olcModuleLoad: syncprov.la
Now send the configuration to the LDAP server.
ldapadd -Y EXTERNAL -H ldapi:/// -f syncprov_mod.ldif
Output:
SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 adding new entry "cn=module,cn=config"
Enable Config Replication
Change the olcServerID on all servers. For example, for ldpsrv1, set olcServerID to 1, for ldpsrv2, set olcServerID to 2 and for ldpsrv3, set to 3.
vi olcserverid.ldif
Copy and paste the below text into the above file.
dn: cn=config
changetype: modify
add: olcServerID
olcServerID: 1
Update the configuration on LDAP server.
ldapmodify -Y EXTERNAL -H ldapi:/// -f olcserverid.ldif
Output:
SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 modifying entry "cn=config"
We need to generate a password for LDAP configuration replication.
slappasswd
Output:
New password: Re-enter new password: {SSHA}MAfw/QNizKx4NxueW7CpCSN6jeDB5Z+C
You should generate a password on each server by running the slappasswd command.
Set a password for configuration database.
vi olcdatabase.ldif
Copy and paste the below text into the above file. You need to put the password you generated in the previous step on this file.
dn: olcDatabase={0}config,cn=config
add: olcRootPW
olcRootPW: {SSHA}MAfw/QNizKx4NxueW7CpCSN6jeDB5Z+C
Update the configuration on LDAP server.
ldapmodify -Y EXTERNAL -H ldapi:/// -f olcdatabase.ldif
Output:
SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 modifying entry "olcDatabase={0}config,cn=config"
Now we will set up the configuration replication on all servers.
vi configrep.ldif
Copy and paste the below text into the above file.
### Update Server ID with LDAP URL ### dn: cn=config changetype: modify replace: olcServerID olcServerID: 1 ldap://ldpsrv1.itzgeek.local olcServerID: 2 ldap://ldpsrv2.itzgeek.local olcServerID: 3 ldap://ldpsrv3.itzgeek.local ### Enable Config Replication### dn: olcOverlay=syncprov,olcDatabase={0}config,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: syncprov ### Adding config details for confDB replication ### dn: olcDatabase={0}config,cn=config changetype: modify add: olcSyncRepl olcSyncRepl: rid=001 provider=ldap://ldpsrv1.itzgeek.local binddn="cn=config" bindmethod=simple credentials=x searchbase="cn=config" type=refreshAndPersist retry="5 5 300 5" timeout=1 olcSyncRepl: rid=002 provider=ldap://ldpsrv2.itzgeek.local binddn="cn=config" bindmethod=simple credentials=x searchbase="cn=config" type=refreshAndPersist retry="5 5 300 5" timeout=1 olcSyncRepl: rid=003 provider=ldap://ldpsrv3.itzgeek.local binddn="cn=config" bindmethod=simple credentials=x searchbase="cn=config" type=refreshAndPersist retry="5 5 300 5" timeout=1 - add: olcMirrorMode olcMirrorMode: TRUE
Now send the configuration to the LDAP server.
ldapmodify -Y EXTERNAL -H ldapi:/// -f configrep.ldif
Output:
SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 modifying entry "cn=config" adding new entry "olcOverlay=syncprov,olcDatabase={0}config,cn=config" modifying entry "olcDatabase={0}config,cn=config"
Enable Database Replication
By this time, all your LDAP configurations are replicated. Now, we will enable the replication of actual data, i.e., user database. Perform below steps on any one of the nodes since the other nodes are in replication.
We would need to enable syncprov for hdb database.
vi syncprov.ldif
Copy and paste the below text into the above file.
dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: syncprov
Update the configuration on LDAP server.
ldapmodify -Y EXTERNAL -H ldapi:/// -f syncprov.ldif
Output:
SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 adding new entry "olcOverlay=syncprov,olcDatabase={2}hdb,cn=config"
Setup replication for hdb database.
vi olcdatabasehdb.ldif
Copy and paste the below content to the above file. You may get an error for olcSuffix,olcRootDN, and olcRootPW if you have these already on your configuration. Remove the entries, if not required.
dn: olcDatabase={2}hdb,cn=config changetype: modify replace: olcSuffix olcSuffix: dc=itzgeek,dc=local - replace: olcRootDN olcRootDN: cn=ldapadm,dc=itzgeek,dc=local - replace: olcRootPW olcRootPW: {SSHA}xtbbtC/1pJclCPzo1n3Szac9jqavSphk - add: olcSyncRepl olcSyncRepl: rid=004 provider=ldap://ldpsrv1.itzgeek.local binddn="cn=ldapadm,dc=itzgeek,dc=local" bindmethod=simple credentials=x searchbase="dc=itzgeek,dc=local" type=refreshOnly interval=00:00:00:10 retry="5 5 300 5" timeout=1 olcSyncRepl: rid=005 provider=ldap://ldpsrv2.itzgeek.local binddn="cn=ldapadm,dc=itzgeek,dc=local" bindmethod=simple credentials=x searchbase="dc=itzgeek,dc=local" type=refreshOnly interval=00:00:00:10 retry="5 5 300 5" timeout=1 olcSyncRepl: rid=006 provider=ldap://ldpsrv3.itzgeek.local binddn="cn=ldapadm,dc=itzgeek,dc=local" bindmethod=simple credentials=x searchbase="dc=itzgeek,dc=local" type=refreshOnly interval=00:00:00:10 retry="5 5 300 5" timeout=1 - add: olcDbIndex olcDbIndex: entryUUID eq - add: olcDbIndex olcDbIndex: entryCSN eq - add: olcMirrorMode olcMirrorMode: TRUE
Once you have updated the file, send the configuration to the LDAP server.
ldapmodify -Y EXTERNAL -H ldapi:/// -f olcdatabasehdb.ldif
Output:
SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 modifying entry "olcDatabase={2}hdb,cn=config"
Make changes to the olcDatabase={1}monitor.ldif file to restrict the monitor access only to LDAP root (ldapadm) user, not to others.
# vi monitor.ldif dn: olcDatabase={1}monitor,cn=config changetype: modify replace: olcAccess olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external, cn=auth" read by dn.base="cn=ldapadm,dc=itzgeek,dc=local" read by * none
Once you have updated the file, send the configuration to the LDAP server.
ldapmodify -Y EXTERNAL -H ldapi:/// -f monitor.ldif
Add the LDAP schemas.
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
Generate base.ldif file for your domain.
# vi base.ldiff dn: dc=itzgeek,dc=local dc: itzgeek objectClass: top objectClass: domain dn: cn=ldapadm ,dc=itzgeek,dc=local objectClass: organizationalRole cn: ldapadm description: LDAP Manager dn: ou=People,dc=itzgeek,dc=local objectClass: organizationalUnit ou: People dn: ou=Group,dc=itzgeek,dc=local objectClass: organizationalUnit ou: Group
Build the directory structure.
ldapadd -x -W -D "cn=ldapadm,dc=itzgeek,dc=local" -f base.ldif
Output:
Enter LDAP Password: adding new entry "dc=itzgeek,dc=local" adding new entry "cn=ldapadm ,dc=itzgeek,dc=local" adding new entry "ou=People,dc=itzgeek,dc=local" adding new entry "ou=Group,dc=itzgeek,dc=local"
Test the LDAP replication
Let’s create a user LDAP called “ldaptest“ in any one of your master servers, to do that, create a .ldif file on the ldpsrv1.itzgeek.local (in my case).
[[email protected] ~]# vi ldaptest.ldif
Update the above file with below content.
dn: uid=ldaptest,ou=People,dc=itzgeek,dc=local objectClass: top objectClass: account objectClass: posixAccount objectClass: shadowAccount cn: ldaptest uid: ldaptest uidNumber: 9988 gidNumber: 100 homeDirectory: /home/ldaptest loginShell: /bin/bash gecos: LDAP Replication Test User userPassword: {crypt}x shadowLastChange: 17058 shadowMin: 0 shadowMax: 99999 shadowWarning: 7
Add a user to LDAP server using the ldapadd command.
[[email protected] ~]# ldapadd -x -W -D "cn=ldapadm,dc=itzgeek,dc=local" -f ldaptest.ldif
Output:
Enter LDAP Password: adding new entry "uid=ldaptest,ou=People,dc=itzgeek,dc=local"
Search for “ldaptest” on another master server (ldpsrv2.itzgeek.local).
[r[email protected] ~]# ldapsearch -x cn=ldaptest -b dc=itzgeek,dc=local
Output:
# extended LDIF # # LDAPv3 # base <dc=itzgeek,dc=local> with scope subtree # filter: cn=ldaptest # requesting: ALL # # ldaptest, People, itzgeek.local dn: uid=ldaptest,ou=People,dc=itzgeek,dc=local objectClass: top objectClass: account objectClass: posixAccount objectClass: shadowAccount cn: ldaptest uid: ldaptest uidNumber: 9988 gidNumber: 100 homeDirectory: /home/ldaptest loginShell: /bin/bash gecos: LDAP Replication Test User userPassword:: e2NyeXB0fXg= shadowLastChange: 17058 shadowMin: 0 shadowMax: 99999 shadowWarning: 7 # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1
Now, set a password for the user created on ldpsrv1.itzgeek.local by going to ldpsrv2.itzgeek.local. If you can able to set the password, that means the replication is working as expected.
[[email protected] ~]# ldappasswd -s password123 -W -D "cn=ldapadm,dc=itzgeek,dc=local" -x "uid=ldaptest,ou=People,dc=itzgeek,dc=local"
Where,
-s specify the password for the username
-x username for which the password is changed
-D Distinguished name to authenticate to the LDAP server.
Extras
Configure LDAP client to bind to the new master server, too.
authconfig --enableldap --enableldapauth --ldapserver=ldpsrv1.itzgeek.local,ldpsrv2.itzgeek.local,ldpsrv3.itzgeek.local --ldapbasedn="dc=itzgeek,dc=local" --enablemkhomedir --update
That’s All.