LDAP connection problem with self-signed cert

Question:

The code I am using:

# Create LDAPObject instance
conn = ldap.initialize(url)
conn.protocol_version=ldap.VERSION3

conn.simple_bind_s(binddn,bindpw)
# This raises:
# ldap.SERVER_DOWN: 
    {'info': 'error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed', 'desc': "Can't contact LDAP server"}

When I use ldap:// instead of ldaps://, it works correctly.

Can anybody help me figure out why this is?

Thanks. 🙂

Asked By: user290043

||

Answers:

I’ve never used python-ldap over SSL but I believe you have to tell ldap what checks to perform on the server certificate. If this is set to demand (which might be the default), you have to give it valid certs.

See the initialize.py in the Demo directory the source.

Answered By: Mark

I came here looking for a solution to my problem related to this. This Q&A did not solve my exact problem, but others looking for my exact problem’s solution will find the following useful:

For those using SSL/TLS for basic transport encryption and not identity verification (self-signed certificates), you just turn off strict checking of the server certificate:

ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)

This is roughly analogous to setting the OpenLDAP 2.1+ client setting:

tls_checkpeer no
Answered By: jblaine

Try to pass the following environment variable:

LDAPTLS_REQCERT=never

to ignore server certificate which could be expired or invalid.

See:

Answered By: kenorb

to ignore certificate errors

ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
Answered By: navendu

PAY much attention to your protocol and port in your connection string:

Using TLS with python-ldap:

# TLS uses string uri 'ldaP://' (NO 's')
# then the method start_tls_s() will transfer to a secure connection
l = ldap.initialize('ldap://localhost:1390',trace_level=ldapmodule_trace_level,trace_file=ldapmodule_trace_file)

# Set LDAP protocol version used
l.protocol_version=ldap.VERSION3

# Force cert validation
l.set_option(ldap.OPT_X_TLS_REQUIRE_CERT,ldap.OPT_X_TLS_DEMAND)
# Set path name of file containing all trusted CA certificates
l.set_option(ldap.OPT_X_TLS_CACERTFILE,CACERTFILE)
# Force libldap to create a new SSL context (must be last TLS option!)
l.set_option(ldap.OPT_X_TLS_NEWCTX,0)

# Now try StartTLS extended operation
l.start_tls_s()

print('***ldap.OPT_X_TLS_VERSION',l.get_option(ldap.OPT_X_TLS_VERSION))
print('***ldap.OPT_X_TLS_CIPHER',l.get_option(ldap.OPT_X_TLS_CIPHER))

# Try an explicit anon bind to provoke failure
l.simple_bind_s('','')

# Close connection
l.unbind_s()

SSL uses ‘ldapS://’ directly!

And it doesn’t use the start_tls_s()

# Create LDAPObject instance
l = ldap.initialize('ldaps://localhost:1391',trace_level=ldapmodule_trace_level,trace_file=ldapmodule_trace_file)

# Set LDAP protocol version used
l.protocol_version=ldap.VERSION3

# Force cert validation
l.set_option(ldap.OPT_X_TLS_REQUIRE_CERT,ldap.OPT_X_TLS_DEMAND)
# Set path name of file containing all trusted CA certificates
l.set_option(ldap.OPT_X_TLS_CACERTFILE,CACERTFILE)
# Force libldap to create a new SSL context (must be last TLS option!)
l.set_option(ldap.OPT_X_TLS_NEWCTX,0)

# Try an explicit anon bind to provoke failure
l.simple_bind_s('','')

print('***ldap.OPT_X_TLS_VERSION',l.get_option(ldap.OPT_X_TLS_VERSION))
print('***ldap.OPT_X_TLS_CIPHER',l.get_option(ldap.OPT_X_TLS_CIPHER))

# Close connection
l.unbind_s()

source: original developers github demo initialize.py

Answered By: Rafael Gramoschi
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.