记一次被社区用户逼着修Bug经历

记录 Categraf http_response 插件报错 remote error: tls: handshake failure 的排查过程,说明 IPv4/IPv6 入口 TLS 配置差异、Go 1.24 默认加密套件变化,以及 tls_cipher_suites 兼容配置方案。

作者 孔飞@快猫星云

最近社区用户反馈了一个问题:使用最新版 Categraf (v0.4.34) 的 http_response 插件监控某域名 https://oa.sdu.edu.cn 时,报错 remote error: tls: handshake failure。但开发人员在自己的环境中测试却一切正常。吃瓜围观见issue, 用户对这个问题定性:“希望在新版本中修复这个bug”。

本文记录了该问题的完整排查过程、根因分析及最终修复方案。

核心摘要

  • 问题现象是 Categraf v0.4.34 的 http_response 插件访问 https://oa.sdu.edu.cn 时出现 remote error: tls: handshake failure
  • 开发环境访问 IPv4 入口正常,用户环境访问 IPv6 入口失败,关键差异在 TLS 版本和加密套件。
  • 用户环境里服务端协商到 TLS 1.2,并使用 ECDHE-RSA-AES128-SHA256 这类 CBC 模式套件。
  • Categraf 使用较新的 Go 版本编译,默认 Client Hello 不再提供部分旧 CBC 套件,导致和旧入口设备无法协商成功。
  • 修复思路是为 Categraf 增加 tls_cipher_suites 配置,让用户可以显式开启旧服务器需要的加密套件。

术语解释:TLS handshake failure 是什么

TLS handshake failure 表示客户端和服务端在 TLS 握手阶段没有协商出双方都接受的协议版本、证书能力或加密套件。本文案例中,关键不是域名无法访问,也不是 Categraf 插件完全不可用,而是 IPv6 入口只接受旧的 TLS 1.2 CBC 套件,而新版 Go 客户端默认不再提供这类套件。

因此排查这类问题时,不能只看“curl 是否成功”,还要看 curl 实际连接的是 IPv4 还是 IPv6、协商的 TLS 版本是什么、最终使用了哪个 cipher suite。

1. 排查过程

欸?在我的环境明明好好的 好好的.好好的

复现的诡异性

  • 开发环境 (Debian, 公网):没有报错,能够正常通过 curl 和 Categraf 采集数据。
  • 用户环境 (Anolis OS, 校园网环境)curl 正常,但 Categraf 持续报错 tls: handshake failure

初步怀疑方向集中在:

  1. TLS 版本不匹配?
  2. 中间人设备(防火墙、WAF)干扰?
  3. DNS 解析差异?

关键线索:Cipher Suite 与 IP 协议

通过对比开发人员与用户在各自环境下执行 curl -vI https://oa.sdu.edu.cn 的详细日志,我们发现了具体的差异。

开发人员环境(正常)

* Connected to oa.sdu.edu.cn (202.194.20.69) port 443  <-- IPv4
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384

特点:访问的是 IPv4 地址,服务器支持 TLS 1.3 和现代化的 GCM 加密套件。

用户环境(报错)

* Connected to oa.sdu.edu.cn (2001:da8:7000:f03:202:194:20:69) port 443 <-- IPv6
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
...
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-SHA256

特点

  1. 访问的是 IPv6 地址。
  2. 服务端不支持 TLS 1.3,协商降级到了 TLS 1.2
  3. 最终选用的加密套件是 ECDHE-RSA-AES128-SHA256(即 CBC 模式)。

2. 根因分析:Go的安全策略变更

至此,问题原因浮出水面。

  1. IPv6 入口设备"老旧":该域名的 IPv6 入口(可能是负载均衡或防火墙)配置落后于 IPv4 入口,仅支持 TLS 1.2 且只接受 CBC 模式的加密套件。
  2. Categraf/Go 的默认行为:Categraf 是用较新的 Go 版本(1.24)编译的,而且升级了TLS的依赖库。Go 语言团队为了安全性,在默认的 Client Hello 加密套件列表中剔除了被认为不够安全的 CBC 模式套件(如 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)。
  3. 握手死锁
    • Categraf: “我支持 TLS 1.2/1.3,但我只用 GCM/Chacha20 等高性能安全算法,不提供 CBC。”
    • Server (IPv6): “我只支持 TLS 1.2 且必须用 CBC。”
    • 结果: 双方无法达成一致,服务端发送 handshake failure
  4. Why Curl Works?curl 使用的 OpenSSL 版本不高, 默认策略包含了旧的 CBC 套件,因此能与“老”服务器成功握手。

3. 修复方案

我们通过代码修改,赋予 Categraf “向下兼容” 的能力,允许用户手动指定那些被 Go 默认屏蔽的加密套件。

代码变更 (Pull Request)

  1. 修改 pkg/tls/config.go: 在 ClientConfig 中增加 TLSCipherSuites 字段,允许从配置文件读取 tls_cipher_suites

  2. 修改 pkg/tls/common.go: 补全 Go 标准库中存在但未在 Categraf 映射表中暴露的 Legacy Cipher Suites:

    // 添加 Legacy CBC 套件
    "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
    "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA":    tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
    // ...
    

用户配置

用户现在可以通过在 http_response.toml 中显式配置旧套件来解决此问题:

[[instances]]
targets = ["https://oa.sdu.edu.cn"]

# 强制开启兼容旧服务器所需的 CBC 套件
tls_cipher_suites = [
  "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",  # 对应 curl 的 ECDHE-RSA-AES128-SHA256
  "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"      # SHA1 版本作为备选
]

可复用的排查方法

这次问题的关键,不在于简单地复现失败,而在于比较两边成功和失败时的握手细节。后续遇到类似问题,可以按下面顺序排查:

  1. curl -vI 查看实际连接的 IP 地址,确认是 IPv4 还是 IPv6。
  2. 对比 TLS 版本,例如 TLS 1.3 还是 TLS 1.2。
  3. 对比最终协商出的 cipher suite。
  4. 确认客户端运行时或编译环境是否调整了默认 TLS 安全策略。
  5. 如果确实需要兼容旧服务端,再通过显式配置开启旧套件,而不是降低所有场景的默认安全策略。

总结

在 IPv6 推进过程中,基础设施的更新往往不同步,导致 IPv4 和 IPv6 入口的 SSL 配置产生“代差”。作为监控客户端,保持对旧协议的适度兼容性配置能力,是应对复杂网络环境的关键。

这次修复的边界也很清楚:默认行为仍应优先遵循较新的安全策略;只有在确实遇到旧服务器或旧入口设备时,才通过 tls_cipher_suites 显式打开兼容配置。

FAQ

Q1:为什么开发环境正常,用户环境失败? A:开发环境连接的是 IPv4 地址,服务端支持 TLS 1.3 和现代 GCM 套件;用户环境连接的是 IPv6 地址,服务端只协商到 TLS 1.2,并使用 CBC 模式套件。

Q2:为什么 curl 能成功,Categraf 却失败? A:原文排查结果是,curl 使用的 OpenSSL 默认策略包含旧 CBC 套件,而 Categraf 使用较新的 Go 版本编译,默认 Client Hello 不再提供相关旧套件。

Q3:修复方案是不是降低 Categraf 默认安全性? A:不是。修复方案是增加可配置能力,让用户在需要兼容旧服务器时显式配置 tls_cipher_suites。默认安全策略不应为了个别旧入口全面降低。

Q4:遇到 TLS handshake failure 应该先查什么? A:先查连接 IP、TLS 版本和 cipher suite。尤其在域名同时有 IPv4 和 IPv6 入口时,两边的 TLS 配置可能不一致。

延伸路径

继续看解决方案和产品对比

如果你正在做监控、可观测性或故障定位相关选型,建议从解决方案和产品对比继续往下看。

标签 Categraf
快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云