时间跳跃导致证书失效的 chrony makestep threshold 与 hwclock -systohc

14次阅读

chrony makestep 仅在全新启动时对超 1 秒时间跳跃生效,热重载不触发;需用 systemctl restart chronyd 并确保配置在 /etc/chrony.conf 全局段,设 makestep -1 可强制校正任意偏差。

时间跳跃导致证书失效的 chrony makestep threshold 与 hwclock -systohc

chrony makestep 为什么没生效

因为 makestep 默认只对时间跳跃超过 1 秒的场景起作用,且仅在 chrony 启动时触发一次。如果系统时间已经严重偏移(比如关机数天后开机),但 chrony 进程是热重载(chronyc reload)或 service 重启而非全新启动,makestep 根本不会执行。

实操建议:

  • 确认 chrony 是全新启动:用 systemctl restart chronyd,而不是 chronyc makestep 或 reload 配置
  • 检查配置是否写对位置:makestep 必须放在 /etc/chrony.conf 的全局段,不能套在 poolserver 块里
  • 想让任意时间偏移都强制校正?把阈值设成负数:makestep -1(单位秒),这样只要检测到偏差就跳变
  • chronyc trackingLeap statusSystem time 差值,比看日志更直接

hwclock -systohc 写入 BIOS 时间失败的常见原因

最常被忽略的是硬件时钟模式不匹配:Linux 默认认为硬件时钟是 UTC,但有些 BIOS 实际按本地时间维护。一旦 hwclock -systohc 把当前系统时间(UTC)强行写进一个“以为自己存的是本地时间”的 RTC,下次开机系统就会误判时间,造成循环偏移。

实操建议:

  • 先查当前硬件时钟解释方式:timedatectl status | grep "RTC in local TZ",输出 yes 表示 BIOS 用本地时间
  • 若为 yes,别用 -systohc,改用 hwclock --systohc --localtime
  • 若为 no(推荐),确保系统时区设置正确,并在 /etc/adjtime 中第三行是 UTC,不是 LOCAL
  • 虚拟机里运行 hwclock -systohc 可能静默失败——某些 hypervisor 禁止客户机写 RTC,得靠宿主机同步或启用 host-time-sync 特性

chrony + hwclock 协同失效的典型时间链断裂点

问题不在单个命令,而在时间同步链条中多个环节的职责错位:chrony 负责校准系统时钟(CLOCK_REALTIME),hwclock -systohc 负责快照此刻系统时间写入硬件时钟,但二者没有自动联动。系统关机时若没执行 hwclock -systohc,下次开机就从错误的 BIOS 时间起步,chrony 启动前已偏移巨大。

实操建议:

  • 加 systemd 关机钩子:创建 /usr/lib/systemd/system-shutdown/save-clock.sh,内容为 hwclock --systohc(注意权限 +x)
  • 不要依赖 cron 每小时跑一次 hwclock -systohc——它解决不了关机瞬间的时钟冻结问题
  • chrony 的 makestep 是启动时行为,和关机无关;hwclock 是关机时行为,和 chrony 运行状态无关——它们是两个时间维度的操作,硬凑在一起反而容易互相掩盖问题
  • 云环境或容器里,/dev/rtc 往往不可写或不存在,此时 hwclock 无意义,应专注 chrony + NTP + 宿主机时间透传

BIOS 时间倒退导致 chrony 拒绝同步的应对逻辑

当硬件时钟被人为调早再重启,或虚拟机恢复快照后 BIOS 时间比系统上次关机时还旧,chrony 启动时会发现系统时间“倒流”,默认拒绝校正(防止意外跳变影响日志、证书等)。这不是 bug,是保护机制。

实操建议:

  • chronyd -n -d 启动日志,搜 kernel reported time jumpbackwards,确认是否因倒退被拒
  • 临时解法:加 -r 参数强制 chronyd 忽略倒退(chronyd -r -n -d),但仅限调试,生产环境慎用
  • 根治办法:确保 BIOS 时间始终单调前进——物理机定期用 ntpdate -s pool.ntp.org(仅作参考,非 chrony 替代)校准 RTC;虚拟机禁用 RTC 设备或启用 guest time sync
  • 证书类服务(如 TLS)依赖系统时间,若 chrony 因倒退沉默,openssl s_client -connect 就可能报 certificate has expired,实际是时间没校准,不是证书真过期

真正麻烦的从来不是单个命令怎么写,而是 chrony 启动时机、hwclock 写入时机、BIOS 时间语义、以及关机 / 开机这三秒之间谁在管哪段时钟——漏掉其中一环,证书就敢跟你较真。

text=ZqhQzanResources