Próbowałem użyć Python-LDAP (wersja 2.4.19) pod MacOS X 10.9.5 i Python 2.7.9Jak wymusić Python LDAP, aby potwierdzić/zweryfikować certyfikat SSL podczas korzystania .start_tls_s()
Chcę sprawdzić poprawność połączenia z danym serwerem LDAP po tym, jak zadzwoniłem pod numer .start_tls_s()
(lub aby metoda była podnoszona i wyjątkowa, jeśli certyfikat nie może zostać zweryfikowany). (Chciałbym też sprawdzić CRL, ale to już inna sprawa).
Oto mój kod:
#!python
#!/usr/bin/env python
import ConfigParser, os, sys
import ldap
CACERTFILE='./ca_ldap.bad'
## CACERTFILE='./ca_ldap.crt'
config = ConfigParser.ConfigParser()
config.read(os.path.expanduser('~/.ssh/creds.ini'))
uid = config.get('LDAP', 'uid')
pwd = config.get('LDAP', 'pwd')
svr = config.get('LDAP', 'svr')
bdn = config.get('LDAP', 'bdn')
ld = ldap.initialize(svr)
ld.protocol_version=ldap.VERSION3
ld.set_option(ldap.OPT_DEBUG_LEVEL, 255)
ld.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
ld.set_option(ldap.OPT_X_TLS_CACERTFILE, CACERTFILE)
ld.set_option(ldap.OPT_X_TLS_DEMAND, True)
ld.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_HARD)
## From: https://stackoverflow.com/a/7810308/149076
## and : http://python-ldap.cvs.sourceforge.net/viewvc/python-ldap/python-ldap/Demo/initialize.py?revision=1.14&view=markup
ld.start_tls_s()
for each in dir(ldap):
if 'OPT_X_TLS' in each:
try:
print '\t*** %s: %s' % (each, ld.get_option((getattr(ldap, each))))
except Exception, e:
print >> sys.stderr, '... Except %s: %s\n' % (each, e)
ld.simple_bind_s(uid, pwd)
results = ld.search_s(bdn, ldap.SCOPE_SUBTREE)
print 'Found %s entries under %s' % (len(results), bdn)
sys.exit()
Jak zauważył w komentarzach mam skopiowanych większość to od https://stackoverflow.com/a/7810308/149076 iz http://python-ldap.cvs.sourceforge.net/viewvc/python-ldap/python-ldap/Demo/initialize.py?revision=1.14&view=markup ... chociaż próbowałem wiele odmian i sekwencje z tego.
Jak widać mam dwa pliki, które stanowią świadectwo złe i jeden, który powinien działać (to faktycznie pochodzi z jednego z naszych systemów, które są skonfigurowane do uruchamiania sssd (System Usług Bezpieczeństwa Daemon), który uznaje się za sprawdzanie tego poprawnie:
W "złym" egzemplarzu po prostu zastąpiłem pierwszy znak każdej linii kluczowej literą "x" przy założeniu, że spowoduje to uszkodzenie klucza CA i spowoduje, że kod spróbuje zweryfikować łańcuch sygnatury do niepowodzenia:
Wydaje się jednak, że kod LDAP w języku Python ignoruje to, nawet jeśli ustawię go na /dev/null
lub całkowicie fałszywa ścieżka, którą mój kod nadal działa, nadal wiąże się z serwerem LDAP i wciąż wykonuje moją prośbę wyszukiwania.
Więc pytanie brzmi, jak mogę dostać tego na „nie” w sposób zamierzony (lub, bardziej ogólnie, w jaki sposób mogę zapobiec wyświetlaniu mojej kod jest podatny na MiTM (Mallory) ataki?
Jeśli to którejkolwiek konsekwencją tej dyskusji oto moja wersja OpenSSL:
$ openssl version
OpenSSL 0.9.8za 5 Jun 2014
serwer LDAP jest uruchomiony OpenLDAP, ale nie znam żadnych szczegółów na temat jego wersji ani konfiguracji
Oto próba wyjścia z mojego kodu.
*** OPT_X_TLS: 0
*** OPT_X_TLS_ALLOW: 0
*** OPT_X_TLS_CACERTDIR: None
*** OPT_X_TLS_CACERTFILE: /bogus/null
*** OPT_X_TLS_CERTFILE: None
*** OPT_X_TLS_CIPHER_SUITE: None
*** OPT_X_TLS_CRLCHECK: 0
*** OPT_X_TLS_CRLFILE: None
*** OPT_X_TLS_CRL_ALL: 1
*** OPT_X_TLS_CRL_NONE: {'info_version': 1, 'extensions': ('X_OPENLDAP', 'THREAD_SAFE', 'SESSION_THREAD_SAFE', 'OPERATION_THREAD_SAFE', 'X_OPENLDAP_THREAD_SAFE'), 'vendor_version': 20428, 'protocol_version': 3, 'vendor_name': 'OpenLDAP', 'api_version': 3001}
*** OPT_X_TLS_CRL_PEER: 3
... Except OPT_X_TLS_CTX: unknown option 24577
*** OPT_X_TLS_DEMAND: 1
*** OPT_X_TLS_DHFILE: None
*** OPT_X_TLS_HARD: 3
*** OPT_X_TLS_KEYFILE: None
*** OPT_X_TLS_NEVER: {'info_version': 1, 'extensions': ('X_OPENLDAP', 'THREAD_SAFE', 'SESSION_THREAD_SAFE', 'OPERATION_THREAD_SAFE', 'X_OPENLDAP_THREAD_SAFE'), 'vendor_version': 20428, 'protocol_version': 3, 'vendor_name': 'OpenLDAP', 'api_version': 3001}
... Except OPT_X_TLS_NEWCTX: unknown option 24591
*** OPT_X_TLS_PACKAGE: OpenSSL
*** OPT_X_TLS_PROTOCOL_MIN: 0
*** OPT_X_TLS_RANDOM_FILE: None
*** OPT_X_TLS_REQUIRE_CERT: 1
*** OPT_X_TLS_TRY: 0
Found 883 entries under [... redacted ...]
* "Chciałbym również sprawdzić CRL, ale to już inna sprawa" * - uważaj na to. Możesz ustawić się na DoS z powodu brakujących/uszkodzonych list CRL i respondentów OCSP. Mozilla wyłączyła go na jakiś czas, ponieważ miała tak negatywny wpływ na wygodę użytkownika. Zszyte odpowiedzi byłyby prawdopodobnie drogą do zrobienia. – jww
W moim przypadku będzie działać w środowisku, które zapewnia własny urząd certyfikacji i zarządza własnymi listami CRL. To wszystko jest wewnętrzne. –
Mogę być nośnikiem złych wiadomości ... Python-LDAP może korzystać z OpenSSL. Jednak połączenia zwykle używane lub spotykane w celu obsługi certyfikatów nie są obecne. Na przykład otrzymuję 0 trafień dla 'cd python-ldap; grep -R -i ca_certs *; grep -R -i wrap_socket *; grep -R -i certs_reqs * '. Możesz skontaktować się z programistami, aby zobaczyć ich pozycję. Mogą oni powiedzieć coś w stylu "kod ma być uruchamiany na tej samej granicy bezpieczeństwa co serwer LDAP, więc używamy certyfikatu dla poufności, ale nie weryfikujemy serwera ani nie stosujemy uwierzytelniania serwera, ponieważ nie ma aktywnego MitM". – jww