Simple steps to configure LDAPS 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

Advertisement

 

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.

 

Lab Environment

I have already configured an LDAP server and LDAP client in my previous articles so I will use the same setup here. Just to brief the setup, my LDAP server hostname is server.example.com with IP address 192.168.0.114 while my client's hostname is client.example.com with an IP address 192.168.0.152

 

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

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

 

Generate CA certificate

We will use our own CA certificate to sign the server certificate required for secure LDAP communication. So first we will generate the CA certificate using openssl. Navigate to /etc/pki/CA where we will keep our serial and index.txt file to keep a track of issued certificates.

[root@server ~]# cd /etc/pki/CA/

[root@server CA]# touch index.txt
[root@server CA]# echo 01 > serial

 

Create private key for CA certificate

Let's generate a private key required for the CA certificate. If you wish to have an encrypted private key then you can add -des3 in the below command. It is IMPORTANT that you store this private key securely as you will need this to renew your CA certificate later.

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

 

Generate CA Certificate

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

[root@server ~]# openssl req -new -x509 -days 365 -key ca.key -out ca.cert.pem

Sample output from my terminal:
configure-openldap-with-tls-certificates/

 

Generate LDAP server certificate

Next we will generate a certificate for our LDAP server which will be used by the client for communication.

 

Configure openssl x509 extension to create SAN certificate(optional)

This step can be optional based on your requirement. It is possible you have multiple interfaces of the LDAP server with different IP Address and FQDN. So in such case we can create a SAN certificate with multiple Subject Alternate Name.

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 server.

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. You can add all the possible IP Address and FQDN of your LDAP server under [alt_names] which will be used by the client for making secure connection.

[root@server ~]# cat server_cert_ext.cnf
[v3_ca]
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.0.114
IP.2 = 192.168.43.31
IP.3 = 192.168.43.154
DNS.1 = server.example.com

 

Advertisement

Generate private key for LDAP server certificate

Next we will need another private key for the LDAP server certificate which we will name as "ldap.example.com.key"

[root@server CA]# cd private/

[root@server private]# 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 server certificate. As we are planning to use an additional configuration file with the list of IP and DNS value of the LDAP server, so you can just choose to give any of the FQDN value of LDAP server as Common Name here:

[root@server private]# openssl req -new -key ldap.example.com.key -out ldap.example.com.csr

Sample output from my terminal:
configure-openldap-with-tls-certificates/

 

Create LDAP server certificate

Next we will create our ldap server 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. We have also specified our configuration file with the required extension as used in the config file.

[root@server CA]# openssl ca -keyfile ca.key -cert ca.cert.pem -in private/ldap.example.com.csr -out private/ldap.example.com.crt -extensions v3_ca -extfile /root/server_cert_ext.cnf
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Apr  7 12:34:03 2021 GMT
            Not After : Apr  7 12:34:03 2022 GMT
        Subject:
            countryName               = IN
            stateOrProvinceName       = Karnataka
            organizationName          = GoLinuxCloud
            organizationalUnitName    = Database
            commonName                = server.example.com
            emailAddress              = admin@golinuxcloud.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Cert Type:
                SSL Server
            Netscape Comment:
                OpenSSL Generated Server Certificate
            X509v3 Subject Key Identifier:
                10:FB:A6:87:22:21:76:A8:3D:E3:08:46:26:9D:05:7D:AF:91:A0:4C
            X509v3 Authority Key Identifier:
                keyid:82:63:18:EE:5A:BE:5D:91:B8:A0:BE:BC:52:59:BB:B9:89:BC:46:29
                DirName:/C=IN/ST=Karnataka/L=Bengaluru/O=GoLinuxCloud/OU=Test/CN=server.example.com/emailAddress=admin@golinuxcloud.com
                serial:C8:2F:0C:95:1A:52:02:1B

            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                IP Address:192.168.0.114, IP Address:192.168.43.31, IP Address:192.168.43.154, DNS:server.example.com
Certificate is to be certified until Apr  7 12:34:03 2022 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Now that the certificate has been signed by the CA , we can see that the index.txt file has been updated.

[root@server CA]# cat index.txt
V       220407123403Z           01      unknown /C=IN/ST=Karnataka/O=GoLinuxCloud/OU=Database/CN=server.example.com/emailAddress=admin@golinuxcloud.com

 

Verify the ldap client certificate

We can also verify the issued certificate against our CA:

[root@server CA]# openssl verify -CAfile ca.cert.pem private/ldap.example.com.crt
private/ldap.example.com.crt: OK

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

[root@server CA]# openssl x509  -noout -text -in private/ldap.example.com.crt  | grep -A 1 "Subject Alternative Name"
            X509v3 Subject Alternative Name:
                IP Address:192.168.0.114, IP Address:192.168.43.31, IP Address:192.168.43.154, DNS:server.example.com

 

Configure LDAPS certificate (using TLS)

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@server CA]# cp -v private/ldap.example.com.crt private/ldap.example.com.key /etc/openldap/certs/              
‘private/ldap.example.com.crt’ -> ‘/etc/openldap/certs/ldap.example.com.crt’
‘private/ldap.example.com.key’ -> ‘/etc/openldap/certs/ldap.example.com.key’

[root@server CA]# 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@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@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@server ~]# chown -R openldap:openldap /etc/openldap/certs
[root@server ~]# chown -R openldap:openldap /etc/openldap/cacerts

And we run the ldapmodify command with this LDIF file .

[root@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@server ~]# cat tls7_1.ldif
dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/openldap/cacerts/ca.cert.pem

Apply these changes:

[root@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@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

 

Enable TLS in LDAP configuration file

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
TLS_REQCERT allow
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

 

Restart slapd service

Then we restart the service to activate our changes

[root@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@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/openservers/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 server.example.com slapd[3801]: conn=1001 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
Jul 23 16:52:19 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 server.example.com slapd[3801]: conn=1001 op=2 SRCH attr=objectClass objectClass cn sudoCommand sudoHost sudoUser sudoOptio...imestamp
Jul 23 16:52:19 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.

 

Configure Firewall

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

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

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

[root@server ~]# firewall-cmd --reload

 

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 from our client node (assuming you have configured your client):

[root@client ~]# ldapsearch -x -ZZ
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# example.com
dn: dc=example,dc=com
objectClass: dcObject
objectClass: organization
dc: example
o: example

# search result
search: 3
result: 0 Success

# numResponses: 2
# numEntries: 1

Following is the log snippet from journalctl -f on the ldap server:

Apr 07 18:20:52 server.example.com slapd[4034]: conn=1002 fd=15 ACCEPT from IP=192.168.0.152:45486 (IP=0.0.0.0:389)
Apr 07 18:20:52 server.example.com slapd[4034]: conn=1002 op=0 EXT oid=1.3.6.1.4.1.1466.20037
Apr 07 18:20:52 server.example.com slapd[4034]: conn=1002 op=0 STARTTLS
Apr 07 18:20:52 server.example.com slapd[4034]: conn=1002 op=0 RESULT oid= err=0 text=
Apr 07 18:20:52 server.example.com slapd[4034]: conn=1002 fd=15 TLS established tls_ssf=256 ssf=256
Apr 07 18:20:52 server.example.com slapd[4034]: conn=1002 op=1 BIND dn="" method=128
Apr 07 18:20:52 server.example.com slapd[4034]: conn=1002 op=1 RESULT tag=97 err=0 text=
Apr 07 18:20:52 server.example.com slapd[4034]: conn=1002 op=2 SRCH base="dc=example,dc=com" scope=2 deref=0 filter="(objectClass=*)"
Apr 07 18:20:52 server.example.com slapd[4034]: conn=1002 op=2 SEARCH RESULT tag=101 err=0 nentries=1 text=
Apr 07 18:20:52 server.example.com slapd[4034]: conn=1002 op=3 UNBIND
Apr 07 18:20:52 server.example.com slapd[4034]: conn=1002 fd=15 closed

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@server certs]# openssl x509 -in /etc/openldap/certs/ca.cert.pem -hash
5e379662
-----BEGIN CERTIFICATE-----
MIIEETCCAvmgAwIBAgIJAIUTUHlq/B9HMA0GCSqGSIb3DQEBCwUAMIGeMQswCQYD
VQQGEwJJTjESMBAGA1UECAwJS0FSTkFUQUtBMRIwEAYDVQQHDAlCRU5HQUxVUlUx

 

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

 

 

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

18 thoughts on “Simple steps to configure LDAPS 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