Utilizzo di Python SSL

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 il protocollo SSL Python nativo, devi abilitarlo specificando ssl per della configurazione libraries nel file 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 i certificati delle autorità

Per eseguire un handshake SSL, devi avere un file che contenga certificati dell'autorità di certificazione concatenati. Puoi caricare il tuo file con la tua applicazione oppure utilizzare 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 perché l'applicazione non è in grado di scrivere file per fornire dinamicamente chiavi e certificati diversi. Per aggirare il problema limitazione, i parametri certfile e keyfile il metodo ssl.wrap_socket può essere "file-like" che consentono per archiviare certificati e chiavi in altri modi di 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

La tua app deve convalidare i certificati per evitare che vulnerabilità di sicurezza come "uomo in mezzo" attacchi informatici.

Per farlo:

  1. Modifica il file app.yaml aggiungendo la variabile di ambiente PYTHONHTTPSVERIFY impostata su 1:

     env_variables:
       PYTHONHTTPSVERIFY: 1
    
  2. 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 backport da Python 3.2 per farla parte del modulo SSL di Python 2.7.11 di App Engine. Questa chiamata assicura che fornito dal peer corrisponde a uno degli host designati in certificato del peer.

Lavorare 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.