错误信息
curl: (35) TLS connect error: error:0A00042E:SSL routines::tlsv1 alert protocol version
也可能输出为
- curl: (35) error:0A00042E:SSL routines::tlsv1 alert protocol version
- curl: (35) error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version
较新的 curl 版本会在 OpenSSL 给出的原因前加上“TLS connect error: ”。OpenSSL 1.1.1 会带上函数名:“error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version”。如果反过来是服务器选择了客户端拒绝的版本,客户端报告的是“unsupported protocol”。
curl (OpenSSL backend) — CURLE_SSL_CONNECT_ERROR, TLS alert 70 (protocol_version) received from the server
含义
服务器发送了 TLS 告警 70(protocol_version):curl 提供的 TLS 版本它一个都不接受。前缀“tlsv1”只是 OpenSSL 对 TLS 1.0 起定义的告警的命名,并不代表实际使用的版本。通常是服务器还停留在 TLS 1.0/1.1,而客户端提供的是 1.2 和 1.3;或者客户端的版本上限被设得低于服务器要求的最低版本。
原因
服务器只支持 TLS 1.0 或 1.1
常见现代客户端的 ClientHello 只提供 TLS 1.2 和 1.3。如果服务器支持的最高版本是 1.0 或 1.1,并且能识别 supported_versions 扩展,它就无从选择,只能以 protocol_version 拒绝。
客户端被限定了过旧的最高版本
偶见--tls-max 1.1、带上限的 --tlsv1.0,或者调试旧设备时遗留在 .curlrc 中的一行配置,都会让 curl 提供当前服务器已禁用的版本。
仅支持 TLS 1.3 的服务器遇上上限为 1.2 的客户端
偶见一些经过加固的端点只接受 TLS 1.3。对于基于旧库构建的客户端,或者被配置强制使用 TLS 1.2 的客户端,服务器会用同一个告警拒绝连接。
修复方法
- 1.
找出服务器接受的版本
用 openssl s_client 逐一尝试每个版本。根据结果可以判断该修服务器(只接受 tls1/tls1_1),还是该修客户端(它从未提供服务器接受的版本)。
bash for v in tls1 tls1_1 tls1_2 tls1_3; do printf '%s: ' "$v" openssl s_client -connect api.example.com:443 -servername api.example.com -"$v" </dev/null >/dev/null 2>&1 \ && echo accepted || echo refused done - 2.
在服务器上启用 TLS 1.2 和 1.3
升级 TLS 配置(必要时还要升级 TLS 库或操作系统),让服务器接受 TLS 1.2 和 1.3。
text # nginx ssl_protocols TLSv1.2 TLSv1.3; # HAProxy (global section) ssl-default-bind-options ssl-min-ver TLSv1.2 - 3.
移除客户端的版本上限
从脚本和 .curlrc 中删除 --tls-max 和旧的协议参数;只设置最低版本,让 curl 能协商出双方都支持的最高版本。
bash grep -nE 'tls-max|tlsv1|sslv3' ~/.curlrc # a forgotten cap in the config file curl --tlsv1.2 https://api.example.com/ # minimum 1.2, no maximum
相关错误
SSL routines:ssl3_read_bytes:tlsv1 alert protocol versionOpenSSL (client side)curl: (35) TLS connect error: error:0A000102:SSL routines::unsupported protocolcurl (OpenSSL backend)curl: (35) TLS connect error: error:0A000410:SSL routines::ssl/tls alert handsh…curl (OpenSSL backend)SSL_ERROR_UNSUPPORTED_VERSIONFirefox