Linux – Persuading openldap to work with SSL on Ubuntu with cn=config

ldaplinuxopenldapsslUbuntu

I simply cannot get this (TLS connection to openldap) to work and would appreciate some assistance.

I have a working openldap server on ubuntu 10.04 LTS, it is configured to use cn=config and most of the info I can find for TLS seems to use the older slapd.conf file 🙁

I've been largely following the instructions here https://help.ubuntu.com/10.04/serverguide/C/openldap-server.html plus stuff I've read here and elsewhere – which of course could be part of the problem as I don't totally understand all of this yet!

I have created an ssl.ldif file as follows;

dn:cn=config

add: olcTLSCipherSuite
olcTLSCipherSuite: TLSV1+RSA:!NULL
add: olcTLSCRLCheck
olcTLSCRLCheck: none
add: olcTLSVerifyClient
olcTLSVerifyClient: never
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/ldap_cacert.pem
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/my.domain.com_slapd_cert.pem
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/my.domain.com_slapd_key.pem

and I import it using the following command line

ldapmodify -x -D cn=admin,dc=mydomain,dc=com -W -f ssl.ldif

I have edited /etc/default/slapd so that it has the following services line;

SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"

And everytime I'm making a change, I'm restarting slapd with /etc/init.d/slapd restart

The following command line to test out the non TLS connection works fine;

ldapsearch -d 9 -D cn=admin,dc=mydomain,dc=com -w mypassword \
-b dc=mydomain,dc=com -H "ldap://mydomain.com" "cn=roger*"

But when I switch to ldaps using this command line;

ldapsearch -d 9 -D cn=admin,dc=mydomain,dc=com -w mypassword \
-b dc=mydomain,dc=com -H "ldaps://mydomain.com" "cn=roger*"

This is what I get;

ldap_url_parse_ext(ldaps://mydomain.com)
ldap_create
ldap_url_parse_ext(ldaps://mydomain.com:636/??base)
ldap_sasl_bind
ldap_send_initial_request
ldap_new_connection 1 1 0
ldap_int_open_connection
ldap_connect_to_host: TCP mydomain.com:636
ldap_new_socket: 3
ldap_prepare_socket: 3
ldap_connect_to_host: Trying 127.0.0.1:636
ldap_pvt_connect: fd: 3 tm: -1 async: 0
TLS: can't connect: A TLS packet with unexpected length was received..
ldap_err2string
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)

Now if I check netstat -al I can see;

tcp        0      0 *:www                   *:*                     LISTEN
tcp        0      0 *:ssh                   *:*                     LISTEN
tcp        0      0 *:https                 *:*                     LISTEN
tcp        0      0 *:ldaps                 *:*                     LISTEN
tcp        0      0 *:ldap                  *:*                     LISTEN

I'm not sure if this is significant as well … I suspect it is;

openssl s_client -connect mydomain.com:636 -showcerts
CONNECTED(00000003)
916:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:188:

I think I've made all my certificates etc OK and here are the results of some checks;

If I do this;

certtool -e --infile /etc/ssl/certs/ldap_cacert.pem

I get Chain verification output: Verified.

certtool -e --infile /etc/ssl/certs/mydomain.com_slapd_cert.pem

Gives "certtool: the last certificate is not self signed" but it otherwise seems OK?

Where have I gone wrong? Surely getting openldap to run securely on ubuntu should be easy and not require a degree in rocket science!

Any ideas?

Best Answer

Roger's link has since rotted, here is the same on the Internet Archive's WayBack Machine, as of the last date archived before he changed his site: https://web.archive.org/web/20150530064010/http://rogermoffatt.com/2011/08/24/ubuntu-openldap-with-ssltls/

I've also taken the liberty to append his content below as well:

The Starting Point

I’m going to assume that you have a working openldap installation (not secured) using cn=config (the LDAP database) for configuration rather than the old style slapd.conf variation. If you are making changes by editing slapd.conf, then the rest of this article is not for you!

STEP ONE

Create some self-signed certificates to get started. If you’ve already created some certificates for a web server using openssl, the first thing that will catch you out is that they won’t work with ldap. You need certificates in a different format and to generate them we need a new tool that you won’t have yet.

sudo -i
apt-get update
apt-get install gnutls-bin
certtool --generate-privkey --outfile /etc/ssl/private/ldap-ca-key.pem
certtool --generate-self-signed --load-privkey /etc/ssl/private/ldap-ca-key.pem --outfile /etc/ssl/certs/ldap-ca-cert.pem

Fix your permissions – the resulting files need to be readable by the openldap group.

To do this, add the openldap user to the ssl-cert group and then ensure the certs and key are owned by the ssl-cert group. Remember that the directory /etc/ssl/private has strict permissions on it so you need to get this right.

adduser openldap ssl-cert
chgrp /etc/ssl/private/ldap-ca-key.pem

STEP TWO

Create a suitable ssl.ldif file for importing into the configuration database. It’s worth saying at this point that the ones I’ve seen online have all had syntax errors in that have prevented them from working – and they fail silently which makes you think they have worked! Note especially that the hyphens are syntactically important.

dn: cn=config
changetype: modify
add: olcTLSCipherSuite
olcTLSCipherSuite: NORMAL
-
add: olcTLSCRLCheck
olcTLSCRLCheck: none
-
add: olcTLSVerifyClient
olcTLSVerifyClient: never
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/ldap-ca-cert.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/ldap-ca-key.pem

WARNING: Don’t be clever and change the TLSCipherSuite to something clever like HIGH:MEDIUM:-SSLv2 – this is an openssl directive and you will now find that you can’t restart slapd as it will fail on startup :-( To diagnose this, try starting slapd with the following command;

slapd -d 16383

If you do this, you will probably see the following;

TLS: could not set cipher list HIGH:MEDIUM:+SSLv2.
main: TLS init def ctx failed: -1

You can fix this by editing /etc/ldap/slapd.d/cn=config.ldif directly if you are careful.

STEP THREE

Import the ssl.ldif file and be aware of what you should see when it works, as opposed to what you will see when it doesn’t. Also be aware that if you are running this multiple times, you need to change the add to replace in the ssl.ldif file.

ldapmodify -Y EXTERNAL -H ldapi:/// -f ssl.ldif -v

The -v gives you a verbose output. Make sure that you see the new entries being printed out, if it just says something like;

modifying entry "cn=config"
modify complete

Then this DOES NOT mean it has worked. It quite likely means it hasn’t processed the file because of errors and no changes will actually have been made. You need to see it list the entries it has modified. For example, this is a working version (using replace, not add)

SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
replace olcTLSCipherSuite:
NORMAL
replace olcTLSCRLCheck:
none
replace olcTLSVerifyClient:
never
replace olcTLSCertificateFile:
/etc/ssl/certs/ldap2-ca-cert.pem
replace olcTLSCertificateKeyFile:
/etc/ssl/private/ldap2-ca-key.pem
modifying entry "cn=config"
modify complete

STEP FOUR

Ensure that slapd listens for ldaps:// connections We’re off to edit a file again (is anyone else thinking that using cn=config is causing more hassles than it solves?), this time we need to edit /etc/default/slapd and change the SLAPD_SERVICES line so that it has the ldaps:/// entry as shown here;

SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"

STEP FIVE

Fix the untrusted certificate problem. You’d think we’d be done by now, but it turns out there is one configuration in another file that is really important. If you try to connect now, using a command line that binds to the ldap server such as this;

ldapsearch -d 9 -D “cn=admin,dc=mydomain,dc=com” -w adminpassword -b “dc=mydomain,dc=com” -H “ldaps://mydomain.com” “objectClass=*”

You will probably get;

TLS: peer cert untrusted or revoked (0x42)
TLS: can't connect: (unknown error code).
ldap_err2string
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)

To resolve this, edit the file /etc/ldap/ldap.conf (note that this is not the slapd.conf file – it can be a bit confusing) and add the single line below to what is probably a completely commented out file; TLS_REQCERT never

Now it should work!