公告
记得每天来更新数据哦,更新站点排名靠前。
本店目前百度权重2;谷歌权重2;根据中国站长数据为准;加入VIP快审自助服务 15元/站,软文快审自助服务10元/篇;
截至今日,处置违规站点790站,文章违规1147条,会员违规50位。

SSL证书链缺中间证书:为什么Chrome能打开而curl报错?原因与排查方法

2026-11-03 13:59 2 次浏览 来源:A5站长

手机端有用户反馈打不开,提示证书有问题。桌面Chrome打开同一个域名,地址栏是正常的小锁。curl跑一遍,报unabletogetlocalissuercertificate。你换一台安卓机试,同样报错。iPhone上的Safari倒是正常,看起来跟客户端有关。浏览器验证证书时会顺着签发关系往上找

手机端有用户反馈打不开,提示证书有问题。桌面Chrome打开同一个域名,地址栏是正常的小锁。curl跑一遍,报unable to get local issuer certificate。你换一台安卓机试,同样报错。iPhone上的Safari倒是正常,看起来跟客户端有关。

浏览器验证证书时会顺着签发关系往上找,服务器只发自己的证书,中间那张由浏览器自己去下载,这个机制叫AIA。桌面Chrome、Safari和Windows的信任库会顺着AIA补链,所以缺了也能过。Firefox不做这个补救。curl、Java、Android上的老版本、还有各类SDK不做这个补救,链断了就直接报错。服务器要发的是完整链,自己的证书在前,中间证书在后,根证书不用发,对方系统里本来就有。根证书在操作系统或者浏览器的信任库里,中间证书不在。签发机构一般会把它放在下载页,文件名带chain或者ca-bundle,下载后跟自己那张拼起来用。

证书链不完整还表现在另一些地方。微信内置浏览器、小程序请求、iOS上的部分版本,报错信息各不相同,有的是证书无效,有的是握手失败。同一张证书在电脑上好好的,在手机上出问题,先怀疑链。安卓上的okhttp对链的要求比系统浏览器严,缺一张就断。

openssl s_client的-connect参数填域名和443端口,后面加-showcerts,就能看到服务器发了几张证书。输出里每张以-----BEGIN CERTIFICATE-----开头,正常的应该有两张,只有一张就是缺中间证书。加上-servername参数指定SNI,多域名服务器上才测得准。输出里还有一个verify return code,0表示验证通过,20是unable to get local issuer certificate,21是unable to verify the first certificate。后两个都指向链不完整。

修复是把中间证书拼到服务器证书后面,顺序不能反。cat server.crt intermediate.crt > fullchain.crt,然后ssl_certificate指向fullchain.crt。中间证书从签发机构的仓库下载,别用别的站抓来的,版本要对得上。拼接前先确认两张证书都是PEM格式,里面是-----BEGIN CERTIFICATE-----开头的文本。DER格式是二进制,直接cat会得到一堆乱码,nginx加载时报PEM_read_bio_X509_AUX() failed,提示no start line。格式转换用openssl的x509命令,-inform DER指定输入格式。

顺序反了同样失败,报错跟缺证书差不多。拼完用openssl再跑,两张证书的subject和issuer要能接上,第一张的issuer等于第二张的subject。这个检查用两条命令做,openssl x509 -noout -subject -issuer分别看两张证书的字段,肉眼对一遍就行。

在线检测也能看,SSL Labs的测试报告里有一节chain issues,缺中间证书会明确写出来。这个检测从多个客户端视角验,比自己在一台机器上试全面。检测跑完要等几分钟,免费的公开报告会留在搜索结果里,介意的话用付费版或者本地脚本测。

换完证书链,curl和手机都正常了,桌面浏览器没有变化。证书这类问题按客户端分开测,只在一个浏览器上验证,很容易漏。安卓、iOS、curl、Java各测一次,都过才算修好。顺手把检测脚本存档,下次换证书照着跑一遍。