网络时间协定

网络时间协议（Network Time Protocol，缩写：NTP）是在数据网络潜伏时间可变的计算机系统之间通过分组交换进行时钟同步的一个网络协议，位于OSI模型的应用层。自1985年以来，NTP是目前仍在使用的最古老的互联网协议之一。NTP由特拉华大学的大卫·米尔斯（David L. Mills）设计。

NTP意图将所有参与计算机的协调世界时（UTC）时间同步到几毫秒的误差内。它使用Marzullo算法的修改版来选择准确的时间服务器，其设计旨在减轻可变网络延迟造成的影响。NTP通常可以在公共互联网保持几十毫秒的误差，并且在理想的局域网环境中可以实现超过1毫秒的精度。不对称路由和拥塞控制可能导致100毫秒（或更高）的误差。

该协议通常描述为一种主从式架构，但它也可以用在对等网络中，对等体双方可将另一端认定为潜在的时间源。发送和接收时间戳采用用户数据报协议（UDP）的通讯埠123实现。这也可以使用广播或多播，其中的客户端在最初的往返校准交换后被动地监听时间更新。NTP提供一个即将到来闰秒调整的警告，但不会传输有关本地时区或夏时制的信息。

当前协议为版本4（NTPv4），这是一个RFC 5905文档中的建议标准。它向下兼容指定于RFC 1305的版本3。

## 历史

<image>

1979年，网络时间同步技术在纽约的国家计算机会议上于运行在跨大西洋卫星网络的互联网服务上公开演示，这可能是该技术的首次公开演示。该技术后在1981年互联网工程笔记（IEN）173中描述，并根据RFC 778文档开发为一个公开协议。该技术首先被部署在一个本地网络，作为Hello路由协议的一部分，并在Fuzzball（一个用于网络原型的实验操作系统，已运行多年）中实现。

现在还有其他的相关网络工具。这包括Daytime和Time协议用以记录事件时间，以及互联网控制消息协议和IP时间戳选项（RFC 781）。更多完整的同步系统，虽然缺乏NTP的数据分析和时钟规律算法，包括Unix守护进程timed在内的软件其使用选举算法为所有客户端指定服务器。以及数字时间同步服务（Digital Time Synchronization Service，DTSS）使用类似构NTP阶层模型的服务器层次结构。

1985年，NTPv0被实现于Fuzzball和Unix，文档化于RFC 958的NTP数据包头、和往返延迟和偏移计算都被留存至NTPv4。尽管当时可用的计算机和网络相对较慢，但在跨大西洋链路上也取得了优于100毫秒的精度，在以太网网络上准确度为几十毫秒。

1988年，一个更完整的NTPv1协议规范及相关的算法发表在RFC 1059。它利用了RFC 956的文献中的实验结果和时钟滤波算法，并是第一个描述客户端-服务器和对等网络模型的版本。1991年，NTPv1架构、协议和算法通过大卫·米尔斯在IEEE通信汇刊发布的一篇文章得到了工程学界的更广泛关注。

1989年，RFC 1119发布通过有限状态机定义的NTPv2，使用伪代码来描述其操作。它引入了一个管理协议和加密认证方案，它们留存至NTPv4。社区批评NTP的设计缺乏形式正确性原则。他们的替代设计包括Marzullo算法，其修改版本已及时添加到NTP。这个时代的大多数算法也大部分留存至NTPv4。

1992年，RFC 1305定义了NTPv3。该RFC包括一个对所有错误来源的分析，从参考时钟至最终客户端，这使帮助度量和选择最佳服务器成为可能（在其中几个候选者反对的情况下）。广播模式被引入。

在接下来的几年里，随着新特性的添加和算法的改进，显然还需要一个新的协议版本。2010年，RFC 5905发布了一个对NTPv4的建议规范，但该协议自那时以来已经显著改变，截至2014年，更新的RFC尚未发布。在Mills从特拉华大学退休后，该参考实现目前由Harlan Stenn保持为一个开放源代码项目。

## 时钟层

<image>

<image>

NTP使用一个分层、半分层的时间源系统。该层次的每个级别被称为“stratum”，顶层分配为数字0。一个通过阶层n同步的服务器将运行在阶层n + 1。数字表示与参考时钟的距离，用于防止层次结构中的循环依赖性。阶层并不总是指示质量或可靠性；在阶层3的时间源得到比阶层2时间源更高的时间质量也很常见。电信系统对使用不同的定义。以下提供了阶层0、1、2、3的简要描述。

阶层0（Stratum 0）：这些是高精度计时设备，例如原子钟（如铯、铷）、GPS时钟或其他无线电时钟。它们生成非常精确的脉冲秒信号，触发所连接计算机上的中断和时间戳。阶层0设备也称为参考（基准）时钟。

阶层1：这些与阶层0设备相连、在几微秒误差内同步系统时钟的计算机。阶层1服务器可能与其他阶层1服务器对等相连，以进行完整性检查和备份。它们也被称为主要（primary）时间服务器。

阶层2：这些计算机通过网络与阶层1服务器同步。提供阶层2的计算机将查询多个阶层1服务器。阶层2计算机也可能与其他阶层2计算机对等相连，为对等组中的所有设备提供更健全稳定的时间。

阶层3：这些计算机与阶层2的服务器同步。它们使用与阶层2相同的算法进行对等和数据采样，并可以自己作为服务器担任阶层4计算机，以此类推。

阶层的上限为15；阶层16被用于标识设备未同步。每台计算机上的NTP算法相互构造一个贝尔曼-福特算法最短路径生成树，以最小化所有客户端到阶层1服务器的累积往返延迟。

## 时间戳

NTP使用64位元的时间戳，其中32位元表示秒，32位元表示秒的小数，给出一个每232秒（136年）才会翻转的时间尺度，理论分辨率2−32秒（233皮秒）。NTP以1900年1月1日作为开始时间，因此第一次翻转将在2036年2月7日发生。

NTP的未来版本可能将时间表示扩展到128位元：其中64位元表示秒，64位元表示秒的小数。当前的NTPv4格式支持“时代数字”（Era Number）和“时代偏移”（Era Offset），正确使用它们应该有助于解决日期翻转问题。据Mills称：“64位元的秒小数足以分辨光子以光速通过电子所需的时间。64位元的秒足以提供明确的时间表示，直到宇宙变暗。”

## 时钟同步算法

<image>

典型的NTP客户端将定期轮询不同网络上的三个或更多服务器。为同步其时钟，客户端必须计算其时间偏移量和来回通讯延迟。时间偏移“θ”定义为：

$\theta = {(t_1 - t_0) + (t_2 - t_3 ) \over 2}$。

往返延迟“δ”为：

$\delta = {(t_3 - t_0 ) - ( t_2- t_1 )}$。

其中：

t0 是请求数据包传输的客户端时间戳。

t1 是请求数据包回复的服务器时间戳。

t2 是响应数据包传输的服务器时间戳

t3 是响应数据包回复的客户端时间戳。

“θ”和“δ”的值通过过滤器并进行统计分析。异常值被剔除，并从最好的三个剩余候选中导出估算的时间偏移。然后调整时钟频率以逐渐减小偏移，创建一个反馈回路。

当客户端和服务器之间的输入和输出路由都具有对称的标称延迟时，同步是正确的。如果路由没有共同的标称延迟，则将差异取半作为测量误差。

## 软件实现

<image>

### 参考实现

NTP参考实现连同协议的开发已持续发展了20多年。随着新功能的添加，向后兼容性仍保持不变。它包含几个敏感的算法，尤其是时钟规律，在同步到使用不同算法的服务器时可能会发生错误。该软件已移植到几乎各个计算平台，包括个人计算机。它在Unix上运行名为ntpd的守护进程，或在Windows上运行为一个Windows服务。支持参考时钟，并且以与远程服务器相同的方式对偏移进行过滤和分析，尽管它们通常更频繁地轮询。

### SNTP

一个复杂度更低的NTP实现，使用相同协议，但不需要长时间储存状态 (计算机科学)，也称简单网络时间协议（Simple Network Time Protocol，SNTP）。被某些嵌入式系统和不需要高精度时间的应用所采用。

### Windows时间服务

从Windows 2000起的所有Microsoft Windows版本都包括Windows时间服务（W32Time），其具有将计算机时钟同步到NTP服务器的能力。

W32Time服务最初是为实现Kerberos第五版的身份验证协议，它需要误差5分钟内正确时间值以防止重放攻击。Windows 2000和Windows XP中只实现了简单的NTP，并在几个方面违反了NTP第3版的标准。从Windows Server 2003和Windows Vista开始，已包括符合完整NTP的实现。微软称W32Time服务不能可靠地将同步时间保持在1至2秒的范围内。如果需要更高的精度，微软建议使用其他NTP实现。

Windows 10 与 Windows Server 2016 由版本 1607 开始，提供高精度的系统时间，支持1ms的时间精度。

### Ntimed

一个新的NTP客户端ntimed由Poul-Henning Kamp在2014年开始编写。新的实现由Linux基金会赞助，作为参考实现的一个替代，因为它决定更容易地从头开始编写新的实现，而不是修复现有大型代码库的现有问题。截至2015年6月，它尚未正式发布，但ntimed可以可靠地同步时钟。ntimed在Debian和FreeBSD上工作，但也被移植到Windows和Mac OS。

## 闰秒

在闰秒事件的当天，ntpd从配置文件、附加参考时钟或远程服务器收到通知。因为时间必须是单调递增，所以闰秒的插入方式为：23:59:59、23:59:60、00:00:00。虽然时钟实际上在事件期间停止，但任何查询系统时间的进程都会使它增加微小的量，以保持事件的顺序。如果必要，在序列中删除闰秒的形式为：23:59:58、00:00:00，跳过23:59:59。

## 安全问题

2014年底，几个安全问题被发现。在以前，研究人员发现NTP服务器可能受到中间人攻击的影响，除非数据包被加密和签名以验证身份。但这所涉及的计算量在繁忙的服务器上可能是不切实际的，尤其是容易遭遇阻断服务攻击。NTP消息欺骗可以被用来偏移客户端计算机上的时钟，并配合过期的加密密钥来完成其他攻击。可能受到伪造NTP消息影响的服务包括TLS、DNSSEC、各类缓存方案（例如DNS缓存）、比特币以及许多持久登录方案。

有着25年以上历史的NTP代码库中的参考实现中只发现了几个其他的安全问题，但最近出现的几个引起了人们的强烈关注。该协议正在对其整个历史进行修订和审查。截至2011年1月，在NTP规范中没有安全修订，也没有在CERT协调中心的报告。几年来，该参考实现的当前代码库已经被多个来源进行安全审计，在当前发布的软件中没有已知的高风险漏洞。

多种NTP服务器误用和滥用实践的存在导致了对网络时间协议（NTP）服务器的破坏或劣化。

NTP已经被用于分布式拒绝服务（DDoS）攻击，方法是将一个具有伪造的返回地址的小的查询发送到NTP服务器。类似DNS放大攻击，服务器将以比攻击者发送数据量大很多倍的数据量回复给伪造的目标。为了避免参与攻击，服务器可以配置为忽略外部查询，或者升级到4.2.7p26或更高版本。

一个缓冲区溢位漏洞已经被发现，并自2014年12月19日提供补丁。漏洞覆盖NTP第四版所有版本，自4.2.8修复。苹果公司首次使用自动更新功能解决该问题，不过这仅适用最近的MacOS版本。在10.6.8版本中，用户可以手动修复服务器版本，以及普通用户可以在系统首选项-日期和时间中关闭自动更新时间。研究人员认为该协议的设计是相当好的，缺陷出现在协议的实现中。某些错误很基础，例如例程中缺少返回语句，这可能导致某些运行在root权限下的NTP版本被利用以无限制的访问系统。守护进程不使用root权限的系统（例如BSD）不受此缺陷的影响。

## 外部链接

- 公共NTP服务器列表
- NTP节点镜像群
- IETF NTP working group
- Time and NTP paper
- NTP Survey 2005
- Current NIST leap seconds file compatible with ntpd
- David L. Mills, A Brief History of NTP Time: Confessions of an Internet Timekeeper
- Keith Marzullo's homepage
- NTP Server Test Online Tool