Fehlermeldung
[SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation disabled
Erscheint bei Python, das gegen OpenSSL 3.0 oder neuer gelinkt ist (die meisten Python-Builds seit 2022); OpenSSL 1.1.1 ließ solche Server noch zu. Danach folgt eine Quellcode-Position wie „(_ssl.c:1082)“.
Python ssl module (OpenSSL 3) — ssl.SSLError, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED
Was der Fehler bedeutet
Der Server hat TLS 1.2 oder älter ohne die Erweiterung für sichere Renegotiation aus RFC 5746 ausgehandelt. Clients mit OpenSSL 3 lehnen solche Server standardmäßig ab, weil die alte Renegotiation einem Man-in-the-Middle erlaubte, eigene Daten vor der Anfrage des Clients einzuschleusen (CVE-2009-3555). Python übernimmt diese Voreinstellung, deshalb scheitert die Verbindung während des Handshakes.
Warum der Fehler auftritt
Ein veralteter TLS-Stack eines Servers oder einer Appliance
häufigAlte Versionen von Windows Server, veraltete Java-Server, ERP-Systeme, Netzwerkgeräte und manche Endpunkte von Behörden oder Banken betreiben noch TLS-Implementierungen, die nie mit RFC 5746 nachgerüstet wurden.
Eine TLS-terminierende Middlebox ohne RFC 5746
häufigAlte Load Balancer und Proxys (manche Versionen von F5 BIG-IP und von Firmen-Proxys) terminieren TLS für moderne Backends und zeigen den Clients ihr eigenes veraltetes Verhalten.
Der Client ist auf OpenSSL 3 umgestiegen
häufigDerselbe Server funktionierte mit Python-Builds auf Basis von OpenSSL 1.1.1; ein Upgrade von Python, des Betriebssystems oder eines Container-Basisimages hat OpenSSL ausgetauscht und damit dessen strengere Voreinstellung mitgebracht.
So behebst du den Fehler
- 1.
Bestätigen, dass dem Server sichere Renegotiation fehlt
openssl s_client meldet für solche Server „Secure Renegotiation IS NOT supported“.
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.
Server korrigieren
Aktualisierst du den TLS-Stack oder die Firmware des Servers oder bietest du TLS 1.3 an, verschwindet das Problem für jeden Client.
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.
Übergangslösung: nur für einen Host erlauben
ssl.OP_LEGACY_SERVER_CONNECT (Python 3.12+) erlaubt Verbindungen zu solchen Servern für diesen einen Kontext wieder. Damit kehrt für diesen Host das Risiko zurück, dass bei der Renegotiation fremde Daten eingeschleust werden; setze die Option deshalb weder global noch über die systemweite OpenSSL-Konfiguration.
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)