SSL证书链不完整导致浏览器不信任的排查与修复
什么是证书链不完整
浏览器报”证书错误”或”连接不安全”,但证书明明没过期、域名也对——大概率是证书链不完整。
SSL证书不是单独一张证书,而是一条信任链:
根证书(CA Root) → 中间证书(Intermediate) → 你的网站证书(Server Cert)
浏览器只内置了根证书。你的网站证书是中间证书签发的,服务器必须同时发送”网站证书 + 中间证书”,浏览器才能验证到根证书完成信任链。
少发中间证书,浏览器就不知道你的证书是谁签的,报”未知颁发机构”或”证书链不完整”。
如何判断证书链是否完整
方法一:在线工具
访问 https://whatsmychaincert.com/ ,输入域名,工具会自动检测:
- •✅ Chain complete: 证书链完整
- •⚠️ Chain incomplete: 缺少中间证书
方法二:OpenSSL 命令行
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | grep -E "depth|verify"
完整证书链的输出:
verify depth is 2
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
depth=1 C = US, O = Let's Encrypt, CN = R3
depth=0 CN = example.com
Verify return code: 0 (ok)
缺中间证书的输出:
verify depth is 2
depth=0 CN = example.com
Verify return code: 20 (unable to get local issuer certificate)
depth=0 后面没有 depth=1,说明服务器没发中间证书。
方法三:浏览器查看
Chrome → 地址栏锁标 → 证书 → “证书路径”标签页:
- •完整链:能看到三层(根 → 中间 → 你的证书)
- •不完整:只显示一层(你的证书),或者顶部标红
修复方法
第一步:下载中间证书
从CA官网下载。各家CA的中间证书下载地址:
- •Let’s Encrypt: https://letsencrypt.org/certificates/
- •ZeroSSL: 申请成功时邮件附件或后台下载页有
- •DigiCert: https://www.digicert.com/digicert-root-certificates.htm
从证书本身提取(如果之前有完整链的备份):
# 查看证书的颁发者
openssl x509 -in server.crt -noout -issuer
输出类似 issuer=C = US, O = Let's Encrypt, CN = R3,说明中间证书是 R3。
第二步:合并证书
关键规则:fullchain 文件按网站证书在前、中间证书在后的顺序拼接,根证书不要加(浏览器自带)。
cat server.crt intermediate.crt > fullchain.crt
或者用文本编辑器打开,按顺序粘贴:
-----BEGIN CERTIFICATE-----
(你的网站证书内容)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(中间证书内容)
-----END CERTIFICATE-----
顺序不能反。如果中间证书在前,部分浏览器会报错。
第三步:服务器配置使用 fullchain
Nginx 配置
把 ssl_certificate 指向 fullchain 文件:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/fullchain.crt; # 用fullchain
ssl_certificate_key /etc/nginx/ssl/server.key;
# 其他配置...
}
常见错误:配置成 ssl_certificate server.crt;(只有网站证书),缺中间证书。必须用fullchain。
重载Nginx:
nginx -t && systemctl reload nginx
Apache 配置
<VirtualHost *:443>
ServerName example.com
SSLCertificateFile /etc/apache2/ssl/fullchain.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
# Apache 2.4.8+ 不再需要 SSLCertificateChainFile
</VirtualHost>
Apache 2.4.8 以上版本直接用 SSLCertificateFile 指向 fullchain 即可,老的 SSLCertificateChainFile 指令已废弃。
重载Apache:
apachectl configtest && systemctl reload apache2
验证修复效果
重新用 OpenSSL 检查:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | grep -E "depth|verify"
应该看到三层 depth 且 Verify return code: 0 (ok)。
或者再用 whatsmychaincert.com 检测一次,确认显示 ✅ Chain complete。
acme.sh / certbot 用户注意
用acme.sh或certbot申请的证书,默认就生成了fullchain文件,不会有这个问题。
acme.sh 的文件结构:
- •
~/.acme.sh/example.com/example.com.cer— 仅网站证书 - •
~/.acme.sh/example.com/fullchain.cer— 完整链,配置Nginx用这个 - •
~/.acme.sh/example.com/example.com.key— 私钥
坑点:如果误把 .cer(仅网站证书)当 fullchain 用,就会出现证书链不完整。Nginx 配置里一定要用 fullchain.cer。
常见错误排查
错误1:合并后证书报错 “unable to load certificate”
PEM格式之间没换行,或Base64内容被截断。每个证书块前后都要有空行,且 -----BEGIN/END----- 标记完整。
错误2:部分浏览器正常,部分浏览器报错
老浏览器或非主流浏览器可能不缓存中间证书。完整链能解决所有浏览器问题。
错误3:证书链过长
不要把根证书也加进 fullchain。浏览器内置了根证书,多加反而浪费带宽,部分服务器还会报错。
—
证书链不完整是HTTPS配置最常见的错误之一。用fullchain替代单证书文件,一次解决所有”证书不信任”问题。