用 testssl.sh 给站点做一次 TLS 体检:它查了哪些、怎么跑、结果怎么看
介绍开源工具 testssl.sh 的检查范围、本地与线上两种跑法,以及如何读懂它的红绿输出:哪些红色真该紧张,哪些只是审美问题,帮你把一次扫描变成可执行的整改清单。
本文目录

线上收到告警说“证书链不完整”,你第一反应是掏浏览器——没问题啊,锁还在。问题是浏览器会自己补中间证书,很多客户端不会。这种时候与其猜,不如跑一遍 testssl.sh:单文件 Bash 脚本,克隆下来就能用,不依赖商业账号,也不把你的目标域名交给第三方网页服务。
它到底查什么
testssl.sh 不是“扫一下证书过没过期”那么简单。一次默认扫描大致覆盖:
- 证书本身:有效期、签名算法、证书链是否完整、吊销状态(OCSP/CRL 是否可达)、是否还在用 SHA-1。
- 协议版本:从 SSLv2 一路试到 TLS 1.3,列出服务端实际接受哪些。
- 密码套件:枚举服务端支持的套件,并标出那些该淘汰的——RC4、3DES、CBC 模式的旧套件、不带前向保密的 RSA 密钥交换等。
- 已知漏洞:Heartbleed、POODLE、BEAST、ROBOT、Ticketbleed 等,逐项测试而不是只看版本号猜测。
- 杂项但重要的:HSTS 响应头、OCSP stapling、会话复用、ALPN 协商出的协议。
它的底色是 openssl 加自己的 socket 探测逻辑,所以不依赖系统 openssl 支持所有特性——脚本自带了一套编译好的二进制来测老协议,这也是为什么它在老系统上也能测 TLS 1.3 之前的东西。
怎么跑
最常见的两种方式:

git clone --depth 1 https://github.com/drwetter/testssl.sh.git
cd testssl.sh
./testssl.sh example.com默认就是全量扫描,输出很长但分了段。不想在机器上装东西的话,官方也提供了 Docker 镜像,docker run --rm -ti drwetter/testssl.sh example.com 效果一样。
几个实际用得多的选项:
./testssl.sh -U example.com只测漏洞项,适合变更后快速回归。./testssl.sh -e example.com只枚举密码套件,调 Nginxssl_ciphers时反复用。--jsonfile out.json输出结构化结果,接 CI 或巡检脚本用。输出里每条结果带严重级别(LOW/MEDIUM/HIGH/CRITICAL),比人工读终端颜色可靠得多。- 测非 443 端口直接
example.com:8443,测 STARTTLS 的邮件服务用-t smtp mail.example.com:25。
一个小坑:扫描对目标服务器是实打实的成百上千次握手,对内网设备或性能敏感的服务先掂量一下,别在高峰期对着生产数据库网关扫。
结果怎么读
输出用颜色分级,但颜色不等于行动优先级。经验上是这么排的:

必须处理的红色:证书过期或链不完整、还支持 SSLv2/SSLv3、测出 Heartbleed 这类漏洞为 VULNERABLE。这些不需要讨论,直接修。
应该处理的:接受 TLS 1.0/1.1(除非有真实的老客户端要兼容)、提供弱套件、缺 HSTS。通常改 Nginx 的 ssl_protocols 和 ssl_ciphers 就能解决,改完用 -e 复扫确认。
可以记档缓行的:比如某些 MEDIUM 级别的密码套件偏好问题、OCSP stapling 未启用。它们影响的是加固水位而不是“现在就有洞”,排进例行优化即可。
还有一类是工具自己标注的 “not vulnerable, but...” 式提示——别看到长段落就慌,先看最后的判定词。
修完之后,别让同样的问题再来一遍
扫描发现的问题里,证书过期和链不完整是复发率最高的两个,原因也简单:手动续签和手动部署迟早会忘一步。在 CertbotX 里实践的话,这类问题可以从源头绕开:证书走 ACME 自动签发,DNS-01 验证支持 CNAME 委托(把 _acme-challenge 指到专门区域,不动主 DNS 权限),到期前自动重新签发;签发后自动部署到 Agent、EdgeOne 或 CDN,避免“证书换了但某个入口没换”造成的链不一致。每次部署留有记录,事后想确认哪台机器跑了哪版证书,翻部署审计比翻聊天记录快。
核验入口
- RFC 8555:ACME 协议规范——理解自动签发和 DNS-01 验证在协议层怎么工作
- Nginx 官方 HTTPS 服务器配置文档——改
ssl_protocols、ssl_ciphers时的权威参考 - MDN:HTTP Strict Transport Security——补 HSTS 头之前先看清 preload 和 max-age 的坑