Secure LDAP Transport Layer With TLS

So we’ve got an OpenLDAP server (slapd) running and we’ve added some users.

Searching for or authenticating with or modifying passwords without TLS is unsafe. The following ldapsearch and wireshark capture shows the password in cleartext.

root@fangorn:~# ldapsearch -D uid=lobelia,ou=people,dc=telperion,dc=org -LLL -H ldap://barad-dur.telperion.org -w  ihatebilbo -b uid=lobelia,ou=people,dc=telperion,dc=org -x  userPassword
dn: uid=lobelia,ou=people,dc=telperion,dc=org
userPassword:: e1NTSEF9dmJ5N0Iwbk5IeEx1VXR0WjBXSWRUQVdrQWlXRlpsSzQ=
wireshark shows cleartext ldap traffic

If we want to use it to authenticate, we should secure the traffic. The easiest way to do that is with SSL.

Setting up a certificate hierarchy is not trivial but it is best to either generate a self signed certificate authority or get a certificate signed by a reputable CA (e.g. LetsEncrypt). Because this sample is on a closed personal network, I’ve chosen to generate a self-signed domain certificate authority and an intermediate. The CA signs the intermediate CA and the intermediate CA signs the cert for each of the nodes in the network.

the root is self signed but installed in a trusted location on each node

The default slapd package in debian stretch uses gnutls to perform it’s crypto operations by default so when pouring over the slapd manpages, keep that in mind (some options are meant for slapd built against Mozilla’s NSS and some are for OpenSSL). gnutls is pretty strict about self-signed CAs. If building the CA with OpenSSL, make sure you use the CA extensions. Also, if using Elliptic Curves, make sure you use named curves. I had trouble getting gnutls to parse OpenSSL generated certs that had curve parameters explicitly defined. Switching to using the named NIST curves solved the problem. Establishing an appropriate PKI can be done with the certtool command (from gnutls) or using OpenSSL’s command line suite. I’ve used OpenSSL to generate a CA PKI, loosely following this guide: OpenSSL Certificate Authority.

Configure the Keys and Certs

Now to configure slapd to use this cert. First copy your certs into an appropriate location. I copied my ca cert chain (a file consisting of the concatenation of the root CA and the intermediate CA) and the server cert into /etc/ssl/certs. I put the private key in /etc/ssl/private. Change the group ownership of the private key to ssl-cert to allow the openldap user (a member of the ssl-cert group) to use the key.

Configure the Server Keys (barad-dur)

Place keys in the appropriate locations and give them the appropriate permissions.

root@barad-dur:~# ls -ltr /etc/ssl/certs | tail -n2
-r--r--r-- 1 root root   1836 Feb  3 16:27 telperion.org.ca-chain.cert.pem
-r--r--r-- 1 root root   1208 Feb  3 16:27 barad-dur.telperion.org.cert.pem
root@barad-dur:~# ls -ltr /etc/ssl/private/ | tail -n1
-r--r----- 1 root ssl-cert  288 Feb  3 16:27 barad-dur.telperion.org.key.pem
root@barad-dur:~# groups openldap
openldap : openldap ssl-cert

Configure the Client Keys (fangorn)

Set up the keys:

root@fangorn:~# ls -ltr /etc/ssl/certs/ | grep telperion
-r--r--r-- 1 root root   1200 Feb  3 17:09 fangorn.telperion.org.cert.pem
-r--r--r-- 1 root root   1836 Feb  3 17:09 telperion.org.ca-chain.cert.pem
root@fangorn:~# ls -ltr /etc/ssl/private/ | grep telperion
-r--r----- 1 root ssl-cert  288 Feb  3 17:09 fangorn.telperion.org.key.pem

Configure LDAP to use TLS

Now that we have a PKI that makes sense, we can tell slapd and libldap to use the keys we’ve provided.
On the client, it is pretty easy. Configure the default ldap configuration file (/etc/ldap/ldap.conf) on the client machine (fangorn in this case) as follows:

# See ldap.conf(5) for details
# This file should be world readable but not world writeable.

BASE    dc=telperion,dc=org
URI     ldap://barad-dur.telperion.org
TLS_CACERT      /etc/ssl/certs/telperion.org.ca-chain.cert.pem
TLS_KEY         /etc/ssl/private/fangorn.telperion.org.key.pem
TLS_CERT        /etc/ssl/certs/fangorn.telperion.org.cert.pem

Configuring the server is a little more involved because slapd uses its own directory as configuration. This means we need to use the ldapmodify command to update the config database. Create an ldif file called update-certs.ldif with the following contents:

dn: cn=config
changetype: modify
replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/telperion.org.ca-chain.cert.pem
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/barad-dur.telperion.org.cert.pem
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/barad-dur.telperion.org.key.pem

Use ldapmodify to update the configuration:

root@barad-dur:~# ldapmodify -Y EXTERNAL -H ldapi:/// -f update-certs.ldif 
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"

Verify that our addition “took”:

root@barad-dur:~# ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config "(objectClass=olcGlobal)"
dn: cn=config
objectClass: olcGlobal
cn: config
olcArgsFile: /var/run/slapd/slapd.args
olcLogLevel: none
olcPidFile: /var/run/slapd/slapd.pid
olcToolThreads: 1
olcTLSCACertificateFile: /etc/ssl/certs/telperion.org.ca-chain.cert.pem
olcTLSCertificateFile: /etc/ssl/certs/barad-dur.telperion.org.cert.pem
olcTLSCertificateKeyFile: /etc/ssl/private/barad-dur.telperion.org.key.pem

Now we can use the “startTLS” version of ldapsearch to send ldap results over a secure channel.
Using the following command (-ZZ option forces TLS), we don’t see any cleartext passwords:

root@fangorn:~# ldapsearch -D uid=lobelia,ou=people,dc=telperion,dc=org -LLL -H ldap://barad-dur.telperion.org -w  ihatebilbo -b uid=lobelia,ou=people,dc=telperion,dc=org -x -ZZ  userPassword
dn: uid=lobelia,ou=people,dc=telperion,dc=org
userPassword:: e1NTSEF9dmJ5N0Iwbk5IeEx1VXR0WjBXSWRUQVdrQWlXRlpsSzQ=
wireshark shows encrypted cleartext ldap traffic

Leave a Reply

Your email address will not be published. Required fields are marked *