Last updated: 2026-06-25
OpenLDAP TLS/SSL Configuration Guide
This guide provides recommended TLS/SSL settings for OpenLDAP (slapd) to encrypt LDAP connections. OpenLDAP supports two modes of TLS: LDAPS (implicit TLS on port 636) and STARTTLS (upgrade from plaintext on port 389). Both should be configured, with LDAPS being the preferred mode.
Prerequisites
- OpenLDAP 2.5 or later (2.6+ recommended)
- OpenSSL or GnuTLS (depending on build)
- A valid SSL/TLS certificate
Certificate Setup
Set appropriate permissions on certificate files:
chmod 640 /etc/ldap/ssl/privkey.pem
chown root:openldap /etc/ldap/ssl/privkey.pem
chmod 644 /etc/ldap/ssl/cert.pem /etc/ldap/ssl/ca.pem
Path note: This guide uses Debian/Ubuntu paths (
/etc/ldap/ssl/, groupopenldap). On RHEL and SLES, the base directory is/etc/openldap/and the slapd service runs as user/groupldap. Adjust certificate paths and ownership accordingly (e.g.chown root:ldap).
Configuration Methods
OpenLDAP can be configured via the static config file (slapd.conf) or the dynamic config backend (cn=config). The dynamic backend is recommended for modern deployments as it allows changes without restarting slapd.
OpenLDAP 2.5+ (Debian 12 ships 2.5, Ubuntu 24.04 ships 2.6):
slapd.confis deprecated in favor ofcn=config. While it still works, new deployments should use the dynamic configuration method. See the Dynamic Configuration section below.
Static Configuration (slapd.conf)
Add TLS settings to your slapd.conf:
Certificate Files
TLSCACertificateFile /etc/ldap/ssl/ca.pem
TLSCertificateFile /etc/ldap/ssl/cert.pem
TLSCertificateKeyFile /etc/ldap/ssl/privkey.pem
Protocol Version
Set the minimum TLS version to 1.2:
TLSProtocolMin 3.3
OpenLDAP uses the internal SSL/TLS version numbering:
3.1= TLS 1.03.2= TLS 1.13.3= TLS 1.23.4= TLS 1.3 (requires OpenLDAP 2.5+)
Version note:
TLSProtocolMin 3.4(TLS 1.3) requires OpenLDAP 2.5+. On OpenLDAP 2.4,3.3(TLS 1.2) is the maximum supported value.
Cipher Suites
Configure strong cipher suites. The syntax depends on whether OpenLDAP was built with OpenSSL or GnuTLS.
For OpenSSL:
TLSCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
For GnuTLS:
TLSCipherSuite SECURE256:+SECURE128:-VERS-TLS-ALL:+VERS-TLS1.2:+VERS-TLS1.3:-RSA:-DHE-RSA:-CAMELLIA-128-CBC:-CAMELLIA-256-CBC
On OpenLDAP 2.5+ (OpenSSL builds), you can also set TLS 1.3 cipher suites explicitly with TLSCipherSuite13:
TLSCipherSuite13 TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
Client Certificate Verification
Control how the server verifies client certificates:
TLSVerifyClient demand
Available values:
- never - Don't request a client certificate (default)
- allow - Request a certificate, but don't require one
- try - Request a certificate, verify if presented, but don't fail if missing
- demand - Require a valid client certificate (mutual TLS)
For most deployments, never is appropriate (clients authenticate via LDAP bind):
TLSVerifyClient never
See RFC 8446 ยง4.3.2 for the TLS Certificate Request specification, and Wikipedia: Mutual authentication for a general overview.
Dynamic Configuration (cn=config)
Apply TLS settings using LDIF modifications. Create a file tls.ldif:
dn: cn=config
changetype: modify
replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ldap/ssl/ca.pem
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/ssl/cert.pem
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/ssl/privkey.pem
-
replace: olcTLSProtocolMin
olcTLSProtocolMin: 3.3
-
replace: olcTLSCipherSuite
olcTLSCipherSuite: ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
-
replace: olcTLSVerifyClient
olcTLSVerifyClient: never
Note: On Debian/Ubuntu, OpenLDAP is linked against GnuTLS rather than OpenSSL. Replace the olcTLSCipherSuite value with the hardened GnuTLS priority string SECURE256:+SECURE128:-VERS-TLS-ALL:+VERS-TLS1.2:+VERS-TLS1.3:-RSA:-DHE-RSA:-CAMELLIA-128-CBC:-CAMELLIA-256-CBC. See the Cipher Suites section above for details.
Apply the LDIF:
ldapmodify -Y EXTERNAL -H ldapi:/// -f tls.ldif
Enable LDAPS Listener
Configure slapd to listen on both LDAP (389) and LDAPS (636). Edit the slapd service arguments.
On Debian/Ubuntu, edit /etc/default/slapd:
SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"
On RHEL, edit /etc/sysconfig/slapd:
SLAPD_URLS="ldap:/// ldaps:/// ldapi:///"
Note: On SLES 15, the slapd service configuration is in /etc/sysconfig/openldap. Set the variable OPENLDAP_START_LDAPS="yes" to enable the LDAPS listener on port 636.
To disable plaintext LDAP and only allow LDAPS:
SLAPD_SERVICES="ldaps:/// ldapi:///"
Require TLS for Binds
To prevent passwords from being sent over unencrypted connections, add a security requirement:
In slapd.conf:
security ssf=128
Or via cn=config:
dn: cn=config
changetype: modify
replace: olcSecurity
olcSecurity: ssf=128
This requires a minimum security strength factor of 128 bits, which effectively mandates TLS for all operations.
Client Configuration
ldap.conf
Configure the system-wide LDAP client settings in /etc/ldap/ldap.conf (or /etc/openldap/ldap.conf):
TLS_CACERT /etc/ldap/ssl/ca.pem
TLS_REQCERT demand
- TLS_REQCERT demand verifies the server certificate against the CA (recommended).
Command-Line Usage
Connect with LDAPS:
ldapsearch -H ldaps://ldap.example.com -b "dc=example,dc=com" -D "cn=admin,dc=example,dc=com" -W
Connect with STARTTLS:
ldapsearch -H ldap://ldap.example.com -ZZ -b "dc=example,dc=com" -D "cn=admin,dc=example,dc=com" -W
The -ZZ flag requires STARTTLS to succeed (fails if TLS cannot be established). Use -Z for optional STARTTLS.
Complete Static Configuration
# TLS certificate files
TLSCACertificateFile /etc/ldap/ssl/ca.pem
TLSCertificateFile /etc/ldap/ssl/cert.pem
TLSCertificateKeyFile /etc/ldap/ssl/privkey.pem
# Protocol and cipher settings
TLSProtocolMin 3.3
TLSCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
# Client certificate verification
TLSVerifyClient never
# Require TLS for all operations
security ssf=128
Note: On Debian/Ubuntu, OpenLDAP is linked against GnuTLS rather than OpenSSL. The TLSCipherSuite value above uses OpenSSL syntax; on GnuTLS-based builds, use a GnuTLS priority string instead: SECURE256:+SECURE128:-VERS-TLS-ALL:+VERS-TLS1.2:+VERS-TLS1.3:-RSA:-DHE-RSA:-CAMELLIA-128-CBC:-CAMELLIA-256-CBC (see the Cipher Suites section for details).
Security Notes
OpenLDAP links against either OpenSSL (RHEL/Fedora) or GnuTLS (Debian/Ubuntu), so the relevant vulnerability history depends on your distribution:
OpenSSL builds:
- POODLE (CVE-2014-3566, 2014): SSL 3.0 disabled. Fixed in OpenSSL 1.0.1j / 1.0.2 (October 2014); disabled by default in OpenSSL 1.1.0 (August 2016).
- Heartbleed (CVE-2014-0160, 2014): A memory disclosure bug in OpenSSL 1.0.1 through 1.0.1f. Fixed in OpenSSL 1.0.1g (April 7, 2014). Addressed by patching, not by TLS configuration.
GnuTLS builds:
- POODLE (CVE-2014-3566, 2014): SSL 3.0 disabled since GnuTLS 3.4.0 (April 2015).
- FREAK (CVE-2015-0204, 2015): EXPORT ciphers removed since GnuTLS 3.4.0 (April 2015).
- CVE-2014-0092 (March 2014): Certificate validation bypass fixed in GnuTLS 3.1.22 / 3.2.12.
- Heartbleed: Not applicable. GnuTLS is independent of OpenSSL.
Both builds:
- BEAST (CVE-2011-3389, 2011): Mitigated by recommending TLS 1.2 as the minimum; AEAD-only ciphers eliminate the CBC padding oracle.
- LOGJAM (CVE-2015-4000, 2015): Short-key DHE is excluded; only ECDHE key exchange is recommended.
- Sweet32 (CVE-2016-2183, 2016): 3DES is excluded from the recommended cipher configuration.
- ROBOT (2017): Static RSA key exchange is excluded; only ECDHE is recommended.
The following are not addressable through TLS configuration alone:
- BREACH (CVE-2013-3587, 2013): Not applicable. BREACH targets HTTP-level response compression; LDAP does not involve HTTP.
- DROWN (CVE-2016-0800, 2016): Requires SSLv2 to be enabled on any server sharing the same private key. Ensure SSLv2 is disabled across all services using the same key pair.
Verification
Restart slapd:
systemctl restart slapd
Test LDAPS connectivity:
openssl s_client -connect ldap.example.com:636
Test STARTTLS:
openssl s_client -connect ldap.example.com:389 -starttls ldap
Verify the TLS configuration through slapd:
ldapsearch -H ldapi:/// -Y EXTERNAL -b "cn=config" "(objectClass=olcGlobal)" olcTLS*