Configuring OpenLDAP replication with OLCSyncrepl

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.

Posted by Tony on Feb 22, 2016 | Servers, OpenLDAP, linux