Configuring OpenLDAP replication with OLCSyncrepl
Having just one OpenLDAP server is asking for trouble. Running more than one with replication will save you hours of trouble if one of the servers dies for any reason. Here's a few tips to get replication working in Ubuntu 14.04 with OpenLDAP.
First, Get Your OpenLDAP Server Working
It's beyond the scope of this article, but step one: get your primary "Provider" OpenLDAP server working. Configure your management account permissions properly. Ensure that it works correctly. If you don't have your primary working then don't start on the replication.
Configure the Consumer Server
Install slapd on the consumer using something like:
sudo apt-get install slapd ldap-utils
Personally, I like to run a dpkg-reconfigure and give it the defaults of my baseDN and the like.
sudo dpkg-reconfigure slapd
Once the server is ready, add any special Schema that your particular environment uses. This should match any schema installed on the Provider server. Personally I use things like adding email addresses to user accounts, DNS schemas for PowerDNS to use LDAP as the backend, SAMBA, Puppet, and sudo schemas. For safe keeping, I retain one large LDIF file that contains all of these schemas so I can add them at any time. At the end of this LDIF I also have settings for the olcOverlay "memberOf" so that I can resolve group membership easier for a groupOfNames. It also specifies what indexes I want configured for the LDAP server using "add: olcDbIndex" chunks. If none of this makes any sense, you're probably not ready to start working on replication and need to go study some basic OpenLDAP configuration and how to use the olc configuration system.
So, my main ldif configuration I apply to all my servers is called "allinone.ldif". I run this on the Consumer:
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f allinone.ldif
Backup the Current LDAP Directory From the Provider Server
On the Provider server grab a dump with slapcat. We'll move this over to the consumer and restore it to get a good basepoint and not have to use sync to grab the current snapshot. If your server is mostly empty, you might be able to skip this step and let the online replication take care of it, but it never hurts to grab your main tree.
sudo slapcat > backup.ldif
Restore the Backup on the Consumer Server
Now, transfer that backup.ldif file to the consumer server. We'll stop the daemon and import this. After the import as root, it will screw up permissions in the /var/lib/ldap directory so we need to change those back. These steps happen on the new Consumer server:
sudo service slapd stop sudo slapadd -c -l backup.ldif sudo chown -R openldap:openldap /var/lib/ldap sudo service slapd start
Make a Replication User
On the main LDAP server you should have already created a replication user and given it appropriate permissions. It's been a while since I've done this so I won't try to give a step-by-step, but you need to set a few things for replication to work correctly. For instance you should set the following options:
# Make sure there's no limiting of the replicate user: olcLimits: dn.exact="cn=replicate,dc=mydomain,dc=com" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited # Give permissions to password fields, for instance and make sure replicate can write it. olcAccess: to attrs=userPassword,shadowLastChange,sambaNTPassword,sambaLMPassword,shadowMax,sambaPwdMustChange by dn="cn=replicate,dc=mydomain,dc=com" write by dn="uid=administrator,ou=people,dc=mydomain,dc=com" write by group/groupOfNames/member="cn=LDAP Admins,ou=groups,dc=mydomain,dc=com" write by anonymous auth by self write by * none
On the Provider server, you don't have to give the replicate user write permissions, but it must be able to read the passwords.
But the two main things to change on the Provider: Unlimited access limits, and ability to read all fields and nodes in LDAP. On the consumer, "replicate" should be able to write to all fields and nodes and again have no limits.
Start the Replication
On the Consumer create an LDIF file named sync.ldif similar to:
dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcSyncrepl olcSyncrepl: rid=123 provider="ldap://ldap.mydomain.com:389/" type=refreshAndPersist retry="60 30 300 +" searchbase="dc=mydomain,dc=com" bindmethod=simple binddn="cn=replicate,dc=mydomain,dc=com" credentials=***insert replication user password*** - add: olcUpdateRef olcUpdateRef: ldap://ldap.mydomain.com
This assumes your Provider LDAP serer is at "ldap.mydomain.com". If a client attempts to change an LDAP entry on the Consumer server, it will use the olcUpdateRef setting to refer the client to the Provider server to make the change there. Insert this into the client while slapd is running with:
ldapadd -Y EXTERNAL -H ldapi:/// -f sync.ldif
Testing Replication Status
You can verify that replication is working correctly by reading and comparing the contextCSN value from each server and ensure that they match:
sudo ldapsearch -z1 -LLLQY EXTERNAL -H ldapi:/// -s base -b dc=mydomain,dc=com contextCSN
Enabling TLS
Enabling TLS support is a must if you want to keep all your passwords secure. Once you have certificates generated (self-signed or not) create a tls.ldif similar to this:
dn: cn=config add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ldap/cacert.pem - add: olcTLSCertificateFile olcTLSCertificateFile: /etc/ldap/ldap2.crt - add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ldap/ldap2.key - add: olcTLSVerifyClient olcTLSVerifyClient: never
Then insert it with:
ldapmodify -c -Y EXTERNAL -H ldapi:/// -f './tls.ldif'
Caveat on Apparent Broken Replication
I've found that if my servers lose contact for a bit, when replication picks back up the root DN object type on the Consumer servers will be "glue" and the contextCSN check above will not return a value. It's an easy fix - simply by updating the root object in the Provider server by say, changing it's description field, will correct the object on the Consumers.