约 8 分钟读完 · 更新于 2026-10-21 · 文中每条都能在下面的配套工具里动手验证
浏览器把所有证书问题都显示成同一句「你的连接不是私密连接」,但背后的排查起点完全不同。先看告警文案:ERR_CERT_EXPIRED 与 ERR_CERT_DATE_INVALID 指向有效期,ERR_CERT_COMMON_NAME_INVALID 指向域名匹配,ERR_CERT_UNTRUSTED_AUTHORITY / unable to get local issuer certificate 指向证书链或根信任。分诊错了会白折腾:域名不符时反复看有效期,或者链不全时去改 DNS,都不会有任何进展。
| 报错 / 现象 | 真正的原因 | 先查哪一项 |
|---|---|---|
| ERR_CERT_DATE_INVALID / 已过期 | notAfter 已过,或本机时钟错误 | 证书有效期与服务器时间 |
| ERR_CERT_COMMON_NAME_INVALID | SAN 里没有你访问的主机名 | SAN 的 dNSName 列表 |
| unable to get local issuer certificate | 服务器只发了叶子证书,没发中间证书 | 服务器证书链拼接顺序 |
| ERR_CERT_UNTRUSTED_AUTHORITY(内网) | 自签名证书,公司根没装到客户端信任库 | 客户端信任链,不是在服务器改 |
| 浏览器报错但 curl 正常 | curl 用的是自带 CA 包,与系统/浏览器信任库不同 | 两边的 CA 来源差异 |
| 部分设备正常部分设备报错 | 中间证书缓存、CDN 节点配置不一致 | 各节点实际下发的链 |
| 只有某个域名子域名报错 | 泛域名证书不覆盖多级子域 | SAN 里是否精确列出了该子域 |
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \ | openssl x509 -noout -subject -issuer -dates -ext subjectAltName # -servername 必须带上:不带就拿不到 SNI 选中的那张证书 # 若想看服务器发出的完整链(含中间证书): openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
openssl x509 -in cert.pem -noout -subject -issuer -dates openssl x509 -in cert.pem -noout -ext subjectAltName openssl x509 -in cert.pem -noout -fingerprint -sha256 # 肉眼比对指纹,必须逐字符一致(冒号可有可无,大小写不敏感) openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \ | openssl x509 -noout -fingerprint -sha256
curl -v https://example.com 2>&1 | grep -iE "subject|issuer|expire|certificate|SSL" # -k 跳过校验,只是看内容用;不要用来"修复"问题 curl -k https://example.com # 带上自己的 CA 包,验证内网证书链是否完整 curl --cacert /etc/ssl/certs/corp-root-ca.crt https://internal.example.com
三条规则足以覆盖绝大多数域名不符问题。一、主流浏览器只检查 subjectAltName 里的 dNSName,证书 CN 里的域名只作兼容考虑,写在 CN 里但 SAN 没写的域名会直接判不匹配。二、通配符只匹配一级:*.example.com 能覆盖 a.example.com 和 b.example.com,覆盖不了 a.b.example.com;三级域名要单独签或再申请 *.b.example.com。三、IP 访问要求 SAN 里是 iPAddress 类型的条目,写成 dNSName 的 IP 字符串无效。签证书时把所有对外域名一次列全,比日后补签便宜得多。
指纹是判断「这张证书和我手上的是不是同一张」的唯一可靠依据,也是核对服务器是否真的换对了的唯一手段。优先用 SHA-256,指纹命令加 -fingerprint -sha256;SHA-1 指纹已无参考价值。换证不要一步到位,正确顺序是:先在 CA 后台签发新证书并本地验证链完整 → 部署到预发或灰度节点 → 用 s_client 确认线上返回的是新指纹 → 全量替换 → 原证书保留到所有客户端缓存过期之后再下线。同时把到期时间纳入监控告警,提前 30 天提醒;短有效期证书(90 天)配自动续期,别靠人记。
用 openssl s_client -connect 域名:443 -servername 域名 -showcerts 看响应里有没有中间证书:只有一张叶子证书就是链不全,服务器侧要部署「叶子 + 中间」的完整链。命令末尾的 </dev/null 不能省,否则会挂住等交互输入。
两种常见原因:一是本机或服务器时钟偏差,让有效期判断失效;二是报错根本不是有效期问题,而是域名不符或链不全——浏览器把所有证书错误都显示成同一句话。先看具体告警代码,再看 SAN 和链,别直接归因到过期。
不能。通配符只匹配一级标签。要覆盖 a.b.example.com,需要单独签发该域名,或再申请一张 *.b.example.com 证书。IP 访问同理,SAN 里必须是 iPAddress 类型的条目才算数。
用 SHA-256。SHA-1 已有可构造的碰撞,核对值本身不再可靠,主流浏览器也不再接受 SHA-1 签发的证书。计算方式是 openssl x509 -in cert.pem -noout -fingerprint -sha256,两边的输出逐字符比对即可。