11

W appserver AppEngine dewelopera ja otrzymuję błąd jak poniżej:AppEngine UrlFetch validate_certificate = False/Nikt nie jest przestrzegana

SSLCertificateError: Invalid and/or missing SSL certificate for URL ... 

gdy Robię sprowadzić tak aby serwer https z podpisem własnym certyfikat (prawie zawsze localhost portu przekazane przez ssh do VM):

result = urlfetch.fetch(url=url, method=method, payload=payload, 
         deadline=DEADLINE, validate_certificate=None) 

nie spodziewałbym awarie nieważnych certyfikatów SSL gdzie validate_certificate jest False, choć jest to dość być może efektem ubocznym polityki 2.7.9 w Pythonie, aby zawsze sprawdzać certyfikaty SSL.

Należy pamiętać, że podanie False (zamiast None) dla validate_certificate również nie działa.

Ten problem występuje w języku Python 2.7.9-10 przez Homebrew/XCode na OS X 10.10.2-4 z AppEngine 1.9.18 do 1.19.26.

Istnieją problemy (na przykład: 12096) dotyczące tego mechanizmu Google App Engine, ale szukam obejścia.

Oto, co starałem się obejść:

  1. Dodaj certyfikat do Mac logowania pęku kluczy (działa w przeglądarce, a nie z Pythona)

  2. Dodaj certyfikat do app-engine-python/lib/cacerts/cacerts.txt i/lub ./lib/cacerts/urlfetch_cacerts.txt (chociaż prawdopodobnie wymaga to weryfikacji na, aby działało, ponieważ wydaje się, że jest to jedyny przypadek, w którym są używane) z np.

    $ echo >> /usr/local/share/app-engine-python/lib/cacerts/urlfetch_cacerts.txt

    $ openssl x509 -subject -in server.crt >>/usr/local /share/app-engine-python/lib/cacerts/urlfetch_cacerts.txt

  3. Wyłącz HTTPS SSL sprawdzianów z PEP-0476 obejście tj

    ssl._create_default_https_context = ssl._create_unverified_context

    przy lub po import ssl (około 1149 linii) z google/appengine/dist27/python_std_lib/httplib.py

Jest to szczególnie problematyczne na Mac od obniżamy jak z XCode 7/Mac OS X El Capital nie jest praktycznym rozwiązaniem.

Preferowanym sposobem obejścia tego problemu nie jest poprawianie poprawnego kodu AppEngine za każdym razem, gdy aktualizowany jest appserver.


EDIT

Należy pamiętać, że Mac wbudowane certyfikaty OpenSSL są przechowywane w /System/Library/OpenSSL, która jest zabezpieczona SIP/rootlessness, który szczerze to ból syf z i wartościowym elementem do utrzymania, jeśli możemy.

Po sprawdzeniu poprawności certyfikatu za pomocą openssl s_client -connect localhost:7500 -CAfile server.pem.

To zostało dodane do pęku kluczy i /usr/local/etc/openssl/certs z formatem hash.# gdzie hash pochodzi openssl x509 -subject_hash -in server.pem (lub homebrew SSL mianowicie /usr/local/Cellar/openssl/1.0.2d_1/bin/openssl). W takim przypadku /usr/local/Cellar/openssl/1.0.2d_1/bin/openssl s_client -connect localhost:7500 weryfikuje certyfikat (ale python nadal nie działa).

Próbowałem przy użyciu wersji homebrew Pythona i openssl, ale na próżno. Uruchomienie następujących w Pythonie wydaje się zawsze zawieść;

./pve/bin/python -c "import requests; requests.get('https://localhost:7500')" 

To również nie gdzie SSL_CERT_FILE jest ustawiony na certyfikacie serwera (czyli dla dodanego jednego środka może oczekiwać, że do pracy, ponieważ komenda openssl zasadniczo działa tak), a także nie gdzie SSL_CERT_PATH jest ustawiony na /usr/local/etc/openssl/certs.

Uwaga, pve jest wirtualny env gdzie help(ssl) pokazuje FILE z /usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py

Dalsze sprawdzenie, czy homebrew Pythona _ssl.so linki do homebrew na OpenSSL Pobiegłem:

xcrun otool -L /usr/local/Cellar /python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/_ssl.so

która zwraca

./Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/_ssl.so:

/usr/local/opt/openssl /lib/libssl.1.0.0.dylib (wersja zgodności 1.0.0, aktualna wersja 1.0.0)

/usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib (wersja zgodności 1.0. 0, obecna wersja 1.0.0)

/usr/lib/libSystem.B.dylib (kompatybilność wersji 1.0.0, aktualna wersja 1225.1.1)

Jeśli ktoś biegnie brew info openssl to uwagi pod CAVEATS:

Plik CA została bootstrapped przy użyciu certyfikatów z systemu pęku kluczy. Aby dodać dodatkowe certyfikaty, umieść pliki w .pem/usr/local/etc/openssl/certs

ale wyraźnie z jakiegoś powodu pyton nie używa algorytmu openssl homebrew dla znalezienia certyfikatów.

Więc pozostaje w rozterce, dlaczego Python biblioteki standardowej nie jest potwierdzanie certyfikatów, które znajdują się w katalogu OpenSSL określonym w dokumentach, jak również pęku kluczy (w obu .pem i .p12 formatów, ze „zawsze zaufać” dla Secure Sockets Layer (SSL)).

Odpowiedz

8

To dev_appserver błąd spowodowany przez httplib.HTTPSConnection zmiana zachowania (check certyfikat domyślnie włączona) w pewnym najnowszej wersji Pythona (I belive 2.7.9).

Ponieważ błąd znajduje się w wewnętrznym kodzie dev_appserver (plik google_appengine/google/appengine/api/urlfetch_stub.py pakietu SDK aplikacji), który jest uruchamiany niezależnie od testowanej aplikacji, nie ma sposobu, aby naprawić, która przetrwa aktualizację pakietu SDK.

Jedynym stałym obejście mogę myśleć będzie umożliwienie validate_certificate i dodać Certyfikat CA do pliku urlfetch_cacerts.txt. Jako tymczasową poprawkę możesz załączyć numer urlfetch_stub.py za pomocą obejścia # 3.

+0

Dzięki @Alex. Jeśli nie będzie możliwe dodanie certyfikatu do systemu Macintosha, Httplib tego Pythona będzie wtedy używał? –

+0

Brian, nie bardzo wiem, jak działa Python ssl lib na Macu, sprawdziłbym stronę [ssl doc] (https://docs.python.org/2/library/ssl.html#ssl-contexts) i zobacz, jaki jest domyślny ciąg znaków: 'ssl.get_default_verify_paths()'. Być może istnieje sposób użycia zmiennej [env do ustawienia ścieżki do pliku certyfikatu] (https://www.python.org/dev/peps/pep-0476/#trust-database). – Alex

+0

[Tutaj jest odpowiedni dokument] (http://gagravarr.org/writing/openssl-certs/others.shtml) na temat dodawania samopodpisanego certyfikatu dla openssl. – Alex

1

Wpadłem na ten sam problem w systemie Windows. Używałem starej wersji Pythona (2.7). Po aktualizacji do wersji Python 2.7.11 problem zniknął.