排错指南

关闭 TLS 1.0 / 1.1,只留 1.2 和 1.3

服务器还在使用 TLS 1.0 或 1.1 协商连接。

TLS 1.0 和 1.1 在 2020 年就被 Chrome、Firefox、Safari、Edge 集体废弃了,PCI DSS 也要求禁用 TLS 1.0。现在正确的配置是只保留 TLS 1.2 和 1.3

改动很小 —— nginx 一行,Apache 一行。真正需要判断的是兼容性代价:确认没有还在用老客户端的调用方,再动手。

改配置

nginx

nginx.conf
ssl_protocols TLSv1.2 TLSv1.3;

# TLS 1.3 时代,让客户端选套件通常比服务器强制更好
ssl_prefer_server_ciphers off;

TLS 1.3 需要 nginx 1.13.0 以上并链接 OpenSSL 1.1.1 以上。nginx -V 能看到编译时用的 OpenSSL 版本;如果偏低,写上 TLSv1.3 不会报错,但也不会生效。

Apache

httpd.conf / vhost
SSLProtocol -all +TLSv1.2 +TLSv1.3

-all 先全部关掉再逐个打开,比逐个 -TLSv1 排除更不容易漏 —— 后者在升级 Apache 后新增的协议版本会默认打开。

密码套件要不要一起调

多数情况下不用。手写套件列表是最容易配错、也最容易过时的一处:抄一份两年前的「安全配置」,往往同时关掉了现代客户端需要的套件。需要调的时候用 Mozilla 的 intermediate 档配置生成,不要自己列。

改完照例先测语法再重载:

nginx -t && nginx -s reload
# 或
apachectl configtest && apachectl graceful

谁会被挡在外面

这是唯一需要认真评估的部分。只支持 TLS 1.0/1.1 的客户端:

客户端情况
Android 4.4 及更早系统栈不支持 TLS 1.2
IE 10 及更早(Windows 7)不支持;IE 11 支持但可能需要手动勾选
Windows XP / Vista系统层面就没有 TLS 1.2
Java 6、Java 7支持但默认不启用,需要调用方改启动参数
.NET Framework 4.5 及更早默认不用 TLS 1.2,需要调用方改代码
很老的 curl / OpenSSL 0.9.8不支持

对面向公众的网站来说,这几类加起来的占比现在已经可以忽略。真正的风险在服务端到服务端的调用:某个合作方的老系统、某台多年没动过的内部机器、某个用旧 Java 写的对接程序。这些不会出现在浏览器统计里,出问题时也不会有人来告诉你,只会静默失败。

所以顺序是:先在访问日志里确认还有没有 TLS 1.0/1.1 的连接,再改。nginx 可以把协议版本打进日志:在 log_format 里加上 $ssl_protocol,观察几天。

nginx.conf
log_format tlsver '$remote_addr $ssl_protocol $ssl_cipher "$request"';
access_log /var/log/nginx/access.log tlsver;

怎么确认真的关掉了

逐个版本单独建连,最直接:

# 应该失败(handshake failure)
openssl s_client -tls1   -connect example.com:443 -servername example.com </dev/null
openssl s_client -tls1_1 -connect example.com:443 -servername example.com </dev/null

# 应该成功
openssl s_client -tls1_2 -connect example.com:443 -servername example.com </dev/null
openssl s_client -tls1_3 -connect example.com:443 -servername example.com </dev/null

如果本机是 OpenSSL 3.x,前两条可能因为本机的安全等级就拒绝了,而不是因为服务器拒绝 —— 这两种失败长得很像。加上 -cipher 'DEFAULT@SECLEVEL=0' 可以把本机限制放开,让失败真正来自对端。

为什么本站的检测只报「协商到的版本」

值得说清楚,因为它决定了这个结论该怎么用:一次握手只会协商出一个版本,而我们提供的是现代版本,所以正常情况下会协商到 TLS 1.2 或 1.3。也就是说 ——

  • 检测报出 TLSv1TLSv1.1,说明服务器最高只支持到这个版本,问题确凿。
  • 检测报出 TLSv1.3,只能说明它支持 1.3,不能说明它已经关掉了 1.0 —— 一台同时支持 1.0 到 1.3 的服务器在我们这里看起来是干净的。

要判断第二种情况,必须每个版本单独建一次连接,也就是上面那四条命令。我们没有把它做进默认检测,是因为那意味着每次检测多开四个连接、对被检测的服务器多四倍的握手成本,而这一项并不是导致访客打不开网站的故障。

常见问题

检测一下你自己的域名

免登录,一次真实的 TLS 握手,直接给出结论:还有多少天到期、证书链是否完整、是否包含这个域名。

需要一张新证书?本站提供基于 Let's Encrypt 的免费签发,支持泛域名。

了解免费证书

其他排错指南

Last updated on