命令行工具
error 10 at 0 depth lookup: certificate has expired 怎么办
error 10 at 0 depth lookup: certificate has expired错误 10 的意思是:OpenSSL 检查时,证书链里有一张证书已经过期了。 看 depth:depth 0 是服务器自己的证书该续期了;depth 1 及以上是服务器还在发过时的中间证书;如果看起来都没过期,多半是做验证的那台机器时钟不对。
快速修复
先按 depth 找出过期的那张证书:depth 0 续期站点证书,depth 1 及以上更换中间证书。打印服务器发出的每张证书的有效期,以及当前 UTC 时间:
date -u
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null \
| awk '/BEGIN CERT/{c++} {print > "cert" c ".pem"}'
for f in cert*.pem; do openssl x509 -in "$f" -noout -subject -enddate 2>/dev/null; done
- 站点证书过期: 续期并部署,重载 Web 服务器。
- 中间证书过期: 用 CA 当前的中间证书重新拼接证书链文件。
- 都没过期: 修正报错那台机器的时钟。
原因
5 种原因里,前 3 种是证书真的过期了,后两种是客户端时钟或测试文件的问题。
1. 服务器证书过期(depth 0)
- 确认: 第一张证书的
notAfter已经过去。 - 修复: 用 ACME 客户端或到 CA 续期,部署新证书和证书链,然后重载。磁盘上已经有新证书、对外却还是旧证书,说明服务器没重载,或者读的是另一个路径。阿里云、腾讯云的免费证书不会自动续期,到期前要重新申请和部署。
2. 证书包里有过期的中间证书(depth ≥ 1)
- 确认: 站点证书有效,链里另一张证书的
notAfter更早而且已过期。 - 修复: 更换 CA 证书包;不同年份的中间证书不要不看日期就混用。SSL 检测工具会标出链中过期的证书。
3. 老版本 OpenSSL 走了过期的交叉签名路径
OpenSSL 1.0.2 及更早版本,即使存在一条经过受信任根证书的有效路径,也可能选择经过过期交叉签名证书的路径。OpenSSL 1.1.0 起默认优先使用受信任证书。
- 确认: 只有老系统报错(比如 CentOS 6、很老的嵌入式设备),新系统验证同一台服务器正常。
- 修复: 升级 OpenSSL;服务器端不要再发送过期的交叉签名证书。
4. 客户端时钟错误
- 确认:
date -u与真实时间相差很多;访问许多无关网站都报错误 10 或 9。 - 修复: 开启 NTP(
timedatectl set-ntp true、chrony),国内可以使用阿里云、腾讯云提供的 NTP 服务器。从快照恢复的虚拟机、没有时钟电池的设备最容易出这个问题。
5. 验证的是旧文件
拿几个月前保存的证书文件来测试,也会报错误 10。
- 修复: 用 s_client 验证服务器现在发出的证书,而不是本地副本。
各环境修法
避免错误 10 要做到三点:续期自动化、续期后重载、到期前告警。
Certbot / acme.sh: 手动执行 certbot renew --dry-run 或 acme.sh --cron,看输出;确认有重载钩子。
宝塔面板: 在站点 SSL 页面查看证书到期时间和续签日志,确认“自动续签”开启。
Kubernetes: 用 kubectl get secret <名称> -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -enddate 解码 TLS Secret 查看到期时间。
Java 密钥库和硬件设备: 手动导入的证书不会自动续期,用 keytool -list -v 列出,在到期前更换。
监控: 链中任何证书剩余不足 14 天就告警。2026 年 3 月 15 日起公网证书最长有效 200 天,一年至少续期两次,配置方法见自动续期证书。
不要这样做
忽略时间检查、回拨时钟、只续站点证书,都会留下过期的证书。
- 在真实流量上用
-no_check_time或类似的应用标志。 你会接受 CA 已经不再负责的证书。 - 把时钟往回调,让过期证书通过验证。 其他所有依赖时间的功能都会出错。
- 只续站点证书,证书包还用旧的。 中间证书也要检查,CA 可能已经更换过。
常见问题
怎么检查证书在某个日期是否有效?
用 -attime 加 Unix 时间戳:openssl verify -attime $(date -d 2026-12-01 +%s) -untrusted chain.pem leaf.pem(GNU date)。快速查是否快到期:openssl x509 -checkend 1209600 -noout -in leaf.pem,14 天内到期会返回非零退出码,适合写进监控脚本。
站点证书没过期,depth 1 却报错误 10,为什么?
服务器发出的中间证书过期了,通常是旧证书链文件残留。用 CA 当前的中间证书替换证书包,可以从 CA 官网获取,或用证书链补全工具生成。
能让 OpenSSL 忽略日期吗?
能,但只用于排查。-no_check_time 用于排查归档或测试数据,应用程序里也有类似的标志。不要用在真实连接上:过期证书不再受吊销服务覆盖,私钥泄露了也可能没人发现。