错误信息
tls: server selected unsupported protocol version 301
这个数字是不带 0x 前缀的十六进制版本代码:300 = SSL 3.0,301 = TLS 1.0,302 = TLS 1.1。HTTP 客户端会加上前缀“Get \"https://…\": ”。基于当前版本的库构建、只支持 TLS 1.0 的服务器会直接拒绝,而不是降级,此时 Go 报告的是“remote error: tls: protocol version not supported”(针对 openssl s_server -tls1 测试时观察到)。
Go crypto/tls client — the server chose TLS 1.0 (0x0301) or 1.1 (0x0302), below Go's minimum
含义
服务器在响应 Go 的 ClientHello 时,选择了 Go 客户端不允许的 TLS 版本:301 是 TLS 1.0 的十六进制版本代码,302 是 TLS 1.1 的。Go 客户端默认要求 TLS 1.2 或更高版本(自 Go 1.18 起),因此会中止握手。服务器需要支持 TLS 1.2 及以上版本。
原因
服务器只支持 TLS 1.0 或 1.1
常见老旧的硬件设备、嵌入式设备、旧版 Windows 服务器以及过时的负载均衡器。
Go 客户端的最低版本是 TLS 1.2
常见自 Go 1.18 起,客户端的 tls.Config.MinVersion 默认为 TLS 1.2;用较新的 Go 重新构建的程序,即使代码没有任何改动,也无法再与 TLS 1.0 服务器通信。
修复方法
- 1.
升级服务器的 TLS
在服务器上启用 TLS 1.2(以及 1.3),或者在它前面部署一个现代的 TLS 终止代理。
text Upgrade the server (or the appliance firmware / TLS terminator in front of it) to TLS 1.2 or 1.3. 0x0301 = TLS 1.0, 0x0302 = TLS 1.1, 0x0303 = TLS 1.2, 0x0304 = TLS 1.3. - 2.
最后手段:使用 MinVersion 为 TLS 1.0 的专用客户端
在只用于那台旧设备的客户端中降低 MinVersion,就能恢复连接。TLS 1.0 已被弃用(RFC 8996),缺少现代的安全保护;这类流量只应在受信任网络中传输,切勿在共享的 Transport 上这样设置。
go // Last resort for one legacy device on a trusted network: a dedicated client legacy := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{ MinVersion: tls.VersionTLS10, // only for this client; never in a shared transport }}} resp, err := legacy.Get("https://legacy.example.com:8443/")