La versione 2.7
della libreria SSL Python è stata deprecata.
Utilizza invece l'ultima versione, che attualmente è 2.7.11
.
App Engine supporta la libreria SSL Python nativa per il runtime Python 2.7 tramite la libreria SSL, che devi aggiungere alla tua app.
Specifica della libreria SSL
Se vuoi utilizzare SSL Python nativo, devi abilitarlo specificando ssl
per
la configurazione libraries
nel app.yaml
dell'applicazione. Dovresti utilizzare la versione più recente della libreria, attualmente la versione 2.7.11. Questa versione supporta le versioni TLS 1.0, 1.1 e 1.2 e corrisponde alle versioni SSL da Python 2.7.11 e successive:
libraries:
- name: ssl
version: latest
Fornitura dei certificati di autorità
Per eseguire un handshake SSL, devi avere un file contenente certificati dell'autorità di certificazione concatenati. Puoi caricare il tuo file con la tua applicazione oppure utilizzare il file fornito da App Engine: /etc/ca-certificates.crt
.
Esecuzione di un handshake SSL
Il metodo wrap_socket
Python 2.7 accetta due parametri dei nomi file che contengono la chiave e il certificato del client. Nell'ambiente App Engine, questo è un limite poiché l'applicazione non è in grado di scrivere file per fornire in modo dinamico chiavi e certificati diversi. Per aggirare questa limitazione, i parametri certfile
e keyfile
per il metodo ssl.wrap_socket
possono essere oggetti "simili a file" che consentono all'applicazione di archiviare certificati e chiavi in modi diversi dai file dell'applicazione appena caricati. Un oggetto "simile a un file" ha un metodo "lettura" che restituisce l'intero certificato sotto forma di stringa.
# Example of a dynamic key and cert.
datastore_record_k = ndb.Key('Employee', 'asalieri', 'Address', 1)
datastore_record = datastore_record_k.get()
key_str = datastore_record.key_str
cert_str = datastore_record.cert
ssl_server = ssl.wrap_socket(server_sock,
server_side=False,
keyfile=StringIO.StringIO(key_str),
certfile=StringIO.StringIO(cert_str),
cert_reqs=ssl.CERT_REQUIRED,
ssl_version=ssl.PROTOCOL_SSLv23,
ca_certs=CERTIFICATE_FILE)
Non è necessario specificare il parametro ssl_version
. Se lo ometti, la libreria 2.7.11 viene impostata in modo predefinito su PROTOCOL_SSLv23
. Puoi anche specificare
PROTOCOL_TLSv1
, PROTOCOL_TLSv1_1
o PROTOCOL_TLSv1_2
.
L'implementazione App Engine del metodo wrap_socket
include il parametro obbligatorio ca_certs
, utilizzato per specificare il file speciale contenente i certificati dell'autorità di certificazione concatenati.
Convalida dei certificati in corso...
L'app deve convalidare i certificati per evitare determinate vulnerabilità di sicurezza, ad esempio attacchi man in the middle.
Per farlo:
Modifica il file
app.yaml
, aggiungendo la variabile di ambientePYTHONHTTPSVERIFY
impostata su1
:env_variables: PYTHONHTTPSVERIFY: 1
Esegui nuovamente il deployment dell'app.
In alternativa a specificare la convalida del certificato in app.yaml
, puoi chiamare esplicitamente la libreria SSL per eseguire la convalida, dopo aver eseguito un handshake SSL riuscito, come segue:
ssl.match_hostname(ssl_server.getpeercert(), 'a.hostname.com')
Il codice riportato sopra utilizza la funzionalità match_hostname
, di cui è stato eseguito il backporting da Python 3.2 per far parte del modulo SSL Python 2.7.11 di App Engine. Questa chiamata assicura che il certificato fornito dal peer corrisponda a uno degli host designati nel certificato del peer.
Utilizzo di dev_appserver
Puoi inviare richieste HTTPS utilizzando l'API urlfetch. Il comportamento di convalida dei certificati di Dev_server utilizzando httplib
con urlfetch è identico all'ambiente di produzione di App Engine. Dev_appserver
non supporta le richieste che utilizzano socket.