user290043
user290043

Reputation:

LDAP connection problem with self-signed cert

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. :)

Upvotes: 15

Views: 27705

Answers (5)

Rafael Gramoschi
Rafael Gramoschi

Reputation: 116

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

Upvotes: 0

Mark
Mark

Reputation: 108567

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.

Upvotes: 7

navendu
navendu

Reputation: 274

to ignore certificate errors

ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)

Upvotes: 13

kenorb
kenorb

Reputation: 166871

Try to pass the following environment variable:

LDAPTLS_REQCERT=never

to ignore server certificate which could be expired or invalid.

See:

Upvotes: 2

jblaine
jblaine

Reputation: 530

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

Upvotes: 30

Related Questions