A versão 2.7
da biblioteca SSL Python foi descontinuada.
Em alternativa, use a versão mais recente, atualmente 2.7.11
.
O App Engine suporta a biblioteca SSL Python nativa para o tempo de execução do Python 2.7 através da biblioteca SSL, que tem de adicionar à sua app.
Especificar a biblioteca SSL
Se quiser usar o SSL Python nativo, tem de o ativar especificando ssl
para a configuração libraries
no app.yaml
da sua aplicação. Deve usar a versão mais recente da biblioteca, que é atualmente a versão 2.7.11. Esta versão suporta as versões 1.0, 1.1 e 1.2 do TLS e corresponde às versões SSL do Python 2.7.11 e posteriores:
libraries:
- name: ssl
version: latest
Fornecer certificados de autoridade
Para realizar um handshake SSL, tem de ter um ficheiro que contenha
certificados de autoridade de certificação concatenados. Pode
carregar o seu próprio ficheiro com a sua aplicação ou usar o
ficheiro fornecido pelo App Engine: /etc/ca-certificates.crt
.
Realizar um handshake SSL
O método wrap_socket
do Python 2.7 usa dois parâmetros de nome de ficheiro que contêm a chave e o certificado do cliente. No ambiente do App Engine, isto é limitativo, uma vez que a aplicação não consegue escrever ficheiros para fornecer dinamicamente diferentes chaves e certificados. Para contornar esta limitação, os parâmetros certfile
e keyfile
para o método ssl.wrap_socket
podem ser objetos "semelhantes a ficheiros" que permitem à aplicação armazenar certificados e chaves de outras formas que não apenas em ficheiros de aplicações carregados. (Um objeto "semelhante a um ficheiro" é um objeto que tem um método "read" que devolve o certificado completo como uma string.)
# 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)
Não precisa de especificar o parâmetro ssl_version
. Se o omitir, a biblioteca 2.7.11 é predefinida como PROTOCOL_SSLv23
. Também pode especificar PROTOCOL_TLSv1
, PROTOCOL_TLSv1_1
ou PROTOCOL_TLSv1_2
.
A implementação do App Engine do método wrap_socket
inclui o parâmetro obrigatório ca_certs
, que é usado para especificar o ficheiro especial que contém certificados de autoridade de certificação concatenados.
Validar certificados
A sua app deve validar os certificados para evitar determinadas vulnerabilidades de segurança como ataques do tipo "man-in-the-middle".
Para o fazer:
Edite o ficheiro
app.yaml
, adicionando a variável de ambientePYTHONHTTPSVERIFY
definida como1
:env_variables: PYTHONHTTPSVERIFY: 1
Volte a implementar a sua app.
Em alternativa à especificação da validação de certificados no seu app.yaml
, pode chamar explicitamente a biblioteca SSL para fazer a validação, depois de ter realizado uma
negociação SSL bem-sucedida, da seguinte forma:
ssl.match_hostname(ssl_server.getpeercert(), 'a.hostname.com')
O código acima usa a funcionalidade match_hostname
, com portabilidade inversa do Python 3.2 para fazer parte do módulo SSL do Python 2.7.11 do App Engine. Esta chamada garante que o certificado fornecido pelo par corresponde a um dos anfitriões designados no certificado do par.
Trabalhar no dev_appserver
Pode emitir pedidos HTTPS através da API urlfetch. O comportamento de validação de certificados do servidor de desenvolvimento através de httplib
com urlfetch é idêntico ao do ambiente de produção do App Engine. O dev_appserver não suporta pedidos que usem sockets.