Windows Server для самых маленьких. Часть 12: Как устроено время в домене?

Все части серии «Windows Server для самых маленьких»

В части 6 аутентификатор Kerberos нёс метку времени, и KDC отвергал его при расхождении больше пяти минут. В части 10 конфликт репликации при равных версиях решался по метке времени. Сертификаты, которые появятся в части 25, имеют срок начала действия; журналы, которые мы читаем в каждой части, бесполезны, если на двух серверах часы показывают разное. Время в домене — не удобство, а условие работы, и у Windows для него есть отдельная служба со своей иерархией, протоколом и правилами, которые стоит понять один раз.


Иерархия

Служба времени Windows — W32Time, служба w32time. Она говорит по NTP версии 3 (RFC 1305) — по словам самой Microsoft, это не точная реализация стандарта — с расширением MS-SNTP для подписи ответов. Внутри домена источники времени выстроены в дерево:

                   Внешний источник: pool.ntp.org, GPS-часы, NTP провайдера
                            │
             PDC-эмулятор корневого домена леса  (stratum 2–3)
                     ┌──────┴──────┐
     PDC-эмуляторы дочерних доменов   остальные контроллеры корневого домена
             │                              │
     контроллеры дочернего домена     члены домена: серверы и рабочие станции
             │
     члены дочернего домена

Правило простое: каждый берёт время у того, кто выше. Рабочая станция и рядовой сервер — у контроллера своего домена, контроллер — у PDC-эмулятора своего домена (или у контроллера родительского домена), PDC дочернего домена — у надёжного источника своего домена или у любого контроллера родительского, а PDC корневого домена — ни у кого: он вершина, и источник ему назначает администратор. Этот режим называется NT5DS (domain hierarchy), и он включается у машины автоматически при вступлении в домен:

PS C:\> w32tm /query /configuration | Select-String 'Type|NtpServer|AnnounceFlags'
AnnounceFlags: 10 (Local)
Type: NT5DS (Local)
NtpServer: time.windows.com,0x9 (Local)
NtpServer (Local)

Строки идут в порядке разделов вывода: AnnounceFlags — из общего раздела [Configuration], Type и NtpServer — из настроек поставщика NtpClient в разделе [TimeProviders], а NtpServer (Local) — заголовок второго поставщика, серверной части службы. Конфигурацию, как и w32tm /query /source ниже, служба показывает только в окне администратора; без повышенных прав обе команды отвечают Access is denied. (0x80070005).

Type: NT5DS — брать время по иерархии домена; значение NtpServer при этом не используется. AnnounceFlags имеет смысл только у контроллеров: 0x1 — «всегда сервер времени», 0x2 — «сервер времени автоматически», 0x4 — «всегда надёжный сервер», 0x8 — «надёжный сервер автоматически». Значение по умолчанию 10 — это 0x2 + 0x8: решение объявлять себя принимает служба, и контроллер с несинхронизированными часами объявлять себя перестаёт. У PDC с ручным источником ставят 5 = 0x1 + 0x4: «всегда сервер времени» и «всегда надёжный».

Откуда член домена знает, у кого спросить? У того же DC Locator из части 3: в ответе контроллера есть флаги TIMESERV и GTIMESERV, и W32Time выбирает контроллер с первым, предпочитая второй. Флаг TIMESERV контроллер поднимает, когда сам синхронизирован; GTIMESERV — когда объявлен надёжным. Поэтому контроллер с AnnounceFlags по умолчанию, потерявший синхронизацию, перестаёт объявлять себя сервером времени (событие 142, а надёжным сервером — событие 144), и клиенты уходят к другому.


Почему ответ подписан

Обычный NTP ничем не защищён: любой, кто ответит быстрее, задаст клиенту время, а время — это пять минут до отказа Kerberos. В домене W32Time использует MS-SNTP: клиент посылает запрос с идентификатором ключа, младший 31 бит которого — RID его учётной записи компьютера, а старший — какой пароль взять, текущий или предыдущий. Контроллер через Netlogon считает MD5 от хеша пароля этой учётной записи и самого ответа и кладёт результат в ответ. Клиент проверяет подпись своим паролем, а неподписанный или неверно подписанный ответ отбрасывает. Подделать ответ, не зная пароля машины, нельзя, а пароль машины знают только она и контроллеры.

Из этого два следствия. Член домена в режиме NT5DS не возьмёт время у NTP-сервера, который не контроллер, даже если тот указан в опции 42 DHCP: служба синхронизируется только по иерархии домена. И у машины с испорченным защищённым каналом (той самой, у которой «trust relationship failed») время тоже перестаёт синхронизироваться, хотя она об этом не сообщает.

Устройства не из домена — коммутаторы, Linux-серверы, принтеры — могут брать время с контроллера обычным NTP без подписи: контроллер отвечает на порт 123 всем. Для них опция 42 и нужна, и указывать в ней стоит контроллеры, чтобы время во всей сети шло от одного источника.


PDC-эмулятор

Вершина иерархии после установки леса ничем не настроена. PDC корневого домена пишет в журнал событие 12: машина настроена брать время по иерархии домена, но она PDC-эмулятор корневого домена леса, и выше неё в иерархии никого нет. Пока ему не назначить внешний источник, весь лес живёт по часам материнской платы dc1, которые уходят на секунды в сутки. Внутри домена всё будет согласовано, но с внешним миром — нет, а внешний мир — это сертификаты, облачные службы и журналы провайдера.

Назначаем на PDC — и только на нём:

PS C:\> w32tm /config /manualpeerlist:"0.pool.ntp.org,0x8 1.pool.ntp.org,0x8 2.pool.ntp.org,0x8" /syncfromflags:manual /reliable:yes /update
The command completed successfully.
PS C:\> Restart-Service w32time
PS C:\> w32tm /resync /rediscover
Sending resync command to local computer
The command completed successfully.
PS C:\> w32tm /query /status
Leap Indicator: 0(no warning)
Stratum: 3 (secondary reference - syncd by (S)NTP)
Precision: -23 (119.209ns per tick)
Root Delay: 0.0234375s
Root Dispersion: 0.0617432s
ReferenceId: 0xC000027B (source IP:  192.0.2.123)
Last Successful Sync Time: 15.10.2026 13:02:41
Source: 0.pool.ntp.org,0x8
Poll Interval: 10 (1024s)

Флаги после имени сервера: 0x8 — клиентский режим (запрос-ответ, без симметричных ассоциаций), 0x1 — использовать особый интервал опроса SpecialPollInterval вместо адаптивного, 0x2 — резервный источник, к которому обращаться только при недоступности остальных. /syncfromflags:manual — брать время только из списка; /reliable:yes — объявить себя надёжным источником, то есть выставить AnnounceFlags в 5 и поднять флаг GTIMESERV. В организации с собственным источником времени — GPS-приёмником или NTP-сервером провайдера — в списке будет он.

Stratum 3 в выводе: pool.ntp.org отдал сервер уровня 2, мы на уровень ниже. Остальные контроллеры будут на уровне 4, члены домена — 5. Чем ниже, тем больше накопленная погрешность, но для пяти минут Kerberos этого достаточно с огромным запасом.

Проблема этой настройки — она привязана к машине, а роль PDC привязана к домену. Когда роль переедет на dc2 (часть 17), dc2 окажется вершиной без источника, а dc1 продолжит ходить в интернет и объявлять себя надёжным, и у домена станет два источника правды. Решение, которое описывает служба поддержки Microsoft в блоге AskDS, — групповая политика, привязанная к OU Domain Controllers с WMI-фильтром на роль PDC (значение 5 свойства DomainRole — Primary Domain Controller):

SELECT * FROM Win32_ComputerSystem WHERE DomainRole = 5

Политика задаёт NTP-клиент с ручным списком серверов и AnnounceFlags = 5; применяется она только к той машине, у которой сейчас роль, и при переносе роли переезжает вместе с ней на следующем обновлении политики. Как собрать такую политику, разберём в части 24; пока правило на бумаге: перенёс PDC — перенастрой время, и на старом PDC вернуть иерархию:

PS C:\> w32tm /config /syncfromflags:domhier /reliable:no /update

Пределы корректировки

W32Time не переводит часы скачком при любом расхождении. Два параметра в HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Config:

  • MaxPosPhaseCorrection и MaxNegPhaseCorrection — максимальная поправка вперёд и назад, которую служба согласна применить. У контроллеров по умолчанию 172 800 секунд (48 часов), у членов домена ограничения нет (0xFFFFFFFF), у автономных машин — 54 000 секунд (15 часов). Если источник говорит, что часы ушли больше, служба отказывается, пишет событие 34 и продолжает жить по своим часам. Это защита: один контроллер с сорвавшимися часами не утащит за собой весь домен. Обратная сторона — контроллер, пролежавший выключенным полгода с севшей батарейкой BIOS, после включения время не синхронизирует, пока его не поставить руками (Set-Date) или временно не поднять лимит.
  • Поправки не больше MaxAllowedPhaseOffset (у членов домена по умолчанию 300 секунд, у автономных машин — 1 секунда) служба вносит плавно: часы ускоряются или замедляются, пока не догонят. Больше — переставляет часы сразу, и в журнале появляется событие 52 с величиной сдвига.

Точность. Windows Server 2016 переписал алгоритм W32Time: при соблюдении условий — задержка до источника меньше 0,1 мс, не дальше stratum 5, не больше четырёх сетевых переходов — он держит точность до одной миллисекунды, а в обычной сети до 50 мс или секунды; для этого в документации есть отдельное руководство Accurate Time. По умолчанию членам домена достаточно секунд, а контроллеры опрашивают источник каждые 64–1024 секунды, подбирая интервал адаптивно. Windows Server 2019 добавил поддержку PTP (Precision Time Protocol, IEEE 1588) для сетей с аппаратными метками времени и корректную обработку високосных секунд.


Виртуальные контроллеры

Виртуальная машина получает время из двух мест: от W32Time по сети и от гипервизора через службы интеграции. Второй источник точнее и не зависит от сети, но он ломает иерархию: контроллер, берущий время у хоста, которому время задаёт NTP с другого источника или вовсе никто, синхронизирован с хостом, а не с PDC.

Как это устроено в Hyper-V. В госте работает поставщик времени VMICTimeProvider, который отдаёт W32Time образцы времени хоста; хост сообщает гостю свой stratum плюс один. На Windows Server 2016 и новее W32Time выбирает лучший из поставщиков — сначала по stratum, потом по задержке, разбросу и смещению, — и гость в домене находит самый точный источник, а не берёт время хоста по умолчанию.

Для контроллеров у Microsoft две рекомендации, и они расходятся. Страница о виртуальных контроллерах на Hyper-V советует отключить синхронизацию времени с хостом для гостя-контроллера целиком — службу интеграции Time Synchronization, это делается на хосте:

PS C:\> Disable-VMIntegrationService -VMName dc1 -Name 'Time Synchronization'

Руководство по точному времени Windows Server 2016 предлагает более мягкий вариант для гостей 2012 R2 и старше — оставить службу интеграции, но отключить поставщика внутри гостя:

PS C:\> Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\VMICTimeProvider' -Name Enabled -Value 0
PS C:\> Restart-Service w32time

Смысл у обоих один: контроллер должен жить по иерархии домена, а не по часам хоста, которые могут идти от другого источника или ни от какого. У VMware свои настройки синхронизации в VMware Tools, и цель та же.

Что не нужно делать с контроллером: откатывать его к снимку. Часы при этом прыгнут назад, и W32Time их поправит, но каталог окажется в прошлом относительно партнёров — это USN rollback, который репликация обнаруживает и останавливает, и которому посвящён отдельный раздел части 18. Контроллеры Windows Server 2012 и новее защищены VM-GenerationID: гипервизор меняет этот идентификатор при откате, каталог замечает и сбрасывает свой invocationID и пул RID, после чего безопасно реплицируется заново. Но это спасение после катастрофы, а не способ работы.


Что ломается

Расхождение больше пяти минут с контроллером:

  • Kerberos отвечает KRB_AP_ERR_SKEW. Клиент Windows умеет восстанавливаться: вместе с ошибкой контроллер сообщает своё время, клиент повторяет запрос, подставив его, и аутентификация проходит. Это спасает вход, но не всё остальное.
  • Репликация между контроллерами идёт по RPC с Kerberos и останавливается. В repadmin /showrepl это ошибка 5 «Access is denied», и про время она ничего не говорит; подсказывают dcdiag /test:CheckSecurityError со строкой «Time skew error» и «Replicate now» в оснастке сайтов с сообщением «There is a time and/or date difference between the client and server» (ошибка 1398).
  • Сертификаты с датой начала в будущем отвергаются; автозачисление (часть 25) молча не выдаёт сертификат.
  • DFS-R разрешает конфликты по принципу «побеждает последний записавший», сравнивая отметки времени обновлений, и изменение с отставшего сервера может проиграть более раннему.

Диагностический признак: ошибки аутентификации, которые появились разом у всех пользователей или всех серверов одного сайта. Первое, что проверить: w32tm /monitor.


Смотрим руками

Состояние всех контроллеров домена одной командой — с любой машины домена:

PS C:\> w32tm /monitor
Getting AD DC list for default domain...
dc2.corp.example.com[192.168.1.11:123]:
    ICMP: 0ms delay
    NTP: -0.0012418s offset from dc1.corp.example.com
        RefID: dc1.corp.example.com [192.168.1.10]
        Stratum: 4
dc1.corp.example.com *** PDC ***[192.168.1.10:123]:
    ICMP: 0ms delay
    NTP: +0.0000000s offset from dc1.corp.example.com
        RefID: (unknown) [0x7B0200C0]
        Stratum: 3
dc3.corp.example.com[192.168.2.10:123]:
    ICMP: 18ms delay
    NTP: +0.0048102s offset from dc1.corp.example.com
        RefID: dc1.corp.example.com [192.168.1.10]
        Stratum: 4

Warning:
Reverse name resolution is best effort. It may not be
correct since RefID field in time packets differs across
NTP implementations and may not be using IP addresses.

RefID — у кого контроллер берёт время, offset — расхождение с PDC. Контроллеры идут не по алфавиту, PDC помечен *** PDC ***. Источник самого PDC часто выглядит как (unknown): w32tm пытается превратить RefID в имя обратным запросом DNS, а если не вышло, печатает его в квадратных скобках с байтами в обратном порядке — 0x7B0200C0 здесь и есть 192.0.2.123, тот же 0xC000027B из w32tm /query /status. Об этом и предупреждение в конце вывода. Миллисекунды — норма; секунды — повод смотреть журнал; минуты — авария. w32tm /monitor /domain:eu.corp.example.com проверит дочерний домен.

Источник конкретной машины и его происхождение:

PS C:\> w32tm /query /source
dc1.corp.example.com

PS C:\> w32tm /query /peers
#Peers: 1

Peer: dc1.corp.example.com
State: Active
Time Remaining: 412.3764110s
Mode: 3 (Client)
Stratum: 3 (secondary reference - syncd by (S)NTP)
PeerPoll Interval: 10 (1024s)
HostPoll Interval: 10 (1024s)

Сравнение с произвольным сервером, не меняя настроек, — stripchart:

PS C:\> w32tm /stripchart /computer:dc1.corp.example.com /samples:3 /dataonly
Tracking dc1.corp.example.com [192.168.1.10:123].
Collecting 3 samples.
The current time is 15.10.2026 13:20:05.
13:20:05, +00.0011384s
13:20:07, +00.0010917s
13:20:09, +00.0011102s

Так проверяют, насколько рабочая станция, внешний NTP или сервер из другого домена расходятся с контроллером. Положительное значение — у цели время больше, чем у нас.

Запрос и ответ в пакетах — pktmon filter add -p 123, затем w32tm /resync на члене домена:

Network Time Protocol (NTP Version 3, client)
    Flags: 0x1b (LI: no warning, VN: 3, Mode: client)
    Peer Clock Stratum: unspecified or invalid (0)
    ...
    Transmit Timestamp: Oct 15, 2026 11:20:33.128745600 UTC
    Key ID: 0x00000450
    Message Authentication Code: 7c3f…e21a

Network Time Protocol (NTP Version 3, server)
    Flags: 0x1c (LI: no warning, VN: 3, Mode: server)
    Peer Clock Stratum: secondary reference (4)
    Reference ID: 192.168.1.10
    ...
    Key ID: 0x00000450
    Message Authentication Code: a91d…04c7

Key ID: 0x450 — 1104 в десятичной, RID учётной записи WS1$: по нему контроллер нашёл пароль машины для подписи. Пакет на 20 байт длиннее обычного NTP (68 вместо 48) — это и есть MS-SNTP.

Журнал службы времени — провайдер Microsoft-Windows-Time-Service в журнале System:

PS C:\> Get-WinEvent -FilterHashtable @{LogName='System'; ProviderName='Microsoft-Windows-Time-Service'} -MaxEvents 5 | Format-Table TimeCreated, Id, LevelDisplayName, Message -Wrap
Id Что
12 PDC корневого домена настроен на иерархию, а выше него никого нет: внешний источник не назначен
29 ни один источник не доступен, следующая попытка — через указанное число минут
34 нужная поправка больше MaxPosPhaseCorrection или MaxNegPhaseCorrection, часы не тронуты
35 служба начала синхронизироваться с указанным источником
36 время давно не синхронизировалось, и служба перестала раздавать его клиентам
37 от источника приходят правильные данные
47 источник из ручного списка не ответил и исключён
50 расхождение больше порога держится дольше заданного времени; служба считает себя несинхронизированной
52 служба переставила часы на указанную величину
129 не найден контроллер для синхронизации по иерархии
131, 134 имя контроллера из иерархии или источника из ручного списка не разрешилось в DNS
142, 144 машина перестала объявлять себя сервером времени (часы не синхронизированы) или надёжным сервером

Событие 129 на члене домена и 12 на PDC означают, что иерархия в этом месте оборвана.

И наконец, время каталога против времени машины:

PS C:\> [DateTime]::UtcNow.ToString('o'); (Get-ADRootDSE -Server dc2).currentTime.ToUniversalTime().ToString('o')
2026-10-15T11:21:40.4012389Z
2026-10-15T11:21:40.0000000Z

currentTime из RootDSE — часы контроллера с его точки зрения, с точностью до секунды; разница с локальным UTC — расхождение, которое увидит Kerberos.


Источники


На этом блок о домене закончен: три контроллера, DNS, DHCP для обоих семейств адресов и согласованное время. Следующие четыре части — о том, как всем этим управлять, не подходя к серверам. Начнём с инструмента, которым мы пользовались с части 4, но ни разу не разбирали.

Дальше — часть 13: PowerShell для Active Directory. Модуль ActiveDirectory и служба ADWS, через которую он работает; -Filter и -LDAPFilter, -Properties и -SearchBase; параметр -Server и выбор контроллера; массовые операции по конвейеру; диск AD:; Get-ADObject для всего, для чего нет отдельного командлета; и как не положить контроллер одним запросом.

Оставить комментарий могут только зарегистрированные пользователи.

Войдите на сайт или зарегистрируйтесь, чтобы оставить комментарий.