La versione 2.7
della libreria SSL di Python è stata ritirata.
Utilizza invece la versione più recente, attualmente 2.7.11
.
App Engine supporta la libreria SSL di 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 attivarlo specificando ssl
per la configurazione libraries
in app.yaml
dell'applicazione. Devi 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 a partire da Python 2.7.11:
libraries:
- name: ssl
version: latest
Fornire certificati delle autorità
Per eseguire un handshake SSL, devi avere un file contenente certificati delle autorità di certificazione concatenati. Puoi caricare il tuo file con l'applicazione oppure utilizzare il file fornito da App Engine: /etc/ca-certificates.crt
.
Esecuzione di un handshake SSL
Il metodo wrap_socket
di Python 2.7 accetta due parametri di nome file che contengono la chiave e il certificato del client. Nell'ambiente App Engine, questo è limitante poiché 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 file dell'applicazione caricati. Un oggetto "simile a un file" è un oggetto che ha 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 la ometti, la libreria 2.7.11 assume per impostazione predefinita il valore 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 delle autorità di certificazione concatenati.
Convalida dei certificati
L'app deve convalidare i certificati per evitare determinate vulnerabilità di sicurezza, come gli 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
, riportata da Python 3.2 per far parte del modulo SSL di Python 2.7.11 di App Engine. Questa chiamata garantisce che il certificato fornito dal peer corrisponda a uno degli host designati nel certificato del peer.
Lavoro su dev_appserver
Puoi emettere richieste HTTPS utilizzando l'API urlfetch. Il comportamento di convalida del certificato di Dev_server che utilizza httplib
con urlfetch è identico a quello dell'ambiente App Engine di produzione. Dev_appserver
non supporta le richieste che utilizzano socket.