Gunicorn: Adicionar suporte para constantes nomeadas no sinalizador --ssl-version

Criado em 15 set. 2015  ·  37Comentários  ·  Fonte: benoitc/gunicorn

Estou usando o gunicorn com certificado SSL e chave. Ele fornece conexão TLS 1.0. É possível configurar o gunicorn para usar o TLS 1.2?

Improvement Documentation help wanted FeaturSSL - Mailing List -

Todos 37 comentários

Olá @rrajaravi , você tentou definir http://docs.gunicorn.org/en/latest/settings.html#ciphers ?

ressalto

Como determinar se funciona ou não?

podemos encerrar esse problema?

TL; DR
Gunicorn parece apenas suportar:
TLSv1
SSLv2

E não suporta:
SSLv3
SSLv23
TLSv1_1
TLSv1_2

@berkerpeksag Os documentos em http://docs.gunicorn.org/en/latest/settings.html#ciphers não parecem estar corretos.
Encontrei os protocolos em ssl.py. Nenhum deles, exceto TLSv1 e SSLv2, funcionam quando fornecidos em uma opção de linha de comando no Ubuntu 14.04 LTS, Python 3.5.1, OpenSSL 1.0.1f 6 de janeiro de 2014

O resto falha com erro:
[2016-03-22 08:51:49 +0000] [2924] [ERROR] Exceção no processo de trabalho:
Traceback (última chamada mais recente):
Arquivo "/home/me/Envs/myproject/lib/python3.5/site-packages/gunicorn/workers/sync.py", linha 126, no identificador
self.cfg.ssl_options)Arquivo "/usr/local/lib/python3.5/ssl.py", linha 1064, em wrap_socketcifras = cifras)Arquivo "/usr/local/lib/python3.5/ssl.py", linha 690, em ** init
self._context.set_ciphers (ciphers)
ssl.SSLError: ('Nenhuma cifra pode ser selecionada.',)


/usr/local/lib/python3.5/ssl.py
As seguintes constantes identificam várias variantes do protocolo SSL:

PROTOCOL_SSLv2
PROTOCOL_SSLv3
PROTOCOL_SSLv23
PROTOCOL_TLSv1
PROTOCOL_TLSv1_1
PROTOCOL_TLSv1_2

Obrigado por fazer a triagem disso, @edwardotis. Estou reabrindo isso para esclarecer a documentação.

@berkerpeksag também estamos usando o bom padrão?

TLSv1 parece bom para versões mais antigas do Python, mas talvez possamos alterar o valor padrão para SSLv23 para usar o melhor protocolo disponível (para clientes e servidores).

Além disso, acho que devemos levantar uma exceção se SSLv2 ou SSLv3 for usado no Gunicorn 20 (seria ótimo descontinuá-los na próxima versão 19.x).

@berkerpeksag : +1:

Alguém implementou essas mudanças? Se não, eu ficaria feliz em tentar e abrir um PR .. Ser capaz de definir a cifra para algo> TLSv1.0 é importante para nós e pelo que podemos ver, qualquer versão de TLS maior que 1 pode ' t seja definido .. o padrão volta para 1.0 (tentamos os listados na documentação e as constantes listadas aqui sem sucesso) - apenas resulta No cipher can be selected

@AndrewJHart isso seria ótimo! :) Obrigado!

É possível usar outras versões. Você só precisa especificar uma constante para --ssl-version na linha de comando. Essas constantes vêm do módulo ssl stdlib.

$ python -c "import ssl; print(ssl.PROTOCOL_SSLv23)"     
  2
$ python -c "import ssl; print(ssl.PROTOCOL_TLSv1_2)"
  5

Apenas especifique --ssl-version 2 ou --ssl-version 5 e você deverá ter suporte para cifras TLS 1.2.

@AndrewJHart dê uma olhada em # 1440 se você gostaria de contribuir com algumas melhorias para SSL. Devemos mudar para o uso de SSLContext para melhor controle sobre o contexto, como definir a preferência de ordem de cifra do servidor. Vou postar uma diferença sobre esse problema momentaneamente com um exemplo de como começar a implementar isso para o trabalhador de sincronização. Qualquer ajuda para melhorar o suporte SSL seria muito apreciada.

Além disso, uma simples solicitação de pull para alterar o valor padrão em gunicorn / config.py para usar a constante SSLv23 em vez de TLSv1 seria ótimo.

Desculpe, eu quis dizer # 1140

Não entendo por que esse problema foi reaberto. Testei o Gunicorn com --ssl-version 2 e descobri que as cifras TLS 1.2 funcionam bem.

Vou encerrar, mas reabra e explique se você acha que fiz isso por engano.

Abri # 1249 para rastrear a alteração do padrão.

Eu o reabri porque:

a) Os usuários devem ser capazes de passar 'SSLv23' ou 'TLSv1_2' vez de 2 ou 5 .
b) Devemos documentar as opções disponíveis em vez de redirecioná-las para documentos Python. https://docs.python.org/3.5/library/ssl.html é um dos documentos mais longos do stdlib e os usuários não devem perder muito tempo apenas para ver quais opções estão disponíveis.

Reaberto, adicionando as etiquetas de documentação.

deixe-me saber o que é necessário aqui, se pudermos fechá-lo antes de um lançamento 19.5 (ou seja, antes de casar) seria legal :)

Este ainda está aberto para fornecer suporte apenas para constantes nomeadas no
sinalizador --ssl-version.

Na segunda-feira, 2 de maio de 2016, 05:43 Benoit Chesneau [email protected] escreveu:

deixe-me saber o que é necessário aqui, se podemos fechá-lo antes do lançamento 19.5
(ou seja, antes de casar) seria legal :)

-
Você está recebendo isso porque modificou o estado abrir / fechar.
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/benoitc/gunicorn/issues/1114#issuecomment -216225302

vamos esquecer a versão 3.x por enquanto. Quais são as constantes necessárias para adicionar suporte em todas as versões do python?

Aqui está uma prova de conceito: https://github.com/benoitc/gunicorn/pull/1454

É possível especificar diferentes versões de TLS para ativar ou desativar? Por exemplo, é comum querer desabilitar ou habilitar versões mais antigas. Não está claro para mim na documentação se "--ssl-version" pode ser usado para desabilitar versões mais antigas ou se pode ser usado mais de uma vez (por exemplo, desabilitar SSL3 e desabilitar TLS1.0).

Acho que isso exigiria mudar para usar SSLContext e adicionar uma nova opção --ssl-options (provavelmente usaremos apenas ssl.create_default_context() portanto SSLv3 e TLS 1.0 serão desativados por padrão). são muitas combinações, não acho que --ssl-version aceitaria constante nomeada, mas os usuários ainda podem colocá-la em um arquivo de configuração Gunicorn:

ssl_options = ssl.OP_NO_COMPRESSION | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3

O uso de PROTOCOL_ * para especificar o protocolo _e a versão exata_ parece estar cada vez mais obsoleto. Supondo que ssl_options não esteja implementado atualmente, eu angariei # 1680.

1890 consertou.

Talvez alguém possa ter alguma orientação para mim? Eu tenho lutado com isso por um tempo agora. Este é meu ambiente:

Python 3.4.3
gunicorn==19.9.0
pyOpenSSL==18.0.0
cryptography==2.4.2

Também estou usando a sinalização gunicorn --ssl-version 5

Meu servidor parece estar servindo TLS 1.2, mas permite uma tonelada de pacotes de criptografia inseguros. Como posso limitar os conjuntos de criptografia? Eu tentei a bandeira --ciphers , mas não tive sorte com isso.

Obrigado!

--ssl-version 5 --ciphers ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256
funcionam bem:

~ # openssl s_client -connect localhost: 443 -cipher ECDHE-RSA-AES256-GCM-SHA384
CONECTADO (00000003)
profundidade = 3 ...

~ # openssl s_client -connect localhost: 443 -cipher DHE-RSA-AES256-GCM-SHA384
CONECTADO (00000003)
140497569816640: erro: 14094410 : Rotinas SSL falha de handshake de alerta sslv3

Obrigado @lemrouch. Não tenho certeza por que isso não funcionou para mim antes. Está funcionando para mim agora!

Como usar TLS 1.2 em vez de TLS1.0 para o aplicativo gunicorn flask? Alguns poderiam compartilhar o comando ou código do terminal que deve ser inserido?

@rkbala Esta é a aparência do código relevante para meu aplicativo

...
from ssl import SSLContext, PROTOCOL_TLSv1_2, OP_NO_SSLv3, OP_NO_TLSv1, OP_NO_TLSv1_1
...
ssl = SSLContext(PROTOCOL_TLSv1_2)
ssl.set_ciphers('ECDH+AES256:ECDH+AES128:' + 
                '!aNULL:!eNULL:!MD5:!DSS:!RC4:!SSLv2:!SSLv3:!TLSv1')
ssl.options |= OP_NO_SSLv3
ssl.options |= OP_NO_TLSv1
ssl.options |= OP_NO_TLSv1_1
ssl.load_cert_chain('/etc/letsencrypt/live/fullchain.pem',
                    '/etc/letsencrypt/live/privkey.pem')
...
if __name__ == '__main__':
    app.run(host='0.0.0.0', port='443', ssl_context=ssl)

@rkbala Esta é a aparência do código relevante para meu aplicativo

...
from ssl import SSLContext, PROTOCOL_TLSv1_2, OP_NO_SSLv3, OP_NO_TLSv1, OP_NO_TLSv1_1
...
ssl = SSLContext(PROTOCOL_TLSv1_2)
ssl.set_ciphers('ECDH+AES256:ECDH+AES128:' + 
                '!aNULL:!eNULL:!MD5:!DSS:!RC4:!SSLv2:!SSLv3:!TLSv1')
ssl.options |= OP_NO_SSLv3
ssl.options |= OP_NO_TLSv1
ssl.options |= OP_NO_TLSv1_1
ssl.load_cert_chain('/etc/letsencrypt/live/fullchain.pem',
                    '/etc/letsencrypt/live/privkey.pem')
...
if __name__ == '__main__':
    app.run(host='0.0.0.0', port='443', ssl_context=ssl)

@pixelrebel Obrigado !! Vou tentar e informá-lo.

O que significa ssl.options | = OP_NO_ *?

Podemos mudar a cifra? Ou os set_ciphers acima definirão a cifra aleatória?

@rkbala Não me lembro por que a operação bit a bit-or foi necessária. Pode não ser necessário ... vale a pena um teste.

Você pode alterar a cifra para qualquer que seja compatível com TLS 1.2. No meu caso, meu aplicativo fornece uma API para o Slack se comunicar com ele. Então, eu só precisava oferecer suporte à cifra que o Slackbot usa.

@rkbala IO deve esclarecer que não me lembro por que precisava dessa sintaxe, mas acredito que, na época, precisei especificar explicitamente as opções OP_NO_ * para fazer meu aplicativo usar apenas TLS1.2 e nenhuma versão inferior.

@rkbala Não me lembro por que a operação bit a bit-or foi necessária. Pode não ser necessário ... vale a pena um teste.

Você pode alterar a cifra para qualquer que seja compatível com TLS 1.2. No meu caso, meu aplicativo fornece uma API para o Slack se comunicar com ele. Então, eu só precisava oferecer suporte à cifra que o Slackbot usa.

Ok, obrigado. Acho que o gunicorn leva a cifra python padrão se não especificarmos uma. Corrija-me se eu estiver errada.

Além disso, o código do frasco acima faz com que o gunicorn inicie o aplicativo do frasco apenas em TLSv1.2? A questão é porque eu quero executar o aplicativo flask via gunicorn. Acabei de aprender hoje que o comando do terminal gunicorn “gunicorn —ssl-version TLSV1_2 project: app ” iniciará o flask app no ​​tls v1.2. Qual maneira é mais eficiente?

Sim, isso faz TLS 1.2 apenas. Todo o resto está obsoleto AFAIK. Presumo que tenham o mesmo efeito, mas acho que usar opções de linha de comando substitui as opções no script. Não sou um especialista em gunicorn de forma alguma. Portanto, siga meu conselho com cautela.

Sim, isso faz TLS 1.2 apenas. Todo o resto está obsoleto AFAIK. Presumo que tenham o mesmo efeito, mas acho que usar opções de linha de comando substitui as opções no script. Não sou um especialista em gunicorn de forma alguma. Portanto, siga meu conselho com cautela.

Obrigado @pixelrebel irei explorar essa parte.

Esta página foi útil?
0 / 5 - 0 avaliações