Windows Server 2022 时间服务跃向未来

chr*_*out 5 windows ntp time time-server

在过去的几个月中,我们的 Windows Server 2022 盒子中有几次会在事件日志中显示类似于此的警告

时间服务已设置偏移量 19630688 秒的时间。,

然后时间会向前跳很多秒。然后几分钟后,它似乎再次与时间服务器同步,我们收到以下错误

时间服务检测到系统时间需要更改-19630688 秒。时间服务不会将系统时间更改超过 54000 秒。验证您的时间和时区是否正确,以及时间源 time.nist.gov (ntp.m|0x0|0.0.0.0:123->128.138.140.44:123) 是否正常工作。

在出现一些与措辞类似的错误之后,时钟会自行纠正,通常在 10 分钟左右。该盒子不在域中,并且它使用 Windows 中的默认时间服务器。知道这里可能出了什么问题吗?

sim*_*sjo 5

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


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


答案较长...

Microsoft 于 2015 年 11 月发布了一项名为“安全时间播种”的功能,该功能包含在 Windows Server 2016+ 中并默认打开。

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

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

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

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

微软最初的博客在他们的帖子中说了以下内容(强调我的):

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

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

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

我们采取的方法是不信任来自单独服务器的数据,无论服务器将自己标识为谁。我们依靠来自多个服务器的证实信息来得出有关当前时间的共同事实。

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

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

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

commit 2016265dfbab162ec30718b5e7480add42598158
Author: Nick Mathewson <nickm@torproject.org>
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 that 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 <nickm@torproject.org>
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 ..)
Run Code Online (Sandbox Code Playgroud)

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

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

从今年年初开始,@chris1out 在 ServerFault 上再次发布。

正如我们和其他人所经历的那样,该问题的频率正在增加,可能是由于报告实际时间和随机值的服务器较少。这很可能会继续增加频率并影响更多用户。

系统时钟是系统上最重要的共享可变状态,将时间更改为截然不同的值的错误会对所有系统造成严重破坏,其影响远远超出其发生的单个服务器。毫无疑问,这是我遇到过的最严重的错误/错误功能,微软需要尽快禁用此功能。

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

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

参考: