GNU Wget built with GnuTLS (Debian)curl
错误信息
ERROR: The certificate of 'api.example.com' has expired.
使用 GnuTLS 构建的 wget 会在通用的“ERROR: The certificate of '<host>' is not trusted.”之后、“The certificate has expired”之前打印这一行。使用 OpenSSL 构建的 wget 则打印“ERROR: cannot verify <host>'s certificate, issued by '…':”,接着是“Issued certificate has expired.”。
含义
按这台机器的时钟,服务器的证书(或其证书链中的另一张证书)已经超过了 notAfter 日期,因此 wget 的 GnuTLS 后端拒绝连接。CA 是受信任的,只是有效期检查未通过。wget 以退出状态 5 退出。
原因
证书没有续期
常见停止运行的续期任务、在 DNS 或防火墙变更后失败的 ACME 挑战,或者无人跟踪的手动安装证书。
续期后的证书已在磁盘上,但未对外提供
常见TLS 终止端(nginx、Apache、HAProxy、负载均衡器或 CDN)会一直提供之前加载的证书,直到重新加载或上传了新证书为止。
客户端时钟不准确
偶见时钟远远超前的机器会把有效的证书视为已过期。没有实时时钟的嵌入式开发板启动后,在 NTP 完成同步之前常常使用错误的日期。
修复方法
- 1.
检查实际提供的证书上的日期
将 notAfter 与当前 UTC 时间对比。如果服务器提供的是旧证书,而更新的证书已经存在,说明服务器还没有加载新证书。
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -subject -startdate -enddate - 2.
续期并重新加载
通过 ACME 客户端或 CA 续期,然后重新加载为该名称终止 TLS 的每一个服务;把这两步都自动化,下一次续期就不必依赖有人记得去做。
bash sudo certbot renew --cert-name api.example.com sudo systemctl reload nginx # or apache2 / haproxy: reload whatever terminates TLS - 3.
校正客户端时间
如果从另一台机器检查时证书有效,就在出错的那台机器上启用 NTP。
bash date -u timedatectl status sudo timedatectl set-ntp true
相关错误
ERROR: The certificate of 'api.example.com' is not trusted.GNU Wget built with GnuTLS (Debian, Ubuntu before 22.04 used it too)curl: (60) SSL certificate problem: certificate has expiredcurl (OpenSSL backend)verify error:num=10:certificate has expiredOpenSSL CLI (openssl s_client / openssl verify)x509: certificate has expired or is not yet valid: current time 2026-08-20T15:4…Go crypto/x509