错误信息
curl: (35) TLS connect error: error:0A000102:SSL routines::unsupported protocol
也可能输出为
- curl: (35) error:0A000102:SSL routines::unsupported protocol
- curl: (35) error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol
较新的 curl 版本(此处为 8.14.1)会在 OpenSSL 给出的原因前加上“TLS connect error: ”。OpenSSL 1.1.1 会写出函数名:“error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol”。如果拒绝的一方是服务器,客户端看到的则是“tlsv1 alert protocol version”。
curl (OpenSSL backend) — CURLE_SSL_CONNECT_ERROR, SSL_R_UNSUPPORTED_PROTOCOL
含义
服务器在响应 ClientHello 时选择了 curl 的 TLS 库不允许使用的协议版本,通常是 TLS 1.0 或 1.1。随后客户端在自己这一侧中止连接。这里与网络路径和证书都无关:双方只是没有共同支持的 TLS 版本。
原因
服务器只支持 TLS 1.0 或 1.1
常见老旧的 Windows Server/IIS、Java 6/7 时代的应用以及无人维护的负载均衡器仍在协商 TLS 1.0。2021年,RFC 8996 弃用了 TLS 1.0 和 1.1,当前的客户端也不再提供这两个版本。
客户端的系统策略要求最低 TLS 1.2
常见Debian、Ubuntu(自 20.04 起)、RHEL 8+ 的加密策略以及 OpenSSL 3 的默认安全级别都会拒绝 TLS 1.0/1.1。同一台服务器从较旧的机器上访问可能仍然正常,因此这个故障看起来像是与环境有关。
嵌入式管理界面和设备
偶见打印机和 UPS 的 Web 管理界面、旧版 IPMI/iLO 固件、SCADA 网关等设备,往往无法升级到 TLS 1.0 以上。
修复方法
- 1.
确认服务器接受哪些版本
逐一显式尝试每个版本。如果只有 tls1 或 tls1_1 成功,就必须升级服务器;如果 tls1_2 也成功,就去查找客户端中限制最高版本的选项。
bash # Which versions does the server accept? (each line succeeds or fails on its own) for v in tls1 tls1_1 tls1_2 tls1_3; do printf '%s: ' "$v" openssl s_client -connect legacy.example.com:443 -"$v" </dev/null >/dev/null 2>&1 && echo ok || echo no done - 2.
在服务器上启用 TLS 1.2 和 1.3
开启 TLS 1.2(在技术栈支持时也开启 1.3),并关闭 1.0/1.1。只有这种修复方式能同时惠及浏览器、移动应用和其他 API 客户端。
text # nginx ssl_protocols TLSv1.2 TLSv1.3; # Apache httpd SSLProtocol -all +TLSv1.2 +TLSv1.3 # IIS / Windows Server: enable TLS 1.2 under # HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server - 3.
最后手段:仅在调用无法升级的设备时单次允许 TLS 1.0
只为与旧设备通信的那条命令重新启用旧版本,切勿在系统范围内启用。TLS 1.0 依赖存在已知攻击的 SHA-1 和 CBC 构造;这类流量应限制在隔离的管理网络中。
bash # Last resort for a device you cannot upgrade: allow TLS 1.0 for this one call only. # OpenSSL 3 also needs security level 0 for the SHA-1 based handshake of TLS 1.0/1.1. curl --tlsv1.0 --ciphers 'DEFAULT:@SECLEVEL=0' https://legacy-device.example.internal/
相关错误
SSL routines:ssl_choose_client_version:unsupported protocolOpenSSL (client side)curl: (35) TLS connect error: error:0A00042E:SSL routines::tlsv1 alert protocol…curl (OpenSSL backend)The server selected protocol version TLS10 is not accepted by client preference…Java (JSSE)tls: server selected unsupported protocol version 301Go crypto/tls clientnet::ERR_SSL_VERSION_OR_CIPHER_MISMATCHChrome, Edge and other Chromium browsers