本文へスキップ
ecdsa.com
Python ssl module (OpenSSL 3)Python の cryptography

エラーメッセージ

[SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation disabled

OpenSSL 3.0 以降にリンクされた Python(2022年以降のほとんどの Python ビルド)で表示されます。OpenSSL 1.1.1 では、まだこうしたサーバーへの接続が許可されていました。その後に「(_ssl.c:1082)」のようなソースの位置が続きます。

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

このエラーの意味

サーバーが、RFC 5746 の安全な再ネゴシエーション拡張を使わずに TLS 1.2 以前をネゴシエートしました。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.

    一時的な回避策:1 つのホストに限って許可する

    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)

関連するエラー

署名エラーデータベースをすべて見る