はじめに
curl で HTTPS エンドポイントに接続しようとしたところ、以下のエラーが発生した。
error:0A000152:SSL routines::unsafe legacy renegotiation disabled
OpenSSL 3.x 系の環境ではよく見かけるエラーで、原因と対処方法をまとめる。
環境
- OS:RHEL 9 系
- curl(libcurl が OpenSSL 3.x にリンクされているもの)
原因
OpenSSL 3.x では、セキュリティ強化の一環として RFC 5746 未対応のレガシーな TLS 再ネゴシエーション方式がデフォルトで無効化 された。
接続先サーバーが古い TLS 実装を使用している場合、このエラーが発生する。
対処方法
システム全体の OpenSSL 設定(/etc/ssl/openssl.cnf)を変更するのはリスクが高い。
一時的な設定ファイル + 環境変数 で対応するのが安全。
1. 一時設定ファイルを作成する
cat > /tmp/openssl_legacy.cnf << 'EOF'
openssl_conf = openssl_init
[openssl_init]
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
Options = UnsafeLegacyRenegotiation
EOF
2. 環境変数を付与して curl を実行する
OPENSSL_CONF=/tmp/openssl_legacy.cnf curl -v -s -k "https://接続先URL"
-v を付けるとハンドシェイクの詳細ログが出力されるため、問題の切り分けに有効。
⚠️ -k はサーバー証明書の検証をスキップするオプション。疎通確認・デバッグ目的に限定すること。
/etc/hosts を変更せずに別 IP で疎通確認したい場合
ロードバランサ配下の特定ノードや、DNS 切り替え前の事前確認など、
hosts ファイルを書き換えずに接続先 IP を指定したいケースでは --resolve オプションが便利。
OPENSSL_CONF=/tmp/openssl_legacy.cnf curl -v -s -k \
--resolve "ホスト名:443:確認したいIPアドレス" \
"https://ホスト名/パス"
--resolve の書式:ホスト名:ポート番号:解決先IPアドレス
まとめ
- OpenSSL 3.x の SSL ハンドシェイクエラーは、一時設定ファイル +
OPENSSL_CONF環境変数で回避できる -
/etc/ssl/openssl.cnfなどシステム全体の設定は変更しない - hosts を変更せずに別 IP で疎通確認したい場合は
--resolveオプションを活用する - 本対処はあくまで暫定措置。接続先サーバーの TLS 設定改善が根本解決になる
参考資料
- OpenSSL 3.0 Migration Guide
-
man curl—--resolveオプション