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 where update-ca-certificates will pick up trusted local CAs from. To pick up CAs from /usr/share/ca-certificates, a call to dpkg-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
2 Likes

Does anyone can explain, why the output file of generated certificates was named with .pem extension two times in this post (see the part “Create the server’s certificate” of ldap-server 1 and 2)?

Is it a mistake or is there a special reason for?

In my mind it should be the following:
–outfile /etc/ldap/ldap01_slapd_cert**.crt**

and not:
–outfile /etc/ldap/ldap01_slapd_cert**.pem**

And also the .ldif file should content then:
olcTLSCertificateFile: /etc/ldap/ldap01_slapd_cert**.crt**

and not:
olcTLSCertificateFile: /etc/ldap/ldap01_slapd_cert**.pem**

Does someone could verify this an tell me wether it’s wrong or not and if not, what’s the cause of this differentiated file extension?

Thanks

1 Like

Is it a mistake or is there a special reason for?

You’re working with encodings; two in specific PEM & DER.

DER is a binary format, unpleasant to read or transmit over a network we instead represent it with a PEM encoding.

You can freely move between these two encodings; for example using openssl.

$ openssl x509 -outform der \ 
         -in cert.pem \
         -out cert.crt 

and back again

$ openssl x509 -outform pem \ 
         -in cert.crt  \
         -out cert.pem
1 Like

I execute

sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f certinfo.ldif

always got the following error message

     ldap_modify: Other (e.g., implementation specific) error (80)

I had try to change the order of

add: olcTLSCertificateKeyFile

and

add: olcTLSCertificateFile

but still failed.

I was succeeded about one year ago.
Any idea?

I am using Ubuntu 20.04 and OpenLDAP: slapd (Ubuntu) (Apr 8 2021 04:22:01)

Ok, I solve the problem
The reason why I got the error is: the private key file own by root and had 600 mode.
Because I generate the private key file with root user.
After I change the user:group of the key and cert file to openldap, the following command succeeded!

sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f certinfo.ldif

I found this situation by turn on the openldap log using the following ldif

dn: cn=config
changeType: modify
replace: olcLogLevel
olcLogLevel: stats

and find

RESULT tag=103 err=80 text=

and here said: system does not allow slap to read the server certificate and private key
https://serverfault.com/questions/919133/ldap-tsl-ldap-modify-error-80

The only extension that really matters for these examples is the “.crt” one for the CA file that gets installed in /usr/local/share/ca-certificates, because the update-ca-certificates script looks specifically for this name:

# Now process certificate authorities installed by the local system
# administrator.
if [ -d "$LOCALCERTSDIR" ]
then
  find -L "$LOCALCERTSDIR" -type f -name '*.crt' | sort | while read crt
  do
    add "$crt"
1 Like

Hi!!

I have one question.
I have tried to create one CA server out of my LDAP server, but It doesn’t work.

I have probed to create all certificates and to send to LDAP server but it doesn’t work.

How I can to configurated both servers?

Help me please!!

Maybe post your question with more details on the ubuntu-server mailing list, or open a new topic here on discourse at https://discourse.ubuntu.com/c/server/17.

Include the commands you ran, config files you used, and the errors that happened.

1 Like

Hello, guys.

I think it is better to write the necessity of reboot of slapd before testing “Tets StartTLS”, because novices may get in trouble.

A slapd restart is only needed if you want to use ldaps:// and that wasn’t enabled in /etc/default/slapd already.

1 Like

Thank you for your reply.

I pointed out wrong position in documents.

I supposed there was only one location about TLS connection, but there are two in the following sections:

  • LDAP & TLS
  • Certificate for an OpenLDAP replica

in ``Certificate for an OpenLDAP replica’’, there is a description about slapd reboot.

``
Like before, if you want to enable LDAPS, edit /etc/default/slapd and add ldaps:/// to SLAPD_SERVICES, and then restart slapd.
‘’

BUT, there is no one in ``LDAP&TLS’’ section. So it is better to write those for novices.

Best

1 Like

Updated, thanks for noticing that.

1 Like