OpenLDAP – Fixing ‘Connection Lost’ Error with SSL

lets-encryptopenldapopensslssl

I have OpenLDAP 2.4.50 installed on a Alpine 3.8 system, and two Debian 10 clients – let us call them A and B – trying to connect the ldap server. My problem is that the first can and the second cannot.

A and B are identical machines, with both up-to-date Debian 10. Client A can connect the ldap server with ldapsearch -x -b "dc=mydomain,dc=tld" -H ldaps://ldap.mydomain.tld/, but client B fails. Here is what the server shows when client B tries to connect:

Jul 16 12:46:39 reglisse local4.debug slapd[17451]: conn=1132 fd=22 ACCEPT from IP=xxx.xxx.xxx.xxx:45444 (IP=0.0.0.0:636)
Jul 16 12:46:39 reglisse local4.debug slapd[17451]: conn=1132 fd=22 TLS established tls_ssf=256 ssf=256
Jul 16 12:46:39 reglisse local4.debug slapd[17451]: conn=1132 fd=22 closed (connection lost)
  • The server certificate has been built with certbot.
  • Both client A and client B can successfully read the ldap database in plain ldap (without SSL) with ldapsearch -x -b "dc=mydomain,dc=tld" -H ldap://ldap.mydomain.tld/ -v. This should prove that there is no network issue, and that the server correctly listens to the port 389.
  • Both client A and client B can successfully connect to the ldaps port with openssl s_client -connect ldap.mydomain.tld:636 -showcerts. This should prove that the server correctly listen to the port 636.
  • Both client A and client B have the same ldap-utils package version installed, and ldd /usr/bin/ldapsearch shows that both binaries are built against the very same libraries. This should prove that both clients are identical.
  • The server slapd.conf has absolutely nothing fancy:

 

suffix dc=mydomain,dc=tld
rootdn cn=admin,dc=mydomain,dc=tld
rootpw "xxxxxxxxxxx"
TLSCertificateKeyFile /etc/openldap/certs/privkey.pem
TLSCACertificateFile /etc/openldap/certs/fullchain.pem
TLSCertificateFile /etc/openldap/certs/cert.pem
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/inetorgperson.schema

So, what am I doing wrong here?

Best Answer

I discovered that ldapsearch has a -d option that shows intersting things:

$ ldapsearch -x -b "dc=mydomain,dc=tld" -H ldaps://ldap.mydomain.tld/ -v -d1
ldap_url_parse_ext(ldaps://ldap.mydomain.tld/)
ldap_initialize( ldaps://ldap.mydomain.tld:636/??base )
ldap_create
ldap_url_parse_ext(ldaps://ldap.mydomain.tld:636/??base)
ldap_sasl_bind
ldap_send_initial_request
ldap_new_connection 1 1 0
ldap_int_open_connection
ldap_connect_to_host: TCP ldap.mydomain.tld:636
ldap_new_socket: 3
ldap_prepare_socket: 3
ldap_connect_to_host: Trying 45.67.80.98:636
ldap_pvt_connect: fd: 3 tm: -1 async: 0
attempting to connect:
connect success
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)

So it seems that the server ldap certificate is not trusted by client B. To fix this issue, I had to set the following line in /etc/ldap/ldap.conf.

TLS_CACERT  /etc/ssl/certs/ca-certificates.crt

Some people could solve similar issues with:

TLS_REQCERT allow

/etc/ldap/ldap.conf seems to be the configuration file that most ldap clients use. Client A already had this file, this is why it worked for it.