Setting up your SSL certificates on OpenLDAP by using a Mozilla NSS database

I’ve recently spent some time setting up TLS/SSL encryption (SSSD won’t send a password in clear text when an user will try to authenticate against your LDAP server) on an OpenLDAP istance and as you may know the only way for doing that on a RHEL / CentOS environment is dealing with a Mozilla NSS database (which is, in fact, a SQLite database). I’ve been reading all the man pages of the relevant tools available to manipulate Mozilla NSS databases and I thought I would have shared the whole procedure and commands I used to achieve my goal. Even if you aren’t running an RPM based system you can opt to use a Mozilla NSS database to store your certificates as your preferred setup.

On the LDAP (SLAPD) server

Re-create *.db files

mkdir /etc/openldap/certs
modutil -create -dbdir /etc/openldap/certs

Setup a CA Certificate

certutil -d /etc/openldap/certs -A -n "My CA Certificate" -t TCu,Cu,Tuw -a -i /etc/openldap/cacerts/ca.pem

where ca.pem should be your CA’s certificate file.

Remove the password from the Database

modutil -dbdir /etc/openldap/certs -changepw 'NSS Certificate DB'

Creates the .p12 file and imports it on the Database

openssl pkcs12 -inkey domain.org.key -in domain.org.crt -export -out domain.org.p12 -nodes -name 'LDAP-Certificate'

pk12util -i domain.org.p12 -d /etc/openldap/certs

where domain.org.key and domain.org.crt are the names of the certificates you previously created at your CA’s website.

List all the certificates on the database and make sure all the informations are correct

certutil -d /etc/openldap/certs -L

Configure /etc/openldap/slapd.conf and make sure the TLSCACertificatePath points to your Mozilla NSS database

TLSCACertificateFile /etc/openldap/cacerts/ca.pem
TLSCACertificatePath /etc/openldap/certs/
TLSCertificateFile LDAP-Certificate

Additional commands

Modify the trust flags if necessary

certutil -d /etc/openldap/certs -M -n "My CA Certificate" -t "TCu,Cu,Tuw"

Delete a certificate from the database

certutil -d /etc/openldap/certs -D -n "My LDAP Certificate"

On the clients (nslcd uses ldap.conf while sssd uses /etc/sssd/sssd.conf)

On /etc/openldap/ldap.conf

BASE dc=domain,dc=org
URI ldaps://ldap.domain.org

TLS_REQCERT demand
TLS_CACERT /etc/openldap/cacerts/ca.pem

On /etc/sssd/sssd.conf

ldap_tls_cacert = /etc/openldap/cacerts/ca.pem
ldap_tls_reqcert = demand
ldap_uri = ldaps://ldap.domain.org

How to test the whole setup

ldapsearch -x -b 'dc=domain,dc=org' -D "cn=Manager,dc=domain,dc=org" '(objectclass=*)' -H ldaps://ldap.domain.org -W -v

Troubleshooting

If anything goes wrong you can run SLAPD with the following args for its debug mode:

/usr/sbin/slapd -d 256 -f /etc/openldap/slapd.conf -h "ldaps:/// ldap:///"

Possible errors: 

If you happen to see an error similar to this one: “TLS error -8049:Unrecognized Object Identifier.“, try running ldapsearch with its debug mode this way:

ldapsearch -d 1 -x -ZZ -H ldap://ldap.domain.org

Make also sure that the FQDN you are trying to connect to is listed on the trusted FQDN’s list of your domain.org.crt.

Update: as SSSD’s developer Stephen Gallagher correctly pointed out on the comments using ldap_tls_reqcert = allow isn’t a best practice since it may take in Man in the Midle Attacks, adjusting the how to to match his suggestions.