| RFC-0134:软件更新时间依赖性 | |
|---|---|
| 状态 | 已接受 |
| 区域 |
|
| 说明 | 移除时间同步作为软件更新的依赖项。 |
| 问题 | |
| Gerrit 更改 | |
| 作者 | |
| 审核人 | |
| 提交日期(年-月-日) | 2021-07-24 |
| 审核日期(年-月-日) | 2021-10-06 |
摘要
此 RFC 移除了时间同步作为软件更新的依赖项。
设计初衷
Fuchsia 设备会报告固定的“后备”时间,直到它们从网络或实时时钟同步时间为止。目前,报告的时间是基础映像 build 的大致时间,可能已过去几个月。
与其他早期启动时间用户不同,系统更新检查不会等待时间同步。在更新检查期间,如果时间未同步,软件包解析器可能会间接使用后备时间作为 TLS 证书验证的一部分。这存在以下问题:
- 如果回溯时间早于证书的创建日期,则更新会失败并显示
CertNotValidYet错误。由于更新服务器和软件包服务器可能通过不同的名称进行访问,因此此故障可能会在多个组件中发生。在这种情况下,如果时间同步中断,设备将卡住,并且永远不会再次更新。 - 在截止时间之前有效的过期证书可用于提供更新响应和软件包。
将时间同步从软件更新流程的依赖项中移除,可解决第一个问题,并使更新更可靠。
设计
此 RFC 建议软件更新不应依赖于准确的时间。
这意味着,该功能将:
允许证书的有效期为未来的日期。
始终使用后备时间来验证证书,即使时间已同步。
实现
需要实现自定义 TLS 证书验证工具,并在 omaha-client 和 pkg-resolver 中使用该验证工具。
在构造期间,验证器将从 UTC 时钟对象的 ClockDetails 获取后备时间,并将其保留为结构体的字段。
验证方将使用 WebPKIVerifier 实现 ServerCertVerifier 特征,并使用返回截止时间的时间函数;如果 WebPKIVerifier 返回 CertNotValidYet 错误,则使用证书有效期内的时间创建另一个 WebPKIVerifier,然后再次调用它。
性能
自定义验证器只是在正常情况下封装 WebPKIVerifier,并且仅当第一次调用返回 CertNotValidYet 错误时才会调用 WebPKIVerifier 两次。
工效学设计
不适用
向后兼容性
API 没有任何变化。
安全注意事项
此设计将接受以下证书作为有效证书:
- 已过期但比截止时间新的 TLS 证书
- 未来的 TLS 证书
虽然这并不理想,但第一种情况目前已经存在,因此不算回归;第二种情况的风险很小。
此外,即使设备被诱骗安装了恶意更新,我们仍然有经过验证的执行,因此设备不会启动,而是会恢复原样。我们还提供回滚保护,因此已签名的旧 build 也无法正常运行。
请注意,如果攻击者拥有遭入侵的证书和 DNS 控制权,可能会欺骗时间系统接受任意时间,因此即使我们让更新检查等待时间同步,也无法解决这种情况。
证书撤消不在本 RFC 的范围内,但会是另一个 RFC 中值得探索的领域,不过此类解决方案可能需要将过期的证书列为无限期撤消。
隐私注意事项
对隐私保护没有影响。
测试
对自定义证书验证器进行了广泛的单元测试,确保将来只有在其他所有内容都有效的情况下,它才会接受证书。
针对 omaha-client 和 pkg-resolver 的集成测试,用于验证更新是否适用于非常旧的时间。
文档
不适用
缺点、替代方案和未知因素
替代方案:等待时间同步
在此模型中,我们不会更新,直到时间同步为止。虽然这给我们带来了一些安全优势,但并不多,因为时间同步也可能会受到损害。不过,此模型使更新依赖于时间同步,而时间同步可能会因各种原因而中断,从而降低更新的可靠性。
替代方案:等待时间,但在截止时间后更新
在此模型中,我们会等待任意时长以同步时间,如果时间尚未同步,则在一段时间后执行更新检查。
虽然这解决了上一个替代方案的主要缺点,但在其他方面却很敏感。延迟时间是任意的:如果设备陷入启动循环,且周期低于此延迟时间,则也永远不会更新。
此外,我们仍然依赖于后备时间,这可能意味着我们需要放宽证书验证的严格程度。
在先技术和参考资料
ChromeOS 不存在此问题,因为它没有后备时间,并且没有在 1970 年有效的 Google TLS 证书。