SSL/TLS证书不受信任的故障排查与修复指南

0 次阅读

SSL/TLS证书不受信任的故障排查与修复指南

SSL/TLS证书不受信任是网站访问、API调用、服务器通信中非常常见的一类安全故障。用户浏览器可能提示“您的连接不是私密连接”“证书不受信任”,应用程序可能出现“certificate verify failed”“unable to get local issuer certificate”等错误。此类问题不仅影响用户访问体验,还可能导致服务之间的HTTPS通信失败。

SSL/TLS证书不受信任通常并不是证书本身失效,而是客户端无法建立完整、可信的证书验证链。造成问题的原因包括证书过期、证书链配置错误、根证书缺失、域名不匹配、服务器配置异常以及客户端环境问题等。

SSL/TLS证书验证机制简介

理解证书不受信任问题,需要先了解HTTPS证书验证流程。

当客户端访问HTTPS服务时,会执行以下验证步骤:

  1. 服务器返回SSL/TLS证书。

  2. 客户端检查证书是否由可信的证书颁发机构(CA)签发。

  3. 客户端验证证书链是否完整。

  4. 检查证书有效时间是否正常。

  5. 检查证书中的域名是否与访问地址匹配。

  6. 验证证书签名是否可信。

任何一个环节失败,都可能导致SSL/TLS证书不受信任。

例如,一个网站使用由某CA签发的服务器证书,但服务器没有配置中间证书,那么浏览器可能无法找到完整验证路径,即使证书本身有效,也会显示“不受信任”。

常见的SSL/TLS证书不受信任原因

1. 证书已经过期

证书具有明确的有效期限,例如:

  • Not Before:证书生效时间

  • Not After:证书过期时间

如果当前时间超过Not After时间,客户端会直接拒绝信任该证书。

检查方法:

openssl x509 -in server.crt -noout -dates

输出类似:

notBefore=Jan 01 00:00:00 2026 GMT
notAfter=Jan 01 00:00:00 2027 GMT

如果证书已经过期,需要重新申请或续期。


2. SSL证书链配置不完整

这是生产环境中最常见的问题之一。

一个完整HTTPS证书链通常包含:

服务器证书
    ↓
中间CA证书
    ↓
根CA证书

服务器通常只需要配置服务器证书和中间证书,而根证书由客户端系统维护。

如果Nginx、Apache等服务器只配置了服务器证书:

ssl_certificate server.crt;

而缺少:

ssl_certificate intermediate.crt;

客户端可能无法完成验证。

正确方式通常是合并证书链:

cat server.crt intermediate.crt > fullchain.crt

然后配置:

ssl_certificate /etc/nginx/ssl/fullchain.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;

修改后重新加载Nginx:

nginx -t
systemctl reload nginx

3. 域名与证书不匹配

SSL/TLS证书绑定的是域名,而不是服务器IP。

例如:

证书申请:

example.com

访问:

www.example.com

如果证书没有包含www子域名,就会出现验证失败。

可以通过以下命令查看证书支持域名:

openssl x509 -in certificate.crt -text -noout

重点查看:

Subject Alternative Name

例如:

DNS:example.com
DNS:www.example.com

如果访问域名不在列表中,需要重新申请包含正确域名的证书。


4. 客户端缺少根证书

部分旧系统、精简Linux发行版、容器环境可能缺少CA根证书。

例如Docker容器中运行Python程序:

requests.exceptions.SSLError:
certificate verify failed

可能原因就是系统CA库不存在。

Linux系统可以安装CA证书:

Debian/Ubuntu:

apt update
apt install ca-certificates
update-ca-certificates

CentOS/RHEL:

yum install ca-certificates
update-ca-trust

安装完成后重新运行应用。


5. 系统时间错误

SSL证书验证依赖系统时间。

如果服务器时间错误,例如:

当前时间:

2026年

系统时间:

2020年

证书可能被判断为“尚未生效”。

检查时间:

date

同步时间:

timedatectl set-ntp true

或者使用NTP服务同步:

systemctl restart chronyd

6. 使用自签名证书

企业内部系统、测试环境经常使用自签名证书。

例如:

Issuer: localhost
Subject: localhost

由于该证书没有受到公共CA机构签名,浏览器和第三方客户端默认不会信任。

解决方案:

  • 测试环境:将自签名根证书导入客户端信任列表。

  • 生产环境:使用正规CA签发证书。


SSL/TLS证书故障排查流程

面对证书不受信任问题,可以按照以下顺序排查。

第一步:确认服务器返回的证书

使用OpenSSL检查:

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

重点观察:

Verify return code

例如:

正常:

Verify return code: 0 (ok)

异常:

unable to get local issuer certificate

说明证书链存在问题。


第二步:检查证书有效期

执行:

openssl s_client -connect example.com:443 /dev/null | openssl x509 -noout -dates

确认:

  • 是否过期

  • 是否提前生效


第三步:检查证书链

查看完整链:

openssl s_client -connect example.com:443 -showcerts

正常情况下应该返回:

Certificate
Certificate
Certificate

如果只有一个服务器证书,通常表示中间证书没有配置。


第四步:检查域名匹配

执行:

openssl x509 -in cert.pem -text -noout

确认:

Subject Alternative Name

包含访问域名。


第五步:检查客户端环境

如果浏览器正常,但程序报错,需要检查:

  • 操作系统CA库

  • Java truststore

  • Python证书环境

  • Docker镜像中的CA包

例如Java:

keytool -list -keystore cacerts

Python:

import certifi
print(certifi.where())

查看使用的CA文件。


不同环境中的修复方案

Nginx修复证书不受信任

常见配置错误:

错误:

ssl_certificate server.crt;

正确:

ssl_certificate fullchain.pem;
ssl_certificate_key private.key;

重新检查:

nginx -t

然后:

systemctl reload nginx

Apache修复方案

配置:

SSLCertificateFile certificate.crt
SSLCertificateChainFile chain.crt
SSLCertificateKeyFile private.key

修改后:

systemctl restart apache2

Docker环境修复方案

Docker镜像可能没有安装CA证书。

Ubuntu基础镜像:

RUN apt-get update && apt-get install -y ca-certificates

Alpine:

RUN apk add --no-cache ca-certificates

重新构建镜像:

docker build -t app .

Java应用证书修复方案

Java使用自己的证书仓库:

$JAVA_HOME/lib/security/cacerts

导入证书:

keytool -importcert 
-alias mycert 
-file ca.crt 
-keystore cacerts

然后重启Java服务。


如何避免SSL/TLS证书故障

定期监控证书有效期

建议提前30天检查证书状态。

可以使用自动化工具:

  • 定期扫描HTTPS服务

  • 配置证书到期提醒

  • 使用自动续期机制

例如Let's Encrypt证书可以通过Certbot自动续期:

certbot renew

保证证书链完整

部署证书时不要只上传服务器证书,应优先使用:

fullchain.pem

避免因缺少中间证书导致客户端验证失败。


保持系统CA库更新

服务器、容器、开发环境都应该定期更新:

apt update