Go crypto/tls server (net/http ErrorLog)Go
错误信息
tls: client offered only unsupported versions: [301]
net/http 把它写作“http: TLS handshake error from <client address>: tls: client offered only unsupported versions: [301]”;列表显示客户端提供的每个版本(300 = SSL 3.0,301 = TLS 1.0,302 = TLS 1.1)。
Go crypto/tls server (net/http ErrorLog) — the client offered only TLS versions below the server's minimum
含义
Go 的 TLS 服务器收到了一个 ClientHello,其中提供的协议版本都低于服务器的最低版本,这里是 TLS 1.0(版本代码 301)。Go 服务器默认接受 TLS 1.2 和 1.3,因此握手会以 protocol_version 告警被拒绝,net/http 会记录这一行日志。另一端的客户端要么已经过时,要么在有意探测。
原因
过时的客户端
常见老旧设备、旧的 Java 6/7 或 .NET Framework 应用,以及无法使用 TLS 1.2 的嵌入式 HTTP 客户端。
互联网扫描器和安全工具
常见扫描器会有意提供旧版本,以便对服务器分类;在公开端点上,来自许多不同地址的此类日志行是正常现象。
配置为使用旧版本的客户端
偶见为了早已不复存在的旧集成,把协议设置固定为 TLS 1.0 的应用。
修复方法
- 1.
查明是谁发送的
按客户端地址对日志行分组:少数几个已知地址意味着有需要升级的过时客户端;大量未知地址则意味着扫描器。
bash # Which addresses send these handshakes, and how often? journalctl -u myservice --since today | grep 'client offered only unsupported versions' \ | grep -oE 'from [0-9a-f.:]+' | sort | uniq -c | sort -rn | head - 2.
保持 TLS 1.2 作为服务器的最低版本
不要为了迁就扫描器而降低 MinVersion;应改为升级少数几个合法的旧客户端。
go // Keep TLS 1.2 as the minimum (Go's server default); set it explicitly to document intent srv := &http.Server{Addr: ":443", TLSConfig: &tls.Config{MinVersion: tls.VersionTLS12}} - 3.
分离握手噪音
http.Server.ErrorLog 会接收握手错误;把它定向到专用的日志记录器,可以让应用日志保持清晰可读。
go // Route handshake noise from scanners to a separate logger instead of the main log srv.ErrorLog = log.New(handshakeLogWriter, "tls: ", 0)