证书管理面板显示“有效”,浏览器却仍然报“连接不安全”,这类问题经常被误判为证书没有续期。证书过期只是其中一种原因。用户实际收到的证书可能来自另一台服务器,证书的域名覆盖范围可能不对,中间证书也可能没有完整发送。
排查时不要只看服务器上的证书文件,也不要只在自己电脑上刷新页面。需要确认三个对象:浏览器访问的具体域名、该域名当前解析和经过的节点、握手时服务器实际返回的完整证书链。只要其中一项和预期不一致,证书剩余时间再长也会报错。

先记录浏览器给出的错误类型
浏览器证书错误页面通常会给出错误代码。不同代码对应的方向不同,先把代码和发生问题的域名记下来:
ERR_CERT_DATE_INVALID:证书已过期、尚未生效,或者客户端时间明显不正确;ERR_CERT_COMMON_NAME_INVALID:访问域名没有被证书的 Subject Alternative Name(SAN)覆盖;ERR_CERT_AUTHORITY_INVALID:证书链不完整、签发机构不受信任,或被代理设备替换了证书;- 只有部分地区、网络或设备报错:优先检查 CDN 节点、多台源站、IPv4/IPv6 返回结果和旧设备兼容性。
同时确认报错的是 example.com、www.example.com 还是某个二级域名。它们是不同的主机名。证书覆盖 example.com,并不自动代表覆盖 www.example.com;通配符 *.example.com 通常也不覆盖根域名 example.com,而且只匹配一层子域名。
用 OpenSSL 查看用户实际收到的证书
在 Linux、macOS 或安装了 OpenSSL 的终端运行:
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
这里的 -servername 会在 TLS 握手中发送 SNI。共享 IP 上可能托管多个 HTTPS 站点,如果省略 SNI,服务器可能返回默认站点的证书,排查结果就会偏离浏览器的真实访问过程。
重点检查输出中的以下内容:
- 第一张证书的
subject和 SAN 是否包含当前域名; issuer是否符合预期;notBefore、notAfter是否处于有效期内;Certificate chain是否包含所需的中间证书;- 最后一行
Verify return code是否为0 (ok)。
也可以直接检查域名和日期:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \ | openssl x509 -noout -subject -issuer -dates -ext subjectAltName
如果网站同时有 IPv4 和 IPv6,建议分别验证。很多“我这里正常、别人那里报错”的问题,来自 AAAA 记录仍指向旧服务器,而管理员只检查了 IPv4。
dig +short A example.com dig +short AAAA example.com curl -4Iv https://example.com/ curl -6Iv https://example.com/
curl -6 需要本机具备可用的 IPv6 网络。没有 IPv6 环境时,可以从支持 IPv6 的服务器检查,或者直接核对 AAAA 记录对应主机上的证书配置。
证书没过期,但域名并不匹配
现代客户端主要根据 SAN 判断证书是否适用于当前主机名。常见配置遗漏有:
- 证书只申请了根域名,没有申请
www; - 证书只包含
www,访问根域名时没有先完成 HTTPS 握手就想依靠跳转修正; - 新增了
api.example.com、shop.example.com,但仍沿用旧证书; - 通配符证书
*.example.com被用于a.b.example.com; - 国际化域名申请时,Punycode 形式或实际访问域名不一致。
HTTP 跳转无法修复证书域名错误。浏览器必须先建立 HTTPS 连接,随后才能读取服务器返回的 301 或 302。正确做法是让每个对外提供 HTTPS 的主机名都由对应证书覆盖,再配置跳转规则。
重新签发证书前,先列出站点需要保留的全部域名,并核对 DNS 是否都指向当前服务。不要为了省事把不再使用的测试域名长期加入证书,域名越多,验证和续期环节也越复杂。
中间证书缺失:桌面浏览器正常,部分设备仍失败
服务器在 TLS 握手时通常需要发送站点证书和中间证书,客户端再利用本地信任库连接到受信任的根证书。服务器只发送站点证书时,一些曾经缓存过中间证书的浏览器可能仍能打开,新的设备、应用程序、爬虫或较严格的客户端却会验证失败。
Nginx 的 ssl_certificate 一般应指向包含站点证书和中间证书的完整链文件,顺序是站点证书在前,中间证书随后。例如自动化签发工具常生成 fullchain.pem:
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
}
修改前先备份当前配置和证书路径记录。完成后运行:
sudo nginx -t sudo systemctl reload nginx
只有 nginx -t 通过后再 reload。reload 失败时,保留原进程并恢复刚才的配置,不要在业务高峰直接重启服务。
Apache HTTP Server 2.4.8 及以后版本可在 SSLCertificateFile 中加载包含中间证书的文件。不同发行版和旧版本的配置方式可能不同,修改前先运行 apachectl -v 或 httpd -v 确认版本,并查看当前虚拟主机:
sudo apachectl -S sudo apachectl configtest
配置检查通过后再执行平滑重载。托管主机或控制面板会自动管理证书文件时,应优先使用面板提供的证书部署入口,手工修改生成文件可能在下一次续期时被覆盖。
SNI 配置错误:同一 IP 返回了别的网站证书
SNI 允许客户端在 TLS 握手阶段告诉服务器自己要访问哪个主机名,服务器据此选择虚拟主机和证书。同一 IP 托管多个站点时,常见错误包括:
server_name或 ApacheServerName、ServerAlias漏写域名;- 新站点证书已部署,但请求落到了默认虚拟主机;
- 443 端口配置重复,加载顺序让错误站点成为默认项;
- 反向代理、负载均衡器或 CDN 终止 TLS,源站改证书并不会改变用户看到的证书;
- 负载均衡后的多台节点没有同步更新。
可以绕过 DNS,直接测试某个 IP 在指定 SNI 下返回什么证书:
openssl s_client -connect 203.0.113.10:443 -servername example.com </dev/null 2>/dev/null \ | openssl x509 -noout -subject -issuer -dates -ext subjectAltName
把示例 IP 换成实际节点地址。若不同 IP 返回不同证书,修复对象是落后的节点或错误的负载均衡配置,而不是重新清理浏览器缓存。
Nginx 可先查看完整生效配置,再定位重复监听和域名归属:
sudo nginx -T | less
该命令会输出配置内容,其中可能含内部地址、路径或其他敏感信息,不要把未经处理的完整结果发布到公开论坛。
使用 CDN 或代理时,要分清边缘证书和源站证书
开启 CDN、WAF 或反向代理后,浏览器先与边缘节点建立 TLS 连接。用户看到的是边缘证书;边缘节点回源时,还可能再次使用 HTTPS 与源站握手。因此会出现两套证书:
- 浏览器到 CDN 的边缘证书;
- CDN 到源站的源站证书。
浏览器直接报证书错误时,先检查边缘证书是否已签发、是否覆盖当前域名、相关 DNS 记录是否已经代理。CDN 面板显示“部署中”时,不要立刻删除仍在使用的旧证书。
如果前台访问正常,但 CDN 回源报 525、526 或类似 TLS 错误,再检查源站证书、回源 SNI、证书链和 CDN 的源站验证模式。为了临时恢复访问而关闭严格验证,会掩盖源站证书问题,也会降低回源链路的身份校验能力。更稳妥的处理方式是修正源站证书和回源主机名,然后恢复严格验证。
证书更新了,为什么用户仍收到旧证书
证书文件替换成功,不代表所有对外节点都已经加载。常见遗漏有:
- 只更新了一台服务器,负载均衡仍会分配到旧节点;
- 文件已替换,但 Web 服务没有 reload;
- Nginx、Apache 之外还有 HAProxy、Traefik 或云负载均衡器负责 TLS;
- CDN 边缘证书仍在部署,或者 DNS 中还保留绕过 CDN 的记录;
- IPv6 对应的服务器没有同步证书;
- 自动续期脚本签发成功,但部署钩子失败。
修复后不要只测一次。至少从外部网络重复检查所有 A、AAAA 和负载均衡节点,并确认返回证书的序列号或有效期一致:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \ | openssl x509 -noout -serial -fingerprint -sha256 -dates
如果使用自动续期,除了查看定时任务是否存在,还要检查最近一次续期日志和部署动作。签发成功、加载失败的状态很容易被面板里的绿色“已续期”掩盖。
还有两类容易忽略的问题
客户端时间错误
设备时间早于证书的 notBefore,或晚于 notAfter,都会触发日期错误。若只有一台电脑或手机异常,先检查系统日期、时区和自动对时。不要为了迁就时间错误的设备重新签发证书。
HTTPS 页面加载了 HTTP 资源
证书验证通过后,地址栏仍可能出现“不完全安全”提示。这时要检查页面是否通过 http:// 加载图片、脚本、字体、iframe 或表单目标。混合内容和证书错误是两类问题,替换证书无法修复正文中的 HTTP 资源地址。
可在浏览器开发者工具的 Console 和 Network 面板查看被拦截的资源,再从主题、插件、数据库内容或反向代理规则中修正 URL。批量替换数据库前应先备份,并使用能正确处理序列化数据的工具。
一套比较稳妥的排查顺序
遇到证书“明明有效却不安全”,可以按下面的顺序处理:
- 记录完整域名、浏览器错误代码和受影响范围;
- 检查本机时间,并区分证书错误与混合内容;
- 用带
-servername的 OpenSSL 命令查看实际返回证书; - 核对 SAN、有效期、签发者和完整证书链;
- 分别检查 IPv4、IPv6、CDN 边缘和各个源站节点;
- 确认 TLS 终止位置以及 SNI 对应的虚拟主机;
- 备份配置,修正证书链或虚拟主机,先做语法检查再平滑重载;
- 从外部网络复测,并检查自动续期后的部署流程。
这套顺序能先确认用户实际拿到什么,再决定改哪里。证书文件本身没有问题时,继续反复签发只会增加变量;找到负责 TLS 的节点和对应主机名,问题通常会清楚得多。
参考资料
- OpenSSL Documentation:
openssl-s_client,https://docs.openssl.org/3.0/man1/openssl-s_client/ - RFC 9525:Service Identity in TLS,https://www.rfc-editor.org/rfc/rfc9525.html
- RFC 6066:TLS Extensions(包括 Server Name Indication),https://www.rfc-editor.org/rfc/rfc6066.html
- NGINX Documentation:Configuring HTTPS servers,https://nginx.org/en/docs/http/configuring_https_servers.html
- Apache HTTP Server Documentation:SSL/TLS Strong Encryption,https://httpd.apache.org/docs/2.4/ssl/ssl_howto.html
- Let’s Encrypt Documentation:A Chain of Trust,https://letsencrypt.org/certificates/
资料核验日期:2026 年 9 月 30 日。




