证书没过期却报 TLS 失败:先看容器的时间
证书没过期却报 TLS 失败:先看容器的时间
排查 HTTPS 握手失败时,ERR_CERT_DATE_INVALID 这类报错很容易被当成"证书过期",但容器里更常见的原因是系统时间偏了。
症状长什么样
- 浏览器报
NET::ERR_CERT_DATE_INVALID,curl报certificate is not yet valid或certificate has expired - 同一个证书在宿主机上验证通过
openssl s_client -connect example.com:443显示的证书notBefore/notAfter看起来完全正常
原因:容器有自己的时钟偏移
容器共享宿主机内核,但 RTC/NTP 服务不一定在跑。虚拟机被挂起后恢复、宿主机时间漂移、镜像里没装时间同步,都会让容器时间停在几小时甚至几天前。证书校验是拿本地时间和证书有效期比,本地时间错,校验必然错。
先确认:
date -u
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
| openssl x509 -noout -dates
把 date -u 和证书的 notBefore 放在一起看。时间早于 notBefore 就是"尚未生效",晚于 notAfter 就是"已过期",即使真实世界并非如此。
修法
临时:
date -s "$(curl -sI https://example.com | grep -i '^date:' | cut -d' ' -f2-)"
长期:装 chrony 并指向可用 NTP,或者在容器启动脚本里从宿主机同步一次。生产环境更稳的做法是让宿主机做时间同步,容器共享 /etc/localtime 并把时钟源交给内核。
和另外两个坑区分开
1)代理做了 TLS 解密
企业出口代理会用自己的 CA 签发中间证书。此时报的是 certificate signed by unknown authority,不是日期错误。解决是把代理 CA 装进系统信任库,而不是关掉校验。
2)SNI 没带上
用 IP 直连、或者 openssl s_client 少写 -servername,服务端会返回默认站点证书,域名对不上就报 hostname mismatch。这类错误只在特定客户端出现,浏览器通常没事。
一个可复用的判断顺序
date -u与证书notBefore/notAfter对比openssl s_client看证书链是否完整、签发者是否受信- 确认请求是否经过解密代理(看证书签发者)
- 确认 SNI 与目标域名一致
四步里任何一步不确定,都不要先怀疑"证书坏了"——证书很少坏,时间、代理和 SNI 经常出问题。
- 点赞
- 收藏
- 关注作者
评论(0)