如何解决网站SSL证书链不完整

更新时间:
复制 MD 格式

证书链由根证书、中间证书和SSL证书(服务器证书)组成。如果缺少中间证书或根证书,当您访问业务网站时,浏览器可能会提示建立连接失败或其他错误。您可以按照本文的操作指引来检查证书链是否完整,并处理不完整的证书链。

步骤一:检查SSL证书链完整性

在服务器上执行以下命令,检查证书链的完整性。该操作可以直接在服务器上执行,无需等待网站接入完成。

  • <Server_IP>:替换为服务器的实际IP地址。

  • <Domain_Name>:替换为网站的实际域名。

openssl s_client -connect <Server_IP>:443 -servername <Domain_Name>

openssl s_client -connect <Server_IP>:443 -servername <Domain_Name>命令的输出中,Certificate chain 部分列出证书链的层级,depth 表示证书层级(depth 0 为域名证书,depth 1 及以上为中间证书或根证书),Verify return code 表示证书链验证结果。可通过对比以下两种输出示例判断证书链是否完整。

完整证书链输出示例(证书链完整,Verify return code 为 0):

depth=2 O = GlobalSign, CN = GlobalSign
verify return:1
depth=1 C = BE, O = GlobalSign nv-sa, CN = GlobalSign RSA OV SSL CA 2018
verify return:1
depth=0 C = CN, CN = www.example.com
verify return:1
CONNECTED(00000003)
---
Certificate chain
 0 s:C = CN, CN = www.example.com
   i:C = BE, CN = GlobalSign RSA OV SSL CA 2018
 1 s:C = BE, O = GlobalSign nv-sa, CN = GlobalSign RSA OV SSL CA 2018
   i:O = GlobalSign, CN = GlobalSign
---
...
Verify return code: 0 (ok)

不完整证书链输出示例(缺少中间证书,仅返回域名证书,Verify return code 为 21):

depth=0 C = CN, CN = www.example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
---
Certificate chain
 0 s:C = CN, CN = www.example.com
   i:C = BE, CN = GlobalSign RSA OV SSL CA 2018
---
...
Verify return code: 21 (unable to verify the first certificate)

对比两组输出:完整证书链的 Certificate chain 中包含多条 depth(域名证书之外还有中间证书、根证书),且 Verify return code 为 0;不完整证书链的 Certificate chain 中仅有 depth 0(域名证书),同时出现 verify error(例如错误码 20、21),Verify return code 也非 0。因此,如果命令输出中仅包含域名证书(depth 0)而缺少中间证书(depth 1 及以上),或 Verify return code 不为 0,则说明证书链不完整。

---
Certificate chain
 0 s:C = CN, ST = Beijing, O = "xxx Technology Co., Ltd", OU = service operation department, CN = www.xxx.com
   i:C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
 1 s:C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
   i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
---

如果域名证书和中间证书存放在同一文件中,请确保两者之间不包含任何空格或回车字符。

-----BEGIN CERTIFICATE-----
MIIJBzCCB++gAwIBAgIJAJGNv9rVgB8rMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYD
......
6616mkcOi0SU770=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEODCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
......
LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB
-----END CERTIFICATE-----

步骤二:重新下载证书并配置证书

根证书或中间证书缺失的场景示例

说明

本场景以 Windows Server 2008R2 版本为例。

报错信息

"证书链中的一个或多个中间证书丢失。"

问题原因

Windows Server 2008R2 版本较老,服务器自身的证书库中缺少用于验证新签发证书的根证书,需要手动在服务器中安装根证书。

场景示例:浏览器访问正常,但 curl、Postman、微信小程序报错

SSL 证书续期或更换后,使用浏览器访问网站正常,但通过 curl、Postman 或微信小程序等工具访问时,报错提示 "Connection reset by peer" 或 "unable to get local issuer certificate"。

问题原因

浏览器内置了 AIA(Authority Information Access,权威信息访问)机制,当证书链中缺少中间证书时,浏览器会通过证书中的 AIA URL 自动下载缺失的中间证书以补全信任链,因此浏览器访问不受影响。而 curl、Postman、微信小程序等工具不具备 AIA 自动补链能力,无法在缺少中间证书的情况下完成证书链验证,因此会报错。

诊断方法

在服务器上执行以下命令,检查证书链的完整性:

openssl s_client -connect <Server_IP>:443 -servername <Domain_Name> -showcerts

如果命令输出的证书链(Certificate chain)仅显示 1 层(只有 depth 0 的域名证书),说明证书链中缺少中间证书。

解决方案

  1. 将域名证书和中间证书按顺序拼接为一个完整的证书链文件(域名证书在前,中间证书在后,两者之间不包含空格或回车字符)。

  2. 修改 nginx 配置文件,将 ssl_certificate 参数指向拼接后的完整证书链文件:

    ssl_certificate /path/to/full-chain.pem;
  3. 执行以下命令重新加载 nginx 配置:

    nginx -s reload
  4. 重新执行诊断命令,确认证书链已包含中间证书,且 curl、Postman、微信小程序均能正常访问。