Mensagem de erro
[SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation disabled
Aparece com o Python vinculado ao OpenSSL 3.0 ou posterior (a maioria dos builds do Python desde 2022); o OpenSSL 1.1.1 ainda aceitava esses servidores. Em seguida vem uma localização no código-fonte, como “(_ssl.c:1082)”.
Python ssl module (OpenSSL 3) — ssl.SSLError, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED
O que significa
O servidor negociou TLS 1.2 ou anterior sem a extensão de renegociação segura da RFC 5746. Clientes com OpenSSL 3 recusam esses servidores por padrão, porque a renegociação legada permitia que um atacante man-in-the-middle inserisse os próprios dados antes da requisição do cliente (CVE-2009-3555). O Python herda esse padrão, então a conexão falha durante o handshake.
Por que acontece
Uma pilha TLS desatualizada no servidor ou no equipamento
comumVersões antigas do Windows Server, servidores Java legados, sistemas ERP, dispositivos de rede e alguns endpoints governamentais ou bancários ainda rodam implementações de TLS que nunca ganharam suporte à RFC 5746.
Um equipamento intermediário que faz a terminação TLS sem a RFC 5746
comumBalanceadores de carga e proxies antigos (algumas versões do F5 BIG-IP e de proxies corporativos) fazem a terminação TLS para back-ends modernos e apresentam aos clientes o próprio comportamento legado.
O cliente passou para o OpenSSL 3
comumO mesmo servidor funcionava com builds do Python sobre o OpenSSL 1.1.1; a atualização do Python, do sistema operacional ou da imagem base do contêiner trocou o OpenSSL e trouxe o padrão mais rigoroso dele.
Como corrigir
- 1.
Confirmar que o servidor não tem renegociação segura
O openssl s_client informa “Secure Renegotiation IS NOT supported” para esses servidores.
bash openssl s_client -connect legacy.example.com:443 -servername legacy.example.com </dev/null 2>/dev/null \ | grep -i 'secure renegotiation' # "Secure Renegotiation IS NOT supported" confirms the server lacks RFC 5746 - 2.
Corrigir o servidor
Atualizar a pilha TLS ou o firmware do servidor, ou oferecer TLS 1.3, elimina o problema para todos os clientes.
text Server / appliance owners: update the TLS stack or firmware to any release supporting RFC 5746 (every mainstream TLS library since 2010), or enable TLS 1.3, which has no renegotiation at all. - 3.
Solução temporária: permitir só para um host
ssl.OP_LEGACY_SERVER_CONNECT (Python 3.12+) reativa as conexões com esses servidores somente nesse contexto. A opção reabre o risco de inserção de dados via renegociação para esse host, por isso não a defina globalmente nem pela configuração do OpenSSL do sistema.
python # Temporary workaround for one legacy host only (Python 3.12+: ssl.OP_LEGACY_SERVER_CONNECT) import ssl, urllib.request ctx = ssl.create_default_context() ctx.options |= ssl.OP_LEGACY_SERVER_CONNECT urllib.request.urlopen("https://legacy.example.com/", context=ctx)