LDAP and Transport Layer Security (TLS)¶
When authenticating to an OpenLDAP server it is best to do so using an encrypted session. This can be accomplished using Transport Layer Security (TLS).
Here, we will be our own Certificate Authority (CA) and then create and sign our LDAP server certificate as that CA. This guide will use the certtool
utility to complete these tasks. For simplicity, this is being done on the OpenLDAP server itself, but your real internal CA should be elsewhere.
Install the gnutls-bin
and ssl-cert
packages:
sudo apt install gnutls-bin ssl-cert
Create a private key for the Certificate Authority:
sudo certtool --generate-privkey --bits 4096 --outfile /etc/ssl/private/mycakey.pem
Create the template/file /etc/ssl/ca.info
to define the CA:
cn = Example Company
ca
cert_signing_key
expiration_days = 3650
Create the self-signed CA certificate:
sudo certtool --generate-self-signed \
--load-privkey /etc/ssl/private/mycakey.pem \
--template /etc/ssl/ca.info \
--outfile /usr/local/share/ca-certificates/mycacert.crt
Note: Yes, the
--outfile
path is correct. We are writing the CA certificate to/usr/local/share/ca-certificates
. This is whereupdate-ca-certificates
will pick up trusted local CAs from. To pick up CAs from/usr/share/ca-certificates
, a call todpkg-reconfigure ca-certificates
is necessary.
Run update-ca-certificates
to add the new CA certificate to the list of trusted CAs. Note the one added CA:
$ sudo update-ca-certificates
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
This also creates a /etc/ssl/certs/mycacert.pem
symlink pointing to the real file in /usr/local/share/ca-certificates
.
Make a private key for the server:
sudo certtool --generate-privkey \
--bits 2048 \
--outfile /etc/ldap/ldap01_slapd_key.pem
Note: Replace
ldap01
in the filename with your server’s hostname. Naming the certificate and key for the host and service that will be using them will help keep things clear.
Create the /etc/ssl/ldap01.info
info file containing:
organization = Example Company
cn = ldap01.example.com
tls_www_server
encryption_key
signing_key
expiration_days = 365
The above certificate is good for 1 year, and it’s valid only for the ldap01.example.com
hostname. You can adjust this according to your needs.
Create the server’s certificate:
sudo certtool --generate-certificate \
--load-privkey /etc/ldap/ldap01_slapd_key.pem \
--load-ca-certificate /etc/ssl/certs/mycacert.pem \
--load-ca-privkey /etc/ssl/private/mycakey.pem \
--template /etc/ssl/ldap01.info \
--outfile /etc/ldap/ldap01_slapd_cert.pem
Adjust permissions and ownership:
sudo chgrp openldap /etc/ldap/ldap01_slapd_key.pem
sudo chmod 0640 /etc/ldap/ldap01_slapd_key.pem
Your server is now ready to accept the new TLS configuration.
Create the file certinfo.ldif
with the following contents (adjust paths and filenames accordingly):
dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/mycacert.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/ldap01_slapd_cert.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/ldap01_slapd_key.pem
Use the ldapmodify
command to tell slapd
about our TLS work via the slapd-config
database:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f certinfo.ldif
If you need access to LDAPS (LDAP over SSL), then you need to edit /etc/default/slapd
and include ldaps:///
in SLAPD_SERVICES
like below:
SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"
And restart slapd
with:
sudo systemctl restart slapd
Note that StartTLS will be available without the change above, and does NOT need a slapd
restart.
Test StartTLS:
$ ldapwhoami -x -ZZ -H ldap://ldap01.example.com
anonymous
Test LDAPS:
$ ldapwhoami -x -H ldaps://ldap01.example.com
anonymous
Certificate for an OpenLDAP replica
To generate a certificate pair for an OpenLDAP replica (consumer), create a holding directory (which will be used for the eventual transfer) and run the following:
mkdir ldap02-ssl
cd ldap02-ssl
certtool --generate-privkey \
--bits 2048 \
--outfile ldap02_slapd_key.pem
Create an info file, ldap02.info
, for the Consumer server, adjusting its values according to your requirements:
organization = Example Company
cn = ldap02.example.com
tls_www_server
encryption_key
signing_key
expiration_days = 365
Create the Consumer’s certificate:
sudo certtool --generate-certificate \
--load-privkey ldap02_slapd_key.pem \
--load-ca-certificate /etc/ssl/certs/mycacert.pem \
--load-ca-privkey /etc/ssl/private/mycakey.pem \
--template ldap02.info \
--outfile ldap02_slapd_cert.pem
Note: We had to use
sudo
to get access to the CA’s private key. This means the generated certificate file is owned by root. You should change that ownership back to your regular user before copying these files over to the Consumer.
Get a copy of the CA certificate:
cp /etc/ssl/certs/mycacert.pem .
We’re done. Now transfer the ldap02-ssl
directory to the Consumer. Here we use scp
(adjust accordingly):
cd ..
scp -r ldap02-ssl user@consumer:
On the Consumer side, install the certificate files you just transferred:
sudo cp ldap02_slapd_cert.pem ldap02_slapd_key.pem /etc/ldap
sudo chgrp openldap /etc/ldap/ldap02_slapd_key.pem
sudo chmod 0640 /etc/ldap/ldap02_slapd_key.pem
sudo cp mycacert.pem /usr/local/share/ca-certificates/mycacert.crt
sudo update-ca-certificates
Create the file certinfo.ldif
with the following contents (adjust accordingly regarding paths and filenames, if needed):
dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/mycacert.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/ldap02_slapd_cert.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/ldap02_slapd_key.pem
Configure the slapd-config
database:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f certinfo.ldif
Like before, if you want to enable LDAPS, edit /etc/default/slapd
and add ldaps:///
to SLAPD_SERVICES
, and then restart slapd
.
Test StartTLS:
$ ldapwhoami -x -ZZ -H ldap://ldap02.example.com
anonymous
Test LDAPS:
$ ldapwhoami -x -H ldaps://ldap02.example.com
anonymous