你打开客户端,选中用了几个月的配置文件,它却以“certificate is not yet valid”停下。你的登录信息没有任何变化,信任存储大概也没问题:握手中出示的证书带有一个有效期窗口,它的起点晚于验证方正在使用的那一刻。三种不同情形都会产生这条完全相同的消息,而它们需要不同的处理。下面的顺序能让你在动时钟或证书文件之前判断自己属于哪一种。

你面对的是三种原因中的哪一种

第一种原因是本地的:执行检查的设备所持时钟早于证书的起始日期。你会在 CMOS 电池耗尽的硬件上、从旧快照恢复的虚拟机上、断电足够久而丢掉时间的设备上,以及出站 NTP 被封锁却无人察觉的网络里看到它。证书可以完全有效,却仍然以这种方式失败。

第二种原因属于签发方,因为证书确实从未来才开始生效:签发过早、以显式起始时间生成,或作为尚未执行的激活步骤的一部分被签名。第三种原因最浪费时间,因为叶子证书是当前的,而所出示链条中的另一张证书不是,于是报错指向你从未安装过的材料。

一个问题能把它们分开。故障是跟着设备走,还是跟着服务走?同一网络里两台机器表现不同,指向时钟。每个客户端都以同样方式失败,指向证书的有效期窗口及其背后的链条。

从实际出示的那张证书读取有效期窗口

不要检查上一次部署遗留的 PEM 文件;向服务索取它此刻发送的链条。openssl s_client -connect vpn.example.com:443 -servername vpn.example.com -showcerts 会打印链条中的每一张证书。保存你关心的那段,运行 openssl x509 -noout -subject -issuer -dates;后者会打印 notBefore 和 notAfter,正是这两个值起决定作用。在 Windows 上,连接对应的证书对话框以及对导出文件运行 certutil -dump 会显示相同字段。

要读窗口的两端,而不只是起点。两小时后才生效的证书和两小时后过期的证书,报错不同,牵涉的团队也不同。记下报错点名的是哪一张证书——叶子、中间还是根——因为这决定了客户端这一侧到底有没有可修的东西。

你也可以不等它生效就测试。验证接受一个显式时间:openssl verify -attime 1793600000 -CAfile ca.pem -untrusted intermediate.pem leaf.pem 会按该时间戳评估链条。先用当前时间运行以复现故障,再用证书的起始时间运行,确认窗口一打开同一条链就能通过。RFC 5280 定义了有效期字段,以及证书不得在其之外使用的规则,这正是你的客户端刚刚执行的规则。

是你的时钟,还是他们的

把你信任的来源给出的证书起始时间与设备时钟按 UTC 比较。date -u 给出当前时刻,systemd 主机上的 timedatectl status 还会报告时钟是否已同步。在 Windows 上,w32tm /query /status 显示当前时间源和上次成功同步。任务栏里显示的时区只是显示选择,不是时钟错误;验证方比较的是 UTC 时刻。

What you seeMost likely readingNext step
Clock behind, one device affectedLocal time faultResync time, keep validation on, retest
Clock correct, window opens soonCertificate staged earlyWait for the window or follow the cutover plan
Clock correct, intermediate not yet validChain material mismatchOperator replaces the intermediate
Some peers pass, others do notInconsistent nodesRecord each peer's chain before changing anything

如果时钟落后,先重新同步并重测,再改动任何证书材料。偏差几分钟或几小时的设备会拒绝它遇到的每一张新签发证书,而不只是某一个服务,所以“只是某个服务”的解释通常是错的。如果时钟正确且已同步,就别再盯着设备:窗口属于签发方,不该为了让它通过而调整任何本地设置。

那张表就是全部判断。把时钟挪到证书期望的位置不是修复,关掉时间检查也不是,因为两者都掩盖了产生错误的条件。

叶子看起来正常,链条为什么失败

续期的叶子和替换用的中间证书通常一起下发,但并不总在同一时刻落地。服务可能发送一张由中间证书签名的新叶子,而那张中间证书自身的窗口开始得更晚;也可能在新叶子之下继续提供较旧的中间证书。无论哪种,叶子自己的日期看着合理,链条却失败。

负载均衡的端点会把“坏掉”变成“不一致”。如果重试成功,或者一个网络能用而另一个不能,在改设置之前记下是哪个对端应答、发的是哪条链。openssl s_client 会打印连接到的地址,试几次就能看出每个节点是否提供同一条链。

保持验证完整的修复路径

时钟问题在设备上修,验证保持开启。证书问题由运营方用已覆盖当前时间的窗口所签发的材料来修。没有任何客户端设置能让尚未生效的证书变得有效;跳过时间检查的开关是用来确认诊断的,不是用来上生产的。

当证书是为计划中的激活而预备时,按切换计划执行。在窗口打开时安装,或使用提供方记录的叠替流程,而不是提前安装、再教用户点掉警告。人们学会忽略的警告,比一次短暂延迟代价更大。

最后,按故障发生的方式重测:新会话、同一客户端、你真正需要的资源。TLS 库可能在连接生命周期内缓存已验证的链条,恢复的会话未必再查一次,所以旧会话可能在修复后继续失败,或在回归后继续可用。能在查看器里打开文件,只证明文件可读;完成一次握手,才证明链条通过验证。

关单之前确认四件事:故障设备的 UTC 时间与同步状态、所出示链条中每张证书的 notBefore 与 notAfter、第二个客户端拿到的同一条链,以及报错点名的那张证书。如果时钟正确而窗口尚未打开,剩下的就是运营方的工作,你这边正确的做法是等窗口,而不是削弱检查。

相关文章