浏览器能打开、curl 却报 unable to get local issuer:中间证书链断了

同样的 HTTPS 站点,浏览器正常而 curl、Java 客户端却报证书错误,多半是服务器没发完整证书链。本文解释中间证书的作用、为什么会漏发,以及如何排查和修复。

本文目录
浏览器能打开、curl 却报 unable to get local issuer:中间证书链断了

运维群里很经典的一幕:同事说"网站证书坏了,curl 报 unable to get local issuer certificate",你打开浏览器一看,绿色小锁,一切正常。两边都没说谎,问题出在中间证书上。

证书链是怎么回事

CA 一般不用根证书直接签你的网站证书,而是通过一张或多张中间证书来签。链是这样的:

根证书(预置在客户端的信任库里)
  └─ 中间证书(需要服务器在握手时发出来)
       └─ 你的服务器证书(leaf / end-entity)

TLS 握手时,服务器应该把自己的证书连同中间证书一起发给客户端。客户端拿着叶子证书,逐级验证签名,直到撞上自己信任库里的一张根证书,链就接上了。

为什么浏览器"看起来没事"

浏览器比命令行客户端宽容得多,主要靠两招:

  • 缓存:你之前访问过同一家 CA 的其他站点,浏览器很可能已经把中间证书存进缓存了,这次直接拿来用。
  • AIA fetching:很多证书里带一个 Authority Information Access 扩展,里面写着中间证书的下载地址。Chrome 会自己去把它抓回来补上。

curl、OpenSSL、Go、Java 这些客户端大多不做 AIA fetching,也没有那种缓存。服务器少发一张中间证书,它们就验证失败。所以你会看到"浏览器全绿、API 调用全红"的诡异分裂——不是客户端矫情,是它们照章办事。

什么时候会遇到

  • 刚换新证书:运维只把 cert.pem(叶子证书)传了上去,忘了拼接 fullchain.pem。Let's Encrypt、Certbot 输出的 fullchain.pem 就是叶子 + 中间打包好的,用它就对。
  • 配置 SSL termination 的设备或网关:F5、某些负载均衡、API 网关上传证书时,中间证书是单独一个字段,很容易漏。
  • Java 服务互相调用:JVM 的信任库管理严格,缺中间证书立刻报 PKIX path building failed,这行报错几乎可以当成"链不完整"的同义词。
浏览器能打开、curl 却报 unable to get local issuer:中间证书链断了:an ACME request being validated at separate stations and turned into a new deployable artifact while private key material remains at its origin
浏览器能打开、curl 却报 unable to get local issuer:中间证书链断了:an ACME request being validated at separate stations and turned into a new deployable artifact while private key material remains at its origin查看原图

怎么排查和修

先看服务器实际发了什么:

openssl s_client -connect example.com:443 -servername example.com

输出里 Certificate chain 一段会列出服务器发了几张证书。如果只有一张(编号 0,即叶子证书),中间证书就是漏了。也可以看 Verify return code,21 (unable to verify the first certificate) 基本就是这个病。

修复方式取决于组件:

  • Nginx:ssl_certificate 指向完整链文件(叶子在前,中间在后拼接),不要用只含叶子的 cert.pem。
  • Apache:新版本把链并到 SSLCertificateFile 里,老版本用 SSLCertificateChainFile。
  • 负载均衡 / 网关:找到"中间证书"或"CA bundle"字段单独上传。

在 CertbotX 中实践

用 CertbotX 做 ACME 自动签发时,平台取回的是完整链并在部署到 Agent、EdgeOne 或 CDN 时一并下发,不会出现"只部署了叶子证书"这种半截子情况。每次部署都有记录可查,出问题时能回看当时推下去的是哪份链文件,排查链不完整这类问题会省掉不少猜的时间。

一个容易踩的小坑

链的顺序有讲究:叶子证书必须在最前,后面按签发顺序排中间证书。顺序拼反了,有的客户端容错,有的直接报错——又是"我这边好的你那边坏的"的经典剧本。另外注意别把根证书塞进链里,没必要,有的客户端还会因此报错。

---

← 返回资讯中心