跳到主要内容
ecdsa.com
curl (OpenSSL backend)curl

错误信息

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;或者客户端的版本上限被设得低于服务器要求的最低版本。

原因

修复方法

  1. 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. 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. 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

相关错误

浏览完整的签名错误库