Windows Server 时间服务跳转到未来并(部分)返回

Windows Server 时间服务跳转到未来并(部分)返回

这看起来像是同一个问题Windows Server 2022 时间服务迈向未来。我还针对此问题在 Microsoft(反馈中心)添加了支持凭单:https://aka.ms/AAkwnpl

由于系统时钟对于软件的正常运行至关重要,并且可能是最核心的共享可变状态,因此这个问题对我们的系统以及与我们通信的每个人都造成了严重破坏,并一路影响到关键基础设施。

我们第一次注意到这个问题是在 2022 年 8 月,当时是在一台 2019 年的服务器上。时钟被设置为 2023 年 1 月,但后来自行修正了。不幸的是,这是在日志被清除后不久发现的,所以我们无法进一步调试它。

但上个月,我们又经历了一次,这次是在 2016 年的服务器上。时钟被设置为未来 55 天。

15 秒后,Time-Service 注意到时钟与我们的域控制器不同,它必须将时钟调回 -4454176 秒。由于它认为该时间大于 4294967295,因此它取消了该时间。

第一次更改 15 分钟后,时钟再次设置,这次向后调至未来的 12 时 26 分 43 秒。

第二次变化后 15 秒,时间服务注意到时钟已关闭,并且这次对其进行了更正,因为它在合理的窗口内。

三周后,同一台服务器上又发生了同样的事情,只是细节有所不同。与此同时,服务器已重新启动并更新了新的月度更新。

我们使用的是 VMWare,配置了两个物理硬件时钟。我们有两个域控制器配置为使用 pool.ntp.org - 可能应该移动到我们自己的 0 层硬件,尽管这可能与我们的问题无关。

在一些外部专家的帮助下,我们几乎排除了错误配置、手动干预(错误、安全漏洞或不忠诚的员工)和硬件问题,剩下的就是“奇怪的 Windows 错误”。

不幸的是,2016 年没有包含与这些事件相关的太多细节,因此很难进一步调试。2019+ 包含更多信息。

@chris1out 在Windows Server 2022 时间服务迈向未来对于未注册到域中的服务器,也存在同样的问题,因此我们可能可以排除域控制器。它还使用标准时间服务器,而不是pool.ntp.org。这意味着我们可能也可以排除这两个。这几乎将 Time-Service 中的错误作为可能的原因。这个 serverfault 问题是我们能够找到的唯一记录在案的事件。

答案1

更新:Ars Technica 已就此有问题的功能撰写了一篇文章:https://arstechnica.com/security/2023/08/windows-feature-that-resets-system-clocks-based-on-random-data-is-wreaking-havoc/


TL;DR:我们发现了最可能的根本原因:W32time 安全时间播种,它查看 SSL 握手标头中的旧“时间”值(该值在较新的 SSL 实现中是随机的),将其解释为正确的时间,并相应地设置时钟。

可以通过设置 UtilizeSSLTimeData 注册表项来关闭它: reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w32time\Config /v UtilizeSslTimeData /t REG_DWORD /d 0 /f

并且可以指示 w3tm 重新读取其配置:W32tm.exe /config /update


较长的答案...

微软于 2015 年 11 月推出了一项名为“安全时间播种”的功能,该功能包含在 Windows Server 2016+ 中并默认启用。

它试图缓解系统没有电源来驱动系统时钟(例如电源故障和 CMOS 电池损坏)并因此在启动时出现完全错误的时间,无法安全地与其他来源通信以可靠地获取正确的时间的问题。

在传出 SSL 握手期间,它会查看“ServerUnixTime”(可能 gmt_unix_time在规范中)。

TLS 1.2 规范规定如下(重点是我的):

根据发送者的内部时钟,当前时间和日期采用标准 UNIX 32 位格式(自 1970 年 1 月 1 日午夜以来的秒数,UTC,忽略闰秒)。 时钟无需正确设置由基本 TLS 协议定义;更高级别或应用协议可以定义其他要求。请注意,由于历史原因,数据元素使用 GMT 命名,GMT 是当前全球时间基准 UTC 的前身。

微软的初始博客在其帖子中说了以下内容(重点是我的):

ServerUnixTime 应该是服务器上的当前系统时间,但某些 SSL 实现也可以将其设置为随机值。我们观察到大多数服务器在此字段提供相当准确的值其余的提供随机值。我们使用该数据字段假设它有一定的准确性但也可能是错误的。

这表明他们误解了规范,他们的实现是在错误的假设下设计和运行的。当世界仍在使用较旧且较不安全的实现时,他们的实现可能运行良好,但随着越来越多的服务器进行更新,前提是完全错误的。

至少他们不信任单一来源,但由于提供时间的来源较少,而使用随机值的来源较多,因此 4 个字节相似到足以混淆他们的算法可能只是时间问题。

我们采取的方法是,不信任来自单个服务器的数据,无论该服务器的身份如何。我们依靠来自多个服务器的相互印证的信息来得出关于当前时间的共同事实。

他们进一步描述说,他们正在使用统计方法来查看何时可以将随机字节解释为正确的时间(重点是我的):

ServerUnixTime 和 OCSP 有效期的信息被合并以产生最小可能的可靠时间范围值以及置信度分数。当置信度分数足够高时,这些数据就变成了信息。

gmt_unix_time字段于 2013 年 9 月在 TLS 邮件列表中被讨论,比微软发布该功能早了两年,并于 2013 年 10 月在 OpenSSL 中实现,并于 2014 年 1 月发布。

commit 2016265dfbab162ec30718b5e7480add42598158
Author: Nick Mathewson <[email protected]>
Date:   Sun Oct 20 15:03:24 2013 -0700

    Do not include a timestamp in the Client/ServerHello Random field.

    Instead, send random bytes, unless SSL_SEND_{CLIENT,SERVER}RANDOM_MODE
    is set.

    This is a forward-port of commits:
      4af793036f6ef4f0a1078e5d7155426a98d50e37
      f4c93b46edb51da71f09eda99e83eaf193a33c08
      3da721dac9382c48812c8eba455528fd59af2eef
      2583270191a8b27eed303c03ece1da97b9b69fd3

    While the gmt_unix_time record was added in an ostensible attempt to
    mitigate the dangers of a bad RNG, its presence leaks the host's view
    of the current time in the clear.  This minor leak can help
    fingerprint TLS instances across networks and protocols... and what's
    worse, it's doubtful thet the gmt_unix_time record does any good at
    all for its intended purpose, since:

        * It's quite possible to open two TLS connections in one second.

        * If the PRNG output is prone to repeat itself, ephemeral
          handshakes (and who knows what else besides) are broken.

commit 2927791d77ddaef687e92b1779e0bff89bdc279f
Author: Nick Mathewson <[email protected]>
Date:   Sun Oct 20 15:08:58 2013 -0700

    Fix another gmt_unix_time case in server_random

### Major changes between OpenSSL 1.0.1e and OpenSSL 1.0.1f [6 Jan 2014]

  * Don't include gmt_unix_time in TLS server and client random values
  * (.. unrelated changes ..)

u/zanatwo 于 2017 年 3 月发现了这个问题并在 r/sysadmin 上报告,但没有迹象表明微软知道这个问题,因为它仍然处于启用状态。

它于 2022 年 1 月被 u/Thranx 重新发现,并在 r/sysadmin 上报告。

今年年初 @chris1out 在 ServerFault 上再次发文。

正如我们和其他人所经历的那样,这个问题出现的频率越来越高,可能是因为报告实际时间的服务器越来越少,而且只是报告随机值。这种情况很可能会继续增加,影响到更多的用户。

系统时钟是系统中最重要的共享可变状态,将时间更改为完全不同值的错误会破坏所有系统,其影响远远超出发生这种情况的单个服务器。毫无疑问,这是我遇到过的最严重的错误/缺陷,微软需要尽快禁用它。

与微软取得联系很困难,因此如果您遇到同样的问题,请向微软报告此问题。

非常感谢@test-is-prod 分享他们的发现并向我指出/u/zanatwo 的 Reddit 帖子!

参考:

相关内容