Golang中TLS 1.0和1.1连接失败问题排查

Golang中TLS 1.0和1.1连接失败问题排查 大家好,

我正在创建一个TLS加密的HTTP服务器,并在使用的tls.Config中降低了支持的最低TLS版本(尽管我知道TLS 1.0和1.1已经终止支持)。

我在Go文档中没有找到任何说明这不应该工作的内容,但是当我运行下面示例中的代码(使用自签名证书和密钥)时,我收到了一个协议不受支持的错误。此外,我还尝试将GODEBUG环境变量设置为tls10server=1,但这也没有效果。

package main

import (
	"crypto/tls"
	"log"
	"net/http"
)

func main() {

	server := http.Server{
		Addr: "0.0.0.0:8080",
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.WriteHeader(http.StatusOK)
			w.Write([]byte("success"))
		}),
	}
	server.TLSConfig = &tls.Config{MinVersion: tls.VersionTLS10}
	if err := server.ListenAndServeTLS("server.crt", "server.key"); err != nil {
		log.Fatalf("server crashed :: %s", err.Error())
	}

}

我尝试使用下面的命令对服务器进行TLS检查(对于使用参数--tls-max 1.0的curl,结果相同):

openssl s_client -connect localhost:8080 -tls1_1

以及:

openssl s_client -connect localhost:8080 -tls1_0

两者都失败了,并显示以下错误信息:

CONNECTED(00000003) 409776618F7F0000:error:0A0000BF:SSL routines:tls_setup_handshake:no protocols available:…/ssl/statem/statem_lib.c:104:

在应用程序的输出中,我可以看到以下条目:

2025/01/10 16:17:21 http: TLS handshake error from 172.21.29.106:33582: remote error: tls: protocol version not supported

有没有人能提示一下,我哪里做错了,或者Go是否完全不支持这两个TLS版本,尽管我在Go文档中没有找到任何相关信息。

非常感谢您的帮助和提示。

此致, Timo


更多关于Golang中TLS 1.0和1.1连接失败问题排查的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

远程错误:tls: 协议版本不受支持是一个常见的 SSL/TLS 连接错误,表明客户端和服务器无法就使用的 SSL/TLS 协议版本达成一致。具体来说,客户端提议的 SSL/TLS 版本要么是服务器不支持的,要么是服务器认为版本过旧存在安全风险。例如,当客户端尝试使用较旧的 SSL 3.0 版本连接,而服务器仅支持 TLS 1.2 或更高版本时,服务器可能会向客户端发送带有“protocol_version”警告的握手失败消息。

尝试限制最大版本?

	tls.Config{MinVersion: tls.VersionTLS10,MaxVersion: tls.VersionTLS11}

更多关于Golang中TLS 1.0和1.1连接失败问题排查的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


首先,感谢您的回复。

您说得完全正确,允许客户端使用 TLS 版本 >= TLS 1.2 时,一切工作正常。

我知道 Go 的默认 TLS 配置中,最低 TLS 版本是 1.2。

在我的实际代码中,我已经尝试了多种最低和最高版本的组合,以及各种密码套件。

我只是提供了一个最小化的示例来演示我遇到的问题,并方便复现。

我将最低 TLS 版本降低到 1.0,是因为我想确保,万一有客户端只支持 TLS < 1.2(现实中确实有极少数情况),我可以自行承担风险,将我的服务器配置为也支持这些客户端。

我发布的那个 openssl 命令,是用来检查是否可以使用给定的参数(在本例中是 tls 1.1 和 tls 1.0)建立 TLS 连接的。尽管我已经将 minVersion 设置为 “VersionTLS10”,但这仍然无法工作。

如果我使用 tls1_2 参数运行相同的 openssl 命令,它又能完美运行。

希望这能澄清我想要实现的目标。

此致, Timo

在Go 1.22及更高版本中,TLS 1.0和1.1的服务器端支持默认被禁用。你需要显式启用这些版本。以下是修正后的代码:

package main

import (
	"crypto/tls"
	"log"
	"net/http"
)

func main() {
	server := http.Server{
		Addr: "0.0.0.0:8080",
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.WriteHeader(http.StatusOK)
			w.Write([]byte("success"))
		}),
	}
	
	server.TLSConfig = &tls.Config{
		MinVersion: tls.VersionTLS10,
		MaxVersion: tls.VersionTLS10, // 明确设置最大版本
	}
	
	if err := server.ListenAndServeTLS("server.crt", "server.key"); err != nil {
		log.Fatalf("server crashed :: %s", err.Error())
	}
}

对于TLS 1.1,使用:

server.TLSConfig = &tls.Config{
	MinVersion: tls.VersionTLS11,
	MaxVersion: tls.VersionTLS11,
}

另外,确保你的证书是有效的自签名证书。可以使用以下命令生成:

openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes -subj "/C=US/ST=State/L=City/O=Org/CN=localhost"

测试时使用正确的openssl命令:

openssl s_client -connect localhost:8080 -tls1

对于TLS 1.1:

openssl s_client -connect localhost:8080 -tls1_1

如果仍然遇到问题,可以检查Go版本是否支持这些TLS版本。在Go 1.22+中,虽然默认禁用,但通过显式配置MaxVersion仍然可以启用。

回到顶部