Transport Layer Security (TLS) is the standard name for the Secure Socket Layer (SSL). The terms (unless qualified with specific version numbers) are generally interchangable.

StartTLS is the name of the standard LDAP operation for initiating TLS/SSL. TLS/SSL is initiated upon successful completion of this LDAP operation. No alternative port is necessary. It is sometimes referred to as the TLS upgrade operation, as it upgrades a normal LDAP connection to one protected by TLS/SSL.

ldaps:// and LDAPS refers to "LDAP over TLS/SSL" or "LDAP Secured". TLS/SSL is initated upon connection to an alternative port (normally 636). Though the LDAPS port (636) is registered for this use, the particulars of the TLS/SSL initiation mechanism are not standardized.

Once initiated, there is no difference between ldaps:// and StartTLS. They share the same configuration options (excepting ldaps:// requires configuration of a separate listener, see slapd(8)'s -h option) and result in like security services being established.

Note:
1) ldap:// + StartTLS should be directed to a normal LDAP port (normally 389),
not the ldaps:// port.
2) ldaps:// should be directed to an LDAPS port (normally 636), not the LDAP port.

Configuring in OpenLDAP 2.1 and later - Since 2.1, the client libraries will verify server certificates. This change requires clients to add the TLS_CACERT (or, alternately, the TLS_CACERTDIR) option to their system-wide ldap.conf(5) file. Without this setting, the LDAP clients will fail to make any TLS/SSL connections to any servers.

Using Certificates: As noted in the Admin Guide, first you need a CA certificate. This can be one purchased commercially, or one you create yourself. To create your own CA certificate using OpenSSL, you create a self-signed cert. (You only need to do this once.) Use the CA.sh script that is installed with OpenSSL. You should have a filesystem directory reserved for the CA's use, e.g. /var/myca.

cd /var/myca
CA.sh -newca

Next, create a cert request and private key for the server. Remember that the Common Name for this cert should be the fully qualified domain name of the server:

openssl req -new -nodes -keyout newreq.pem -out newreq.pem

(The -nodes argument above prevents encryption of the private key. OpenLDAP only works with unencrypted private keys.)
Then use your CA to sign this cert request:

CA.sh -sign

Finally you need to install these certs for use with OpenLDAP Software. Assuming your OpenLDAP Software was installed in /usr/local:

(The server's private key is sensitive data and must only be readable by the user that slapd runs as, so the permissions are explicitly restricted on the key file above. The cert files should be publically readable.)
Then add these lines to /usr/local/etc/openldap/slapd.conf:

OpenLDAP 2.0 and later supports StartTLS [RFC4511][RFC4513] and ldaps://. Most clients now
have a -Z flag which enables sending the StartTLS extended
operation to the server. This extended operation initiates
TLS negotiation. To use ldaps://, one must use -H ldaps://.

As OpenLDAP clients implement certificate checking, you should make sure that
the
domain name provided to the client matches that in the server's certificate.
Generally, you should use fully qualified domain names on the
command line and in the certificate.

RFC 4513 also specifies a means for additional names to be set in a certificate. This is done using the subjectAltName field which is an X.509v3 extension of the basic certificate. This field can be used to list aliases for a server, shared names in a load-balancing setup, or any other desired purpose.
A wildcard can also be used, to allow a single certificate to match all hostnames within a given domain.

In the openssl.cnf file, the syntax for this extension is

subjectAltName=DNS:alias1.domain1,DNS:host2.domain2,DNS:*.domain3

Any number of names may be specified in the comma-separated list.

There is some support for using TLS/SSL in OpenLDAP 2.0.
If you want to try it, keep on reading.

Not much of this has been tested in practice and is under evolution. Currently, only slapd works and it has only be tested with Netscape Communicator as a client.

Most things here will be obvious if you already use Apache with mod_ssl or some similar package. If, however, this is your first project with SSL, then I recommend you play a little bit with Apache mod_ssl and OpenSSL until you feel confident, since those packages are better tested and documented.

First of all you need to rebuild OpenLDAP with support for TLS/SSL. This can be automatic or it may require some help at configure time. You may have to use --with-tls and you may need to do something like:

Then 'make depend; make' to rebuild OpenLDAP and 'make install' to install it. Be careful if you have dynamic libraries for OpenSSL and you are using nss_ldap or pam_ldap linked dynamically with -lldap and -llber: your system may become hosed as soon as you install the new libraries. If this is the case, you will have to rebuild nss_ldap and pam_ldap so that they know they have additional dependencies on libssl and libcrypto.

Now, hopefully you have a TLS/SSL-capable OpenLDAP.

You need a certificate for your server. That certificate will have to be trusted by your Netscape client and this will have to be prepared beforehand. You may be used to Netscape prompting a dialog box so that you decide to trust an unknown certificate and such: forget about it, this will not happen with LDAP: either everything is properly setup or it will not work (typical error from Netscape is 0xFFFFFFFF).

There are a number of ways you can make this happen. You can have Netscape learn the certificate of your server by abusing the HTTP dialog. For this, open URL https://yourserver:636 and the dialog will appear, there you can select to accept that server certificate for this and all future sessions. You can only do this when you have your slapd running with the right magic. Of course, the protocols will not match and no useful communication will happen, but the side effect is what matters. Neither the server nor the client will notice there is something wrong until the have completed the negotiation and, by then, you already got the dialog and have installed the certificate in the client.

If your certificate is directly signed by a CA that is itself installed in your browser and marked as trusted, it will work too.

If your certificate is indirectly signed by a CA that is installed and trusted in the browser, that will work, but you will have to tell slapd to send the intermediate CA certificates to the browser as I explain below.

I think I have tried all methods above and all of them worked for me. Then, I may be wrong.

If you are not experienced in this you may be wondering how to get the CA certificate into Netscape in the first place if it is a CA you created yourself. There are a couple of methods. The easiest method is to use a web server that you may have around. First, arrange for the web server to give the correct MIME type to the certificate using mime.types or including a line in the configuration file like this (for Apache):

AddType application/x-x509-ca-cert .crt

Then put the certificate in a file with extension .crt some place the web server can serve it and ask for it from the browser. A dialog will be shown warning that a new Certification Authority is about to be registered, follow the dialog and make the CA trusted.

You may have to translate the certificate into a format that Netscape likes, as far as I remember, it won't like the default PEM format used by OpenSSL. You can do it like this:

openssl x509 -in cert.pem -out cert.crt -outform net

The second method involves translating the certificate into PKCS12 format and importing it into Netscape as if it were a 'Yours' certificate, but it is more
hairy and you will have to be extra careful not to leak the CA private key this way since, by default, the PKCS12 format wants to have both keys.

OK, if you have a certificate and a private key pair ready, then we can proceed. First the bad news: you need a copy of the private key in the clear: it cannot be encrypted, slapd will not prompt for the decoding password. So be careful with the permissions on that file. Now include the following lines in slapd.conf:

The latter will be needed if there are multiple CAs from the root to the server certificate. I think it can be left out if only one level is used, but I don't think I tried it, so if you want to play safe, catenate together your root certificate and all intermediate CA certificates (PEM format!!!) in a file and use that.

Now stop slapd and start it again like this:

slapd -h "ldap:/// ldaps:///"

Slapd will now listen on port 389 for LDAP and 636 for LDAPS.
The server can also negotiate TLS/SSL using the StartTLS extended operation
over port 389. You may leave out the second URL if you only want to support
StartTLS..

If everything went OK, now open your Address Book on Netscape, right click on the directory, choose properties and select the secure option. If you were running on the standard port 389, the port will change automatically to 636, otherwise set the correct port. Do not set 'Login with Name and Password', there is some problem there that has not been diagnosed yet. Click on accept and you are all set, do a search and the results will appear on your Address Book window. The lock on the lower left corner will show as closed.

If things did not work alright, stop slapd and start it with debugging (see option -d) and read the output, I have tried to provide a complete error trace from OpenSSL, it should be apparent what the problem is. If it isn't, then let us know.

Ok, I think that's it.

Be careful when modifying the CA.pl/Ca.sh/CA-nodes/whatever scripts.
If you change the base-directory (demoCA), ca-key and cert are created in the new directory but for SIGNING new requests the old demoCA-directory-key was used.
This resulted in the following error:
TLS: error: 14094418 ...unknown ca
which (after googleing ) looked like an error in the file ldap.conf or the ldap-client using a different ldap.conf.

For those of you wanting to use the subjectAltName x509 extension, in openSSL 0.97b you should put it in the [user_cert ] section.
You can use both DNS names and IP addresses, e.g.:

Note that if the TLS-related directives in slapd.conf are properly configured, TLS will be available over port 389 even without specifying '-h ldaps://' on the slapd command line. In fact, this is the way to make TLS available without making ldaps available.

TLS_CACERTDIR:
Openssl looks up for ca cert based on the x509 hash of the cert. That's why you need to create a softlink between actual ca cert and its hash (see how they are in Ubuntu's /etc/ssl/certs)
TLS_CACERTDIR=/etc/openldap/certs
HASH=`openssl x509 -noout -hash -in /etc/openldap/certs/cacert1.pem`
cd /etc/openldap/certs;ln -s cacert1.pem ${HASH}.0

Hi, I enabled TLS with my openldap server through port 389 successfully on ubuntu. However, I found there is non encryption connection to the same port 389.How can I enforce TLS connection only and reject all the nonencrypted connections? Thanks a lot!

$ openssl dhparam -out /etc/openldap/ssl.key/dhparam 2048
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
.................................................................

When using static OpenLDAP configuration (slapd.conf)
add this configuration directive to the global section of your configuration file(s).

TLSDHParamFile /etc/openldap/ssl.key/dhparam

When using dynamic OpenLDAP configuration (back-config)
use this LDIF change snippet to set attribute olcTLSDHParamFile
in entry cn=config:

Problem: slapd does not start up, and you see main: TLS init def ctx failed: -1 in your syslog. Possible solution: check permissions on certificate and private key files. If slapd does not run as root, make sure the private key is readable by the user it does run as. Perhaps also check for SELinux.

Problem: on an old version of openldap (e.g., from a Linux distribution), slapd starts up fine, but when you connect to the ldaps port, ssl negotiation fails and the connection is closed. Possible solution: same as above. (Preferable solution: run the latest release of openldap.)