问题背景
使用 cURL 访问某些 HTTPS 接口时,出现以下错误:
cURL error 35: OpenSSL/3.0.15: error:0A000152:SSL routines::unsafe legacy renegotiation disabled
这表明 OpenSSL 在握手过程中拒绝了“unsafe legacy renegotiation”(不安全的旧版重新协商)。根据 OpenSSL 3.0 的设计,如果对端不支持【RFC5746】规定的“安全重新协商”(secure renegotiation)扩展,则会拒绝连接。也就是说,OpenSSL 3.0 默认要求服务器支持 RFC5746(安全协商),不再向后兼容原先不安全的旧版协商方式(即 SSL_OP_LEGACY_SERVER_CONNECT 标志在 SSL_OP_ALL 中被移除)。这直接导致了该错误。一般来说,这是因为服务端或中间代理未实现 RFC5746 扩展,仍然只使用不安全的旧版协商方式,被 OpenSSL 3.0 拒绝连接。
原因分析
TLS 的重新协商(renegotiation)曾在 2009 年被发现存在安全漏洞(CVE-2009-3555),后来通过 RFC5746 引入“安全重新协商”扩展来修复漏洞。所有现代 TLS 库都默认启用该安全扩展,旧版(unsafe legacy)方式被弃用。OpenSSL 1.1.1 时代,为了兼容旧服务器,默认仍然设置了 SSL_OP_LEGACY_SERVER_CONNECT 标志以允许旧协商。但从 OpenSSL 3.0 开始,这个标志不再默认启用。OpenSSL 文档明确指出:“对 SSL 或 TLS 连接,默认情况下要求支持 RFC5746 安全重新协商。需要连接到旧版服务器的应用必须显式设置 SSL_OP_LEGACY_SERVER_CONNECT。SSL_OP_LEGACY_SERVER_CONNECT 不再包含在 SSL_OP_ALL 中”。因此,当客户端(OpenSSL 3.0)发现服务器不支持安全扩展时,就会报出 “unsafe legacy renegotiation disabled” 错误。
简而言之,就是 OpenSSL 3.0 强制要求对端支持安全协商,而服务端/代理不支持,导致连接被拒绝。上述错误也出现在使用 OpenSSL 3.0 的 curl、wget、Python requests
等场景中。
解决方案
此问题无法从应用层解决,只能从系统级别解决。
方案一、升级服务端:最安全的解决方案是让对方服务器或代理支持 RFC5746 安全重新协商,使握手符合现代 TLS 标准。联系 API 提供方更新其 TLS 实现,或迁移到支持安全协商的最新版本,是根本之道。
方案二、谨慎启用 Legacy Renegotiation:仅在无法升级服务器且业务紧迫时,通过 OpenSSL 配置启用 UnsafeLegacyServerConnect
。请务必评估风险,因为一旦启用,客户端连接可被中间人通过复合流量注入攻击(CVE-2009-3555)。
https://github.com/Kong/insomnia/issues/4543#issuecomment-1126771807

修改 openssl 的配置文件 /etc/ssl/openssl.cnf
:
openssl_conf = openssl_init
[openssl_init]
providers = provider_sect
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
Options = UnsafeLegacyServerConnect
最后重启系统即可获取到接口内容。