Перейти к содержимому
ecdsa.com
Python ssl module (OpenSSL 3)Python: пакет cryptography

Сообщение об ошибке

[SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation disabled

Появляется в Python, собранном с OpenSSL 3.0 или новее (большинство сборок Python с 2022 года); OpenSSL 1.1.1 ещё разрешал подключаться к таким серверам. Далее следует место в исходном коде, например «(_ssl.c:1082)».

Python ssl module (OpenSSL 3) — ssl.SSLError, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED

Что это означает

Сервер согласовал TLS 1.2 или более старую версию без расширения безопасного повторного согласования из RFC 5746. Клиенты на OpenSSL 3 по умолчанию отказываются работать с такими серверами, потому что устаревшее повторное согласование позволяло злоумышленнику, вклинившемуся в соединение (атака «человек посередине»), вставлять свои данные перед запросом клиента (CVE-2009-3555). Python наследует это поведение по умолчанию, поэтому соединение завершается ошибкой во время рукопожатия.

Почему это происходит

Как исправить

  1. 1.

    Убедитесь, что сервер не поддерживает безопасное повторное согласование

    Для таких серверов openssl s_client выводит «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. 2.

    Исправьте сервер

    Обновление стека TLS или прошивки сервера либо включение TLS 1.3 устраняет проблему для всех клиентов.

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

    Временное решение: разрешите это только для одного хоста

    ssl.OP_LEGACY_SERVER_CONNECT (Python 3.12+) снова разрешает подключения к таким серверам для одного этого контекста. Для этого хоста флаг возвращает риск вставки чужих данных через повторное согласование, поэтому не задавайте его глобально или через системную конфигурацию OpenSSL.

    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)

Связанные ошибки

Открыть всю базу ошибок подписей