IPconf
返回教程列表
安全 8 分钟阅读

SSL 证书排查清单

主机名匹配、有效期、证书链、TLS 版本、跳转和混合内容——浏览器告警出现时按这个顺序排查。

从浏览器报错开始,不要相信本地信任库

本机浏览器和 `openssl` 经年累月装了一堆信任锚、中间证书缓存、系统证书包。本机能打开的网站,别人不一定能打开。

验证时要用不共享本机信任库的环境:另一台机器、另一个系统、在线检查工具、CI runner 都行。浏览器告警才是真相,本机终端不是。

确认主机名被覆盖

证书必须列出用户实际访问的主机名——要么在 CN(已废弃但仍常见),要么在 Subject Alternative Name (SAN) 扩展中。现代浏览器已完全忽略 CN,只看 SAN。

通配符 `*.example.com` 只匹配一级。它匹配 `www.example.com` 和 `api.example.com`,但既不匹配根 `example.com`,也不匹配 `staging.api.example.com`。多级通配符是不允许的。

# 列出证书覆盖的所有主机名:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -ext subjectAltName

检查有效期和续期自动化

过期证书是最显眼的故障。Let's Encrypt 90 天,商业 CA 一般 397 天,行业趋势在缩短——续期必须自动化。

不仅看过期时间,还要确认续期任务真的在跑。一张剩 30 天但从没续过期的证书就是定时炸弹。监控的是续期日志,不是过期日期。

openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -dates
# notBefore=Jan 1 ...
# notAfter=Apr 1 ...

验证证书链完整

证书有效需要客户端能构建出一条到信任根的链。服务器必须发叶子证书 + 所有中间证书;根证书在客户端信任库里。忘配中间证书是"Chrome 能开但 iOS 打不开"最常见的原因。

从本机信任库之外测。`ssllabs.com/ssltest/` 或 `whatsmychaincert.com` 这种工具能精确报告服务器实际发了什么、缺了什么。

# 显示服务器发的完整链:
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null

# 验证链能到信任根:
curl -v https://example.com 2>&1 | grep -i "ssl\|tls\|verify"

TLS 版本与加密套件

TLS 1.0 和 1.1 已废弃,主流浏览器全部移除。TLS 1.2 是今天的下限,TLS 1.3 是默认。还允许 1.0/1.1 的话,安全扫描器和合规框架都会报红。

弱加密套件(RC4、3DES、出口级)早该清理。现在服务器默认配置基本合理,但参考老教程改的配置偶尔会复活这些。

# 探测服务器支持的协议与套件:
nmap --script ssl-enum-ciphers -p 443 example.com

# 或用 openssl:
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3

跳转与 HSTS

纯 HTTP 必须跳转到 HTTPS。验证跳转链——有时会多一跳 www 去除或末尾斜杠规范化,边缘场景会断。

HTTPS 稳定后再加 HSTS,让浏览器拒绝降级到 HTTP。注意 `preload` 指令基本是永久的,先不带 preload 跑几周再考虑加。

# 跟踪跳转链:
curl -sIL http://example.com | grep -i "location\|HTTP/"

# 检查 HSTS 头:
curl -sI https://example.com | grep -i "strict-transport-security"

混合内容

证书有效不代表浏览器会显示"完全安全"。HTML 里只要有一个 `http://` 的图片、脚本、样式表或 iframe,浏览器就会降级锁标。

搜代码里写死的 `http://` URL,换成协议相对(`//example.com/path`)或绝对 HTTPS。浏览器 DevTools → Console 会在页面加载时列出所有混合内容警告。