【gowy222】 在 https://github.com/istoreos/istoreos/issues/2710 发布:
背景 / 问题描述
在以下场景下,设备时间可能极端回退到 1970 年(含硬件时钟 RTC)或与真实时间相差数年,导致 TLS 证书校验失败、签名时间不合法等,从而使 Docker/容器相关功能无法正常启动或反复崩溃重启:
- 异常断电后时间回退到 1970(不登录很难察觉)。
- 备用/出差设备长期断电“吃灰”,再次上电时系统时间严重漂移。
- 上游 WAN 需要延迟认证(如酒店 Wi‑Fi 需手机门户登录),NTP 长时间不可用, NTP域名访问不到等边界情况,系统时间迟迟无法校准。
影响:
- Docker/相关守护进程或业务容器因 TLS/证书校验失败无法拉取镜像或建立安全通信,导致启动失败或反复重启。
- 若用户未登录进行手动校时(例如用浏览器时间临时修复),系统无法自愈。
受影响场景(非穷举)
- 冷启动 + 无网络/弱网。
- WAN 需人机认证导致 NTP 被延后。
- RTC 长期未供电导致时间漂移严重。
复现观察步骤
- 将设备 RTC/系统时间 置为
1970-01-01(或与当前相差数年)。 - 断开 WAN,仅保留 LAN(或接入需门户认证的 Wi‑Fi,暂不认证)。
- 开机,使 Docker/容器编排随系统自启。
- 观察 Docker 守护进程与业务容器的启动与日志。
期望行为
- 最小时间保护:无论是否联网,开机后系统时间都不应早于一个“合理下限”,避免出现 1970 等极端无效时间导致 TLS 全面失效。
- Docker 启动鲁棒性:在时间异常的情况下,Docker 自身尽可能正常启动;即便无法联网拉镜像,至少本地已有镜像/容器能启动,待网络/NTP 恢复后再自愈。
影响评估
- 影响应急/外出场景下的可用性与自愈能力。
- 用户认知成本高:不登录页面难以察觉“时间异常”这一根因。
临时规避(当前可行但不优雅)
- 人工登录管理界面,用浏览器时间或手动
date临时校时。 - 预先离线缓存所有镜像(仍可能被其他 TLS 交互卡住)。
- 在受控环境中临时启用不安全拉取(存在安全风险,不建议作为长期方案)。
提案
A. 固件内置“最小时间兜底”机制(可做成内置或 iStoreOS 插件)异常断电可能直接导致插件丢失固件回档?
思路:
- 全局UTC时间锚点文件
- 在固件编译时写入一个只读 锚点时间(如
/etc/build_time.anchor)。 - 开机早期(网络/NTP 之前),守护脚本读取当前系统时间;若当前时间 < 锚点时间,则将系统时间 提升 到该值(
date -s+hwclock -w)。 - 该步骤在任何网络状态下都可执行,先消除 1970 等极端值。
进阶:双锚点机制
- 固件锚点:编译时写入的只读时间。
- 运行时锚点:当 NTP 同步成功后,将“最近可信时间”写入
/var/lib/time_anchor(或等价路径)。
启动兜底逻辑:优先使用“更新更近的锚点”;若运行时锚点不存在或更旧,则回退到固件锚点。
B. 启动顺序与依赖优化
-
在 init 流程中,确保“时间兜底”脚本 早于 Docker/容器编排启动。
-
对依赖 NTP 的服务,避免硬性“等待 NTP 成功”导致卡死;采用“兜底后即允许继续”的策略:
- 先做最小时间提升 → 允许服务先启动(至少不因 1970 报错) → 待网络可用后 NTP 修正到准确时间。
C. Docker 启动鲁棒性
-
目标:时间异常时 dockerd 可启动、本地镜像容器可起;网络拉取失败时延后重试。
-
措施建议:
- 调整启动顺序,保证 Docker 在时间兜底完成后再启动。
- 对从私有仓库拉取的场景,采用退避重试而非阻塞启动。
- 在时间异常导致 TLS 失败时,明确错误提示与自愈策略(例如:提示“时间异常,已退避重试;请完成网络认证或等待 NTP 同步”)。
- (谨慎)在 受控私有网络 下提供可选的
insecure registry/HTTP 仓库开关用于 临时救急,默认关闭并显著标注风险。
兼容性 / 安全性
- 安全:仅将时间提升到“锚点时间”或“最近可信时间”,避免设置到未来时间;从根因上减少 TLS 失败面。
- 可回退:兜底仅在时间明显异常时触发;一旦 NTP 成功,会写入运行时锚点,后续冷启动继续受益。
- 平台:建议以插件/可配置方式提供,便于不同设备场景按需开启。
验收标准(建议)
- 在无网络、RTC=1970 的情况下,开机后系统时间 ≥ 固件锚点。
- 在上述条件下,dockerd 正常启动;已有本地镜像的容器可成功拉起。
- 当网络恢复并完成 NTP 同步后,写入/更新 运行时锚点,下一次冷启动继续生效。
- 在需门户认证的 Wi‑Fi 环境中,不登录认证也不会陷入“1970 导致 TLS 全挂”的死循环。
期望:在 iStoreOS/固件中提供内置或可选插件,实现最小时间兜底,确保 Docker 在时间异常条件下也能尽可能启动运行,提高设备在断电/出差/弱网场景下的可用性与自愈能力。