服务加载了别人的证书
同一台服务器部署多个 HTTPS 站点时,最容易出现的问题之一是某个站点引用了其他站点的证书——通常是复制 server 块后漏改证书路径,或 include 的相对路径解析到了别处。表现是访问 A 站点返回 B 站点的证书,浏览器报名字不匹配,但服务本身能正常启动,所以日志里往往什么线索都没有。按 SNI 逐个站点探测实际返回的证书主体,是定位这类问题最快的方法。
基本信息
| 典型原因 | server 块复制后未改证书路径、include 相对路径解析错误 |
|---|---|
| 验证方法 | 按 SNI 逐站点探测,比对 subject 与 SAN 是否覆盖访问域名 |
| 典型表现 | 服务不报错、浏览器报名字不匹配、日志无异常 |
| 修复动作 | 修正对应 server 块的证书路径后 reload |
| 回归要求 | 同批次的其他站点一起复核,避免只修报障域名 |
| 适用平台 | nginx、Apache、Caddy 等多站点虚拟主机环境 |
典型使用场景
- 批量上新站点:一次加多个站点后整体核对,防止路径复制错位。
- 证书轮换后复核:换证时逐一确认每个站点用的是自己的新证书。
- 迁移换机:从旧机器搬配置时路径结构不同,容易出现指向错误。
- 配置重构:整理 include 结构后确认没有引入路径歧义。
- 安全审计:确认没有站点共用同一张证书造成范围混淆。
逐站点探测实际证书
逐站点探测实际证书
for h in a.example.com b.example.com; do
echo -n "$h -> "
echo | openssl s_client -connect 127.0.0.1:443 -servername $h 2>/dev/null | openssl x509 -noout -subject -dates
done
# 同时核对 SAN 是否覆盖该域名
# echo | openssl s_client -connect 127.0.0.1:443 -servername a.example.com 2>/dev/null | openssl x509 -noout -ext subjectAltName
# 修完配置先用 -t 做语法检查再 reload现象与根因
| 现象 | 根因 | 核对方法 |
|---|---|---|
| 访问 A 返回 B 的证书 | server 块证书路径复制未改 | 逐 SNI 探测实际证书主体 |
| 首个站点正常、其余异常 | 默认 server 块抢占了证书 | 确认哪个块是默认站点 |
| 多个站点返回同一张证书 | 共用同一证书路径 | 对比各块配置中的路径 |
| 修改后仍然报错 | 客户端缓存旧结果 | 清缓存或换工具复测 |
| 只有部分网络异常 | 多节点配置不一致 | 按出口逐个探测 |
修复后要对同批次的其他站点一起复核:这类问题是复制粘贴造成的,同一批配置里往往不止一处。