SSL证书链不完整怎么办?检测中间证书、部署fullchain与排错方法

SSL 证书链不完整,常见表现是电脑浏览器可以打开,旧版手机、接口客户端或某些小程序却提示“不受信任”“无法验证颁发者”或 TLS 握手失败。问题通常不是域名没有证书,而是服务器只发送了站点证书,没有把客户端建立信任路径所需的中间证书一并发送。

处理时应先确认真正终止 HTTPS 的节点,再检查服务器发出的证书列表、域名匹配、有效期和验证结果。不要看到浏览器地址栏有锁就直接认定证书链完整。

先理解站点证书、中间证书和根证书

证书层级作用服务器通常是否发送
站点证书证明当前域名对应的公钥和证书主体,也叫叶子证书必须发送
中间证书把站点证书连接到受信任根证书通常需要随站点证书发送
根证书由操作系统、浏览器或客户端信任库预置通常不需要服务器发送

一条完整路径通常是“站点证书 → 一个或多个中间证书 → 客户端信任的根证书”。不同客户端自带的中间证书缓存和根证书库不同,因此链缺失时可能出现“有人正常、有人报错”。

第一步:找到真正提供 HTTPS 的节点

使用 CDN、WAF、负载均衡或反向代理时,用户看到的证书通常来自边缘节点,不一定来自源站 Nginx。先沿访问链路确认 TLS 在哪里终止:

  • 域名是否直接解析到当前服务器,还是指向 CDN/WAF 的 CNAME。
  • 负载均衡、面板站点和源站是否分别配置了证书。
  • 同一 IP 上有多个 HTTPS 站点时,SNI 是否把域名送到正确虚拟主机。
  • 浏览器看到的新证书是否与刚刚修改的文件一致,避免改了源站却仍由边缘节点提供旧链。

域名、端口和反向代理的边界可参考域名解析与端口实现方法;若不确定问题处在哪一层,可按域名状态分层监测清单依次检查 DNS、连接、HTTPS 和页面。

第二步:查看服务器实际发送了哪些证书

OpenSSL 的 s_client 可以直接连接目标,并用 SNI 指定域名:

openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null

重点查看 Certificate chain 和末尾的验证提示。-showcerts 展示的是服务器实际发出的证书列表,OpenSSL 官方文档明确说明它本身不是一条已经验证通过的证书链。若需要在错误时直接返回失败,可增加验证选项:

openssl s_client -connect example.com:443 -servername example.com \
  -verify_hostname example.com -verify_return_error </dev/null
  • 只有编号 0 的站点证书:通常说明服务器没有发送中间证书。
  • unable to get local issuer certificate:客户端无法从已收到的证书构建到受信任颁发者,常见于中间证书缺失或不正确。
  • hostname mismatch:访问域名不在证书允许的名称中,这不是补中间证书能解决的问题。
  • certificate has expired:证书已过期,要续签并部署新证书,而不是只调整链顺序。
  • 某些网络正常、某些网络异常:继续比较不同客户端、IPv4/IPv6、CDN 节点和 SNI 返回的证书,避免只测一个入口。

第三步:取得正确的 fullchain 文件

优先使用证书颁发机构或自动化客户端提供的完整链文件,常见名称包括 fullchain.pemcertificate_bundle.crt 或“证书链”。不要从不明网站下载中间证书,也不要把私钥粘贴到在线检测工具。

对于 Nginx,组合文件的顺序应当是站点证书在前,随后是中间证书。Nginx 官方文档给出的思路是把已签发的站点证书与 CA 提供的链文件按此顺序合并:

cat site.crt intermediate-bundle.crt > fullchain.pem

如果有多个中间证书,也应按从站点证书向根证书延伸的顺序排列。根证书通常已经存在于客户端信任库,不必为了“看起来完整”重复放进服务器链。

第四步:在 Nginx 中部署并验证

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate     /path/to/fullchain.pem;
    ssl_certificate_key /path/to/private.key;
}

ssl_certificate 指向包含站点证书和中间证书的完整链文件,ssl_certificate_key 单独指向匹配的私钥。保存后先检查配置,再平滑重载:

nginx -t
nginx -s reload

不要在未通过 nginx -t 时直接重启。链文件顺序错误、证书与私钥不匹配、文件权限不正确或路径拼写错误,都可能让配置校验失败。重载成功后,应再次从外部网络运行 OpenSSL 检查,而不是只看面板里显示“已部署”。

玩创时代 SSL 证书基础指南配图
SSL 证书启用后仍需检查域名、有效期和完整证书链。基础概念可继续阅读站内的 SSL 证书指南。

使用 CDN、面板或负载均衡时怎么处理

场景应检查的位置常见遗漏
CDN/WAF边缘证书配置和回源 HTTPS 配置只更新源站,边缘仍发送旧证书或缺失链
宝塔等面板当前站点绑定域名、证书内容和实际 Nginx 配置证书粘贴框只填了站点证书,没有填完整链
云负载均衡监听器绑定的证书、SNI 规则和后端协议修改了错误监听器或默认证书
多服务器每个节点和每条 IPv4/IPv6 路径部分节点续期成功,其他节点仍使用旧链

证书链修复后仍报错的排查顺序

  1. 确认访问域名与证书 SAN 中的名称匹配,测试时带上正确 SNI。
  2. 确认当前时间正确,证书未过期、尚未生效等时间问题不存在。
  3. 核对线上实际返回的证书指纹和序列号,确保流量已经到达修改后的节点。
  4. 分别测试 IPv4、IPv6、CDN 节点和备用服务器,排除配置不一致。
  5. 检查客户端信任库是否过旧,尤其是旧系统、Java 运行环境和嵌入式设备。
  6. 查看服务端和客户端 TLS 错误日志,区分链问题、协议版本、密码套件和双向证书问题。
  7. 续期自动化完成后增加外部验证,避免“证书文件已更新但服务未加载”。

常见问题

为什么 Chrome 正常,接口请求却失败?

浏览器可能缓存过中间证书,或者不同客户端使用不同信任库。接口客户端如果只依赖服务器本次发送的证书,更容易暴露链缺失。应修复服务器链,而不是要求每个客户端手工导入中间证书。

fullchain.pem 里需要包含私钥吗?

不需要,也不应该。fullchain 通常只包含公开的站点证书和中间证书;私钥应单独保存、严格限制读取权限,并通过 ssl_certificate_key 配置。

证书链完整就代表 HTTPS 一定安全吗?

不是。完整链只解决信任路径问题,还要检查私钥保护、域名匹配、证书有效期、协议和密码套件、HSTS、应用漏洞以及 CDN 与源站配置。SSL 基础概念可查看网站 SSL 证书指南

总结

修复 SSL 证书链不完整,核心是确认 HTTPS 终止节点,查看服务器实际发送的证书,取得 CA 提供的正确中间证书,并按“站点证书在前、中间证书在后”的顺序部署 fullchain。修复后要从外部、带正确 SNI 再次验证,并检查所有 CDN、负载均衡和多节点入口。

官方参考

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享
评论 抢沙发

    暂无评论内容