Step-by-Step Tutorial: Configure OpenLDAP with TLS certificates CentOS 7 Linux

This is a multi-part article where I will cover different areas of configuration of OpenLDAP server in CentOS 7 Linux node. You can use below links to refer different parts of this tutorial

Basics LDAP Tutorial for Beginners – Understanding Terminologies & Usage
Step-by-Step Tutorial: Install and Configure OpenLDAP
Step-by-Step Tutorial: Configure OpenLDAP with TLS certificates
Step-by-Step Tutorial: Configure LDAP client to authenticate with LDAP server

 

Step-by-Step Tutorial: Configure OpenLDAP with TLS certificates CentOS 7 Linux

 

Configure OpenLDAP with TLS certificates

Before starting with this article to configure OpenLDAP with TLS certificates on Linux you must be aware of basic LDAP terminologies. For the demonstration of this article I am using CentOS 7. In this article I will share detailed steps to secure LDAP connections with TLS. By default, when using LDAP connections, all information is sent in plain text. There’s no need to insist again on the importance of ciphering all traffic transmitted between the client and the server.

We begin by creating a certificate. We have already seen this many times, but this time, we’re going to take a different approach. So far, we have created self-signed certificates in order to provide secure connections to known services. This is more than enough to secure the traffic in a local network.  A stricter use of certificates would require the use of a certificate signed by a certification authority, or CA. This is what Internet sites usually do. They request a signed certificate to a well-known CA.

In our case, however, we’ll create our own CA and sign our certificate to use it with LDAP.

 

If you are not familiar with openssl and creating certificates, I would strongly recommend you to go through these articles before you configure TLS for your LDAP.

 

Install pre-requisite rpms

To configure OpenLDAP with TLS certificates we need openssl package. This will give us a directory hierarchy for creating the certificates to configure OpenLDAP with TLS certificates

[root@ldap-server ~]# yum -y install openssl

 

Create private key for CA certificate

First we need a private key to generate our own CA certificate. If you do not wish to have an encrypted private key then you can ignore -des3 in the below command:

[root@ldap-server ~]# openssl genrsa -des3 -out ca.key 4096
Generating RSA private key, 4096 bit long modulus
..........................................++
...........................................................................................................................++
e is 65537 (0x10001)
Enter pass phrase for ca.key:
Verifying - Enter pass phrase for ca.key:

 

Generate CA Certificate

Next we will use our CA key to generate CA certificate. We will use this CA ceriticate later to sign the ldap client certificates

[root@ldap-server ~]# openssl req -new -x509 -days 365 -key ca.key -out ca.cert.pem
Enter pass phrase for ca.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:IN
State or Province Name (full name) []:Karnataka
Locality Name (eg, city) [Default City]:Bengaluru
Organization Name (eg, company) [Default Company Ltd]:GoLinuxCloud
Organizational Unit Name (eg, section) []:R&D
Common Name (eg, your name or your server's hostname) []:ldap-server.example.com
Email Address []:admin@golinuxcloud.com
IMPORTANT NOTE:

It is important that you provide a proper CN or else you will face problems with TLS handshake later as I have demonstrated in earlier articles. Here I am using the CN of my ldap-server.

 

Configure openssl x509 extension to create SAN certificate

We will create SAN certificate to avoid creating multiple certificates for each of our ldap client. You can learn more about SAN certificates at Create san certificate

[root@ldap-server ~]# cat server_cert_ext.cnf
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
IP.1 = 192.168.43.32
IP.2 = 192.168.43.31
IP.3 = 192.168.43.154
DNS.1 = client.example.com
DNS.2 = server2.example.com

Under [alt_names], I will provide the complete list of IP Address and DNS name which the ldap client certificate should resolve when validating a client request.

 

Generate LDAP client key

Next we will need a ldap client key which we will name as "ldap.example.com.key"

[root@ldap-server ~]# openssl genrsa -out ldap.example.com.key 4096
Generating RSA private key, 4096 bit long modulus
.............................................................++
...............................................................................................................................................................................++
e is 65537 (0x10001)

 

Create Certificate Signing request (CSR)

Next we need a CSR to sign our ldap client certificate. Here we will use our server configuration file to provide the list of IP and DNS. These values will be used as CN so all the clients with these IP or DNS will be allowed to establish TLS communication with the LDAP server

[root@ldap-server ~]# openssl req -new -key ldap.example.com.key -out ldap.example.com.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:IN
State or Province Name (full name) []:Karnataka
Locality Name (eg, city) [Default City]:Bengaluru
Organization Name (eg, company) [Default Company Ltd]:GoLinuxCloud
Organizational Unit Name (eg, section) []:R&D
Common Name (eg, your name or your server's hostname) []:ldap-server.example.com
Email Address []:admin@golinuxcloud.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

 

Create LDAP client certificate

Next we will create our ldap client certificate (ldap.example.com.crt) using the CSR, CA key and CA certificate we created earlier. This certificate will be valid for 365 days and is encrypted with sha256 algorithm.

[root@ldap-server ~]# openssl x509 -req -in ldap.example.com.csr -CA ca.cert.pem -CAkey ca.key -out ldap.example.com.crt -CAcreateserial -days 365 -sha256 -extfile server_cert_ext.cnf
Signature ok
subject=/C=IN/ST=Karnataka/L=Bengaluru/O=GoLinuxCloud/OU=R&D/CN=ldap-server.example.com/emailAddress=admin@golinuxcloud.com
Getting CA Private Key
Enter pass phrase for ca.key:

 

Verify the ldap client certificate

Next check the content of your ldap client certificate to make sure it contains the list of IP and DNS which we provided earlier.

[root@ldap-server ~]# openssl x509  -noout -text -in ldap.example.com.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            f5:bb:f8:f2:53:05:10:30
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=IN, ST=Karnataka, L=Bengaluru, O=GoLinuxCloud, OU=R&D, CN=ldap-server.example.com/emailAddress=admin@golinuxcloud.com
        Validity
            Not Before: Jul 23 10:20:45 2020 GMT
            Not After : Jul 23 10:20:45 2021 GMT
        Subject: C=IN, ST=Karnataka, L=Bengaluru, O=GoLinuxCloud, OU=R&D, CN=ldap-server.example.com/emailAddress=admin@golinuxcloud.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                    00:a4:6e:68:f6:5a:b2:72:ab:3c:8a:ca:aa:bf:3f:
                    e9:0a:d7:e5:49:67:6e:67:a4:01:56:dd:e8:dd:71:
                    40:d6:20:8a:24:ca:b3:72:b0:da:8e:05:86:37:61:
                    a5:1f:fd:0c:05:65:ac:35:72:7a:04:a6:6e:67:65:
                    f3:b4:b1:d5:b4:69:83:cb:d3:39:54:6d:94:b8:67:
                    9c:ec:4d:e6:24:90:a6:ff:fa:19:45:92:77:a7:77:
                    d3:79:d6:06:1c:63:17:d3:67:73:0c:1b:0b:63:97:
                    a7:73:ff:34:ee:8a:0e:6d:b5:4b:d6:2f:67:bc:62:
                    3d:65:21:f5:ff:8b:81:a0:cc:38:9c:fe:8c:27:10:
                    50:da:92:39:a4:bd:ae:14:e2:04:e8:70:f1:0a:01:
                    7f:37:70:c0:64:07:a0:51:1d:58:3e:de:7b:71:85:
                    ef:3f:c2:ff:6c:2f:15:13:17:05:36:9e:90:64:20:
                    d3:80:2d:3e:b3:6d:c2:94:b9:cf:81:8d:8f:65:00:
                    51:a9:8f:0c:0b:6a:dc:e6:93:10:79:68:af:b9:d6:
                    9c:53:32:e0:98:d9:c8:19:1c:6b:c1:d4:83:6b:d9:
                    cd:01:3d:0a:33:e9:6d:c6:c8:b2:27:8b:f1:a1:44:
                    5b:c9:01:7d:de:f9:cf:95:d5:85:4e:b8:e8:49:c2:
                    c8:84:93
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Cert Type:
                SSL Server
            Netscape Comment:
                OpenSSL Generated Server Certificate
            X509v3 Subject Key Identifier:
                34:3E:4D:99:C6:FA:7A:11:EE:57:C4:41:00:89:28:10:3C:04:50:49
            X509v3 Authority Key Identifier:
                keyid:D2:D3:6F:EC:96:57:5E:13:47:57:A3:35:13:47:C1:57:24:C8:01:C6
                DirName:/C=IN/ST=Karnataka/L=Bengaluru/O=GoLinuxCloud/OU=R&D/CN=ldap-server.example.com/emailAddress=admin@golinuxcloud.com
                serial:88:BA:9D:AD:59:E8:C9:27

            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                IP Address:192.168.43.32, IP Address:192.168.43.31, IP Address:192.168.43.154, DNS:client.example.com, DNS:server2.example.com
    Signature Algorithm: sha256WithRSAEncryption
         16:1e:13:6e:45:14:2f:2a:fc:e0:b3:e9:2c:68:e3:b4:4f:7b:
         03:f9:c2:c2:44:fb:5e:7f:ae:fb:07:1d:69:d0:5a:ed:70:62:
         f3:98:f0:8f:34:02:e4:0c:a0:3d:4d:19:69:7d:f8:7d:fb:a2:
         c6:b7:24:ec:02:a3:a3:cc:56:1e:ad:80:14:c7:21:b6:07:0e:
         13:36:80:7d:f8:a1:8c:53:8f:ab:ad:9d:09:f5:de:dc:d3:b7:
         2e:e2:39:40:1d:7e:be:1a:95:13:73:0b:57:64:5c:fd:22:8b:
         0f:56:d0:02:6f:87:b7:7e:c9:10:c0:7a:a2:8d:f6:24:33:b5:
         4f:2e:85:72:85:85:60:ac:f5:2c:28:ac:7e:aa:76:50:44:e0:
         7a:fa:14:06:ce:44:aa:fb:e8:22:cf:e5:ac:47:9c:aa:d4:2f:
         cd:1c:74:87:10:aa:17:af:40:99:7a:01:70:38:4a:a2:87:1e:
         4f:2f:0a:6e:22:71:37:4e:b5:31:28:22:ed:bf:62:d1:6f:34:
         2b:cc:62:06:bd:9f:b2:2d:a5:21:22:0b:a4:9b:19:4a:6c:02:
         b6:29:ec:2d:e7:0a:ed:c1

After signing the certificate, we copy both the certificate and the key file to /etc/openldap/certs/. We also copy the CA certificate to /etc/openldap/cacerts/. Later, we’ll have to modify the openldap configuration accordingly.

[root@ldap-server ~]# cp -v ldap.example.com.crt ldap.example.com.key /etc/openldap/certs/
‘ldap.example.com.crt’ -> ‘/etc/openldap/certs/ldap.example.com.crt’
‘ldap.example.com.key’ -> ‘/etc/openldap/certs/ldap.example.com.key’

[root@ldap-server ~]# cp -v ca.cert.pem /etc/openldap/cacerts/
‘ca.cert.pem’ -> ‘/etc/openldap/cacerts/ca.cert.pem’

 

Securing the LDAP protocol

In CentOS 7, there are already default values for the TLS related attributes. We can see these values with slapcat.

[root@ldap-server ~]# slapcat -b "cn=config" | egrep "olcTLSCertificateFile|olcTLSCertificateKeyFile"
olcTLSCertificateFile: "OpenLDAP Server"
olcTLSCertificateKeyFile: /etc/openldap/certs/password

We have to modify the values of the olcTLSCertificateFile and olcTLSCertificateKeyFile attributes. So, we create the following LDIF file:

[root@ldap-server ~]# cat tls7.ldif
dn: cn=config
changetype: modify
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/openldap/certs/ldap.example.com.crt
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/openldap/certs/ldap.example.com.key

Change the ownership of /etc/openldap/certs and and /etc/openldap/cacerts directory

[root@ldap-server ~]# chown -R openldap:openldap /etc/openldap/certs
[root@ldap-server ~]# chown -R openldap:openldap /etc/openldap/cacerts

And we run the ldapmodify command with this LDIF file .

[root@ldap-server ~]# ldapmodify -Y EXTERNAL -H ldapi:// -f tls7.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"

Next add a new attribute olcTLSCACertificateFile for CA certificate file. For this we will create another ldiff file

[root@ldap-server ~]# cat tls7_1.ldif
dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/openldap/cacerts/ca.cert.pem

[root@ldap-server ~]# ldapmodify -Y EXTERNAL -H ldapi:// -f tls7_1.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"

Validate the new values using slapchat.

[root@ldap-server ~]# slapcat -b "cn=config" | egrep "olcTLSCertificateFile|olcTLSCertificateKeyFile|olcTLSCACertificateFile"
olcTLSCertificateFile: /etc/openldap/certs/ldap.example.com.crt
olcTLSCertificateKeyFile: /etc/openldap/certs/ldap.example.com.key
olcTLSCACertificateFile: /etc/openldap/cacerts/ca.cert.pem

Now we edit the /etc/sysconfig/slapd file to add ldaps:/// to the SLAPD_URLS parameter.

SLAPD_URLS="ldapi:/// ldap:/// ldaps:///"

Change the below in /etc/openldap/ldap.conf

TLS_CACERTDIR /etc/openldap/certs
TLS_CACERT /etc/openldap/cacerts/ca.cert.pem
NOTE:

Since we are using self signed certificate it is important to specify the CA certificate using TLS_CACERT or else you may get "TLS negotiation failure" during ldap client authentication. Alternatively you can choose to use TLS_REQCERT never for insecure communication and ignore any certificate checks

Then we restart the service to activate our changes

[root@ldap-server ~]# systemctl restart slapd

and make sure there are no errors in the logs using "journalctl -f". I prefer to use journalctl to view the logs, you may check /var/log/messages using any editor/reader such as less, more etc

[root@ldap-server ~]# systemctl status slapd
● slapd.service - OpenLDAP Server Daemon
   Loaded: loaded (/usr/lib/systemd/system/slapd.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2020-07-23 16:51:12 IST; 3min 59s ago
     Docs: man:slapd
           man:slapd-config
           man:slapd-hdb
           man:slapd-mdb
           file:///usr/share/doc/openldap-servers/guide.html
  Process: 3799 ExecStart=/usr/sbin/slapd -u ldap -h ${SLAPD_URLS} $SLAPD_OPTIONS (code=exited, status=0/SUCCESS)
  Process: 3760 ExecStartPre=/usr/libexec/openldap/check-config.sh (code=exited, status=0/SUCCESS)
 Main PID: 3801 (slapd)
   CGroup: /system.slice/slapd.service
           └─3801 /usr/sbin/slapd -u ldap -h ldapi:/// ldap:/// ldaps:///

Jul 23 16:52:19 ldap-server.example.com slapd[3801]: conn=1001 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
Jul 23 16:52:19 ldap-server.example.com slapd[3801]: conn=1001 op=2 SRCH base="dc=example,dc=com" scope=2 deref=0 filter="(&(&(?objectClass=sudo...2.168.43
Jul 23 16:52:19 ldap-server.example.com slapd[3801]: conn=1001 op=2 SRCH attr=objectClass objectClass cn sudoCommand sudoHost sudoUser sudoOptio...imestamp
Jul 23 16:52:19 ldap-server.example.com slapd[3801]: conn=1001 op=2 SEARCH RESULT tag=101 err=0 nentries=0 text=
Hint: Some lines were ellipsized, use -l to show in full.

 

Validate TLS connectivity for LDAP

To make sure that TLS for LDAP is working properly, we can check it by passing the -ZZ option to ldapsearch.

Thus, we’re telling ldapsearch to establish a TLS connection.

[root@ldap-server certs]# ldapsearch -x -ZZ
# extended LDIF
#
# LDAPv3
# base <> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# search result
search: 3
result: 32 No such object

# numResponses: 1

When using ldapsearch, sometimes the system expects the certificate files to be in a special numeric format. This numeric format can be obtained with openssl, like this:

[root@ldap-server certs]# openssl x509 -in /etc/openldap/certs/ca.cert.pem -hash
5e379662
-----BEGIN CERTIFICATE-----
MIIEETCCAvmgAwIBAgIJAIUTUHlq/B9HMA0GCSqGSIb3DQEBCwUAMIGeMQswCQYD
VQQGEwJJTjESMBAGA1UECAwJS0FSTkFUQUtBMRIwEAYDVQQHDAlCRU5HQUxVUlUx

 

Configure Firewall

First, in the server, we’ll have to allow incoming traffic to port ldap (389) and ldaps (636)

[root@ldap-server ~]# firewall-cmd --add-service=ldap
success

[root@ldap-server ~]# firewall-cmd --add-service=ldaps
success

 

Conclusion

In this tutorial we learned to create our own Certificate Authority certificate, and then used this CA certificate to create ldap client certificate. This CA and client certificate will be used across all the ldap clients for encrypted and secure communication. I have created SAN certificate here but you can choose to create individual client certificates for all your ldap client nodes.

Lastly I hope the steps from the article to Configure OpenLDAP with TLS certificates on Linux was helpful. So, let me know your suggestions and feedback using the comment section

 

What's Next

Now since we have our LDAP server is ready with TLS certificates, next we will

 

References

I have used below external references for this tutorial guide
Learn CentOS Linux Network Services

 

 

18 thoughts on “Step-by-Step Tutorial: Configure OpenLDAP with TLS certificates CentOS 7 Linux”

  1. Hi,
    First of all, thanks for the article it is very useful and easy to understand. If I may have a suggestion, would you please add a note under securing the LDAP protocol. Since with the default root:root permissions of the certificates under /etc/openldap/certs and /etc/openldap/cacerts dir, ldapmodify can't be executed. It should be owned by openldap user eg:

    chown -R openldap:openldap /etc/openldap/certs

    Reply
  2. Thanks for the tutorial but "ldapsearch -x -ZZ" gives me the error
    ldap_start_tls: Connect error (-11)
    additional info: TLS error -12227:SSL peer was unable to negaotiate an acceptable set of security parameters.

    Reply
  3. i followed all the instruction except
    #
    #TLS_CACERTDIR /etc/openldap/certs
    TLS_REQCERT never
    #

    i couldn't find it in centos 7
    so when i make a request am getting following error
    ldap_start_tls: Connect error (-11)
    additional info: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed (self signed certificate in certificate chain)

    Reply
    • Hello, the problem is that inside ldap.conf, make sure your cacert is pointed to the right file. I made same mistake and was getting same error

      TLS_CACERT      /etc/openldap/cacerts/ca.cert.pem
      Reply
  4. i did followed all instruction except
    #TLS_CACERTDIR /etc/openldap/certs
    TLS_REQCERT never

    so when i make a request am getting following error, any solution in appreciated
    ldap_start_tls: Connect error (-11)
    additional info: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed (self signed certificate in certificate chain)

    Reply
    • If you are using a non valid cert, you can force accept it configuring /etc/openldap/ldap.conf with

      TLS_REQCERT allow
      or
      TLS_REQCERT never
      If you are using a valid cert probably your ldap instalation don't know where store of trusted CA certificates is (probably depending on your OpenSSL installation). Then you can try to set it location and force check configuring /etc/openldap/ldap.conf with

      TLS_CACERT /etc/openldap/cacert
      TLS_REQCERT demand

      source: serverfault.com

      Reply
    • I have updated the article to handle this error. We must define the explicit location of ca certificate and also for clients we should have SAN certificates. I recently faced this while adding one new ldap client.

      Reply
  5. Hi I tried everything and I am stuck with this error:
    ldap_create
    ldap_extended_operation_s
    ldap_extended_operation
    ldap_send_initial_request
    ldap_new_connection 1 1 0
    ldap_int_open_connection
    ldap_connect_to_host: TCP mgmt-node.iteindia.lab:636
    ldap_new_socket: 3
    ldap_prepare_socket: 3
    ldap_connect_to_host: Trying fe80::250:56ff:feb1:a0a3 636
    ldap_pvt_connect: fd: 3 tm: -1 async: 0
    attempting to connect:
    connect success
    TLSMC: MozNSS compatibility interception begins.
    tlsmc_intercept_initialization: INFO: entry options follow:
    tlsmc_intercept_initialization: INFO: cacertdir = `(null)'
    tlsmc_intercept_initialization: INFO: certfile = `(null)'
    tlsmc_intercept_initialization: INFO: keyfile = `(null)'
    tlsmc_convert: INFO: trying to open NSS DB with CACertDir = `(null)'.
    tlsmc_convert: INFO: cannot open the NSS DB, expecting PEM configuration is present.
    tlsmc_intercept_initialization: INFO: altered options follow:
    tlsmc_intercept_initialization: INFO: cacertdir = `(null)'
    tlsmc_intercept_initialization: INFO: certfile = `(null)'
    tlsmc_intercept_initialization: INFO: keyfile = `(null)'
    tlsmc_intercept_initialization: INFO: successfully intercepted TLS initialization. Continuing with OpenSSL only.
    TLSMC: MozNSS compatibility interception ends.
    TLS trace: SSL_connect:before/connect initialization
    TLS trace: SSL_connect:SSLv2/v3 write client hello A
    TLS trace: SSL3 alert read:fatal:handshake failure
    TLS trace: SSL_connect:error in SSLv2/v3 read server hello A
    TLS: can't connect: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure.
    ldap_err2string
    ldap_start_tls: Can't contact LDAP server (-1)
    additional info: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

    ---------------------------------
    Please help

    Reply

Leave a Comment

Please use shortcodes <pre class=comments>your code</pre> for syntax highlighting when adding code.