La versione 2.7 della libreria Python SSL è stata
ritirata.
Utilizza invece l'ultima versione, attualmente 2.7.11.
App Engine supporta la libreria Python SSL 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 file app.yaml dell'applicazione. Devi utilizzare
l'ultima versione della libreria, che al momento è
la versione 2.7.11. Questa
versione supporta le versioni TLS 1.0, 1.1 e 1.2 e corrisponde alle versioni SSL
di Python 2.7.11 e successive:
libraries:
- name: ssl
version: latest
Fornire certificati dell'autorità
Per eseguire un handshake SSL, devi disporre di un file contenente i 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 Python 2.7 wrap_socket accetta due parametri del nome file
che contengono la chiave e il certificato del client. Nell'ambiente App Engine, questa limitazione è un problema perché l'applicazione non è in grado di scrivere file per fornire dinamicamente 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 rispetto ai soli file dell'applicazione caricati. Un oggetto "simile a un file" è un oggetto con un metodo "read"
che restituisce l'intero certificato come 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 per impostazione predefinita su PROTOCOL_SSLv23. Puoi anche specificare
PROTOCOL_TLSv1, PROTOCOL_TLSv1_1 o PROTOCOL_TLSv1_2.
L'implementazione di App Engine del metodo wrap_socket include il parametro obbligatorio ca_certs, che viene utilizzato per specificare il file speciale contenente i certificati concatenati dell'autorità di certificazione.
Convalida dei certificati
La tua app deve convalidare i certificati per prevenire determinate vulnerabilità di sicurezza come gli attacchi "man in the middle".
Per farlo:
Modifica il file
app.yamlaggiungendo la variabile di ambientePYTHONHTTPSVERIFYimpostata su1:env_variables: PYTHONHTTPSVERIFY: 1Esegui 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 verifica 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 App Engine. Dev_appserver
non supporta le richieste che utilizzano i socket.