11

Nel appserver AppEngine sviluppatore sto ottenendo un errore come questo:AppEngine UrlFetch validate_certificate = non False/Nessuno viene rispettato

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

avanti nel processo di un'operazione di recupero come questo a un server https con un auto-firmato certificato (quasi sempre localhost porta-inoltrato tramite ssh ad una VM):

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

uno non si aspetterebbe fallimenti SSL per certificati non validi in cui validate_certificate è False, anche se questo è abbastanza probabilmente un effetto collaterale della politica 2.7.9 in Python per convalidare sempre i certificati ssl.

Nota che passare False (anziché None) per validate_certificate non funziona.

Questo problema si verifica in Python 2.7.9-10 tramite Homebrew/XCode su OS X 10.10.2-4 con AppEngine 1.9.18 fino a 1.19.26.

Ci sono problemi (ad esempio 12096) su questo su Google App Engine, ma sto cercando una soluzione alternativa.

Qui è quello che ho cercato di ovviare a questo:

  1. aggiungere il certificato al portachiavi di login del Mac (opere nel browser, non da Python)

  2. aggiungere il certificato app-engine-python/lib/cacerts/cacerts.txt e/o ./lib/cacerts/urlfetch_cacerts.txt (anche se probabilmente è necessario attivare la verifica su affinché funzioni, poiché sembra essere l'unico caso in cui vengono utilizzati) ad es.

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

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

  3. Disable HTTPS SSL controllo con la soluzione PEP-0476 cioè

    ssl._create_default_https_context = ssl._create_unverified_context

    o dopo import ssl (intorno alla linea 1149) di google/appengine/dist27/python_std_lib/httplib.py

Ciò è particolarmente problematico su Mac dal declassamento come di XCode 7/OS X El Capitale non è più una soluzione pratica.

Una soluzione alternativa preferibile non prevede il patching delle scimmie del codice AppEngine corretto ogni volta che viene aggiornato il server di sviluppo.


EDIT

Nota che i certificati di OpenSSL Mac built sono memorizzati in /System/Library/OpenSSL, che è protetta con SIP/rootlessness, che francamente è un dolore per muck con e una funzione utile per mantenere se possiamo.

Ho verificato che il certificato convalida utilizzando openssl s_client -connect localhost:7500 -CAfile server.pem.

E 'stato aggiunto al portachiavi e /usr/local/etc/openssl/certs con il formato hash.# dove l'hash viene da openssl x509 -subject_hash -in server.pem (o SSL homebrew, cioè /usr/local/Cellar/openssl/1.0.2d_1/bin/openssl). Nel qual caso /usr/local/Cellar/openssl/1.0.2d_1/bin/openssl s_client -connect localhost:7500 verifica il certificato (ma Python continua a non farlo).

Ho provato a utilizzare la versione homebrew di python e openssl, ma senza successo. L'esecuzione di quanto segue in Python sembra fallire sempre;

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

questo viene a mancare anche il luogo dove SSL_CERT_FILE è impostato per il certificato del server (vale a dire per la misura una aggiunto potrebbe aspettarsi che funzioni in quanto il comando openssl funziona essenzialmente come questo), e anche non dove SSL_CERT_PATH è impostato su /usr/local/etc/openssl/certs.

nota, pve è un env virtuale dove help(ssl) mostra un FILE di /usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py

Ulteriori verificando che homebrew di Python _ssl.so collegamenti per homebrew di OpenSSL mi sono imbattuto:

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

che restituisce

012.351.641.061.

./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 (versione di compatibilità 1.0.0, versione corrente 1.0.0)

/usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib (versione di compatibilità 1.0. 0, versione corrente 1.0.0)

/usr/lib/libSystem.B.dylib (compatibilità versione 1.0.0, corrente versione 1225.1.1)

.210

Se si corre brew info openssl esso note poste CAVEATS:

Un file di CA è stato bootstrap usando certificati dal sistema portachiavi. Per aggiungere ulteriori certificati, inserire i file .pem in /usr/local/etc/openssl/certs

ma è chiaro che per qualche motivo non è python utilizzando l'algoritmo di OpenSSL homebrew per la ricerca di certificati.

Così mi rimangono in perdita per i certificati perché Python libreria standard non è la convalida che si trovano nella directory OpenSSL specificata nei documenti così come il portachiavi (in entrambi i formati .pem e .p12, con "sempre fiducia" per Secure Sockets Layer (SSL)).

risposta

8

Questo è un bug dev_appserver causato da un cambiamento di comportamento httplib.HTTPSConnection (controllo certificato attivato per impostazione predefinita) in qualche recente rilascio di Python (credo 2.7.9).

Poiché il bug si trova nel codice interno dev_appserver (file google_appengine/google/appengine/api/urlfetch_stub.py del kit SDK appengine) che viene eseguito indipendentemente dall'applicazione testata, non c'è modo di creare una correzione che sopravviverà a un aggiornamento SDK.

L'unica soluzione permanente mi viene in mente è quello di consentire validate_certificate e aggiungere CA certificato nel file urlfetch_cacerts.txt. Come correzione temporanea, puoi correggere urlfetch_stub.py con il metodo # 3.

+0

Grazie @Alex. Se non fosse possibile aggiungere il certificato al sistema del Mac, allora Httplib di Python utilizzerà? –

+0

Brian, non ho molta familiarità con il modo in cui Python ssl lib funziona su Mac, vorrei controllare [ssl doc page] (https://docs.python.org/2/library/ssl.html#ssl-contexts) e vedere qual è la stringa di percorso predefinita: 'ssl.get_default_verify_paths()'. Può esserci un modo per usare [variabile env per impostare un percorso per il tuo file certificato] (https://www.python.org/dev/peps/pep-0476/#trust-database). – Alex

+0

[Questo è il documento pertinente] (http://gagravarr.org/writing/openssl-certs/others.shtml) su come aggiungere un certificato autofirmato per openssl. – Alex

1

Ho riscontrato lo stesso problema su Windows. Stavo usando una vecchia versione di Python (2.7). Quando ho aggiornato a Python 2.7.11, il problema è andato via.

Problemi correlati