В статье описывается высокоточный протокол синхронизации времени NTP
(Network Time Protocol),
его реализация в Unix (Linux) и Cisco,
приводятся ссылки на списки публичных NTP серверов,
которые можно использовать для синхронизации.
Назначение протокола состоит в синхронизации клиента или
сервера с сервером или источником точного времени (радио, атомные часы или еще что).
Синхронизируется не только текущее
значение времени, но и частота отсчета таймера. Обеспечивает точность до
милисекунды в пределах LAN и десятков милисекунд посредством WAN. Предусмотрена
криптографическая защита (шифрование контрольной суммы), одновременное
подключение к нескольким серверам на случай аварии, алгоритмы усреднения и т.д.
Поддерживает самонастраиваемую иерархическую архитектуру сети синхронизации
(симметричный механизм обмена пакетами). Главные сервера (напрямую
присоединенные к источнику точного времени) образуют первый слой (stratum),
присоединенные непосредственно к ним - второй слой, и т.д.
Для обмена информацией между используется протокол UDP (порт 123).
Используется довольно сложные алгоритмы фильтрации, селекции и
комбинации пакетов на принципах максимальной вероятности. Протокол
обеспечивает поддержку множества
резервных серверов и путей передачи (выбор лучшего на основе алгоритма
взвешенного голосования). Достигаемая точность первичного сервера -
милисекунды. Типичный интервал опроса - от 1
минуты (в начале работы) до 17 минут (если все хорошо).
Сервер непрерывно корректирует ход локальных часов, используя вычисленную
информацию об отклонениях их частоты от истинной. Это позволяет уменьшить
частоту опроса и удерживать отклонения показаний часов от истинных при
временных сбоях сети. Подстройка частоты обеспечивает приличную точность
часов даже при модемном соединении с Интернет.
При больших отклонениях (более 128 мс) местного
времени от времени выбранного сервера коррекция производится скачком,
иначе путем подстройки частоты местных часов.
В качестве значения времени используется беззнаковое 64-битовое число с
фиксированной точкой, число секунд в UTC.
Первые 32 бита - число секунд, вторые 32 бита - дробная часть. Точность 232
пикосекунды. Старший бит взведен где-то в 1968 году,
переполнение наступит в 2036 году. 0 означает неопределенное время.
Возможные классы обслуживания:
multicast: для использования в быстрой локальной сети с
множеством клиентов и без необходимости в высокой точности, один или более
NTP-серверов рассылают broadcast, клиенты определяют время исходя из
предположения, что задержка составляет несколько милисекунд; сервер не
принимает ответных NTP сообщений
procedure-call: в условиях когда нужна высокая точность, а multicast
недоступен; NTP-клиент посылает NTP-запрос на сервер, который
обрабатывает его и немедленно посылает ответ; сервер не
синхронизируется с клиентом
symmetric: динамически реконфигурируемая иерархия серверов, каждый сервер
синхронизирует и синхронизируется своими соседями в
соответствии с правилами выбора соседей; активный режим
используется серверами низшего уровня (большой номер страта) с
преконфигурированными адресами соседей, пассивный режим
используется серверами близкими к корню и
взаимодействующими с соседями с заранее
неизвестными адресами; для каждой пары серверов, обменивающися
сообщениями, создается ассоциация.
Типичная конфигурация в небольшой организации включает 3 местных сервера,
каждый из которых подключен к трем внешним серверам
(9 различных внешних серверов!), местные сервера соединены между собой.
Не рекомендуется соединять между собой более 10 серверов.
Клиенты подключены к каждому из трех местных серверов.
При описании алгоритма используются следующие термины
стабильность
способность удерживать постоянную частоту
точность (аккуратность?)
совпадение с национальным стандартом
разрешение
точность измерения
смещение часов
разница во времени между ними
skew (расхождение?)
разница в частоте между ними
надежность
доля времени, в которое часы доступны
синхронизация часов
синхронизация частоты и времени
первичный (primary) источник
синхронизированный с национальным стандартом (провод, радио,
атомные часы)
Формат NTP-пакета:
LI (leap indicator) - в конце суток должна быть вставлена секунда для
синхронизации атомных (TAI) и астрономических часов (GMT)
VN - номер версии (3 или 4)
mode - режим работы
stratum - слой
precision - разрешение местных часов (log2)
poll interval - интервал запросов (используется минимальный из своего и
соседского, log2)
synchronization distance - полный цикл обмена
сообщениями (roundtrip delay) до первичного источника
synchronization dispersion - дисперсия этих задержек
reference clock identifier - тип опорных часов
reference timestamp - время последнего изменения опорных часов
(используется для управления)
originate timestamp - время соседа, когда последнее NTP-сообщение было
отправлено (копировано по прибытии из transmit timestamp)
receive timestamp - местное время получения этого последнего NTP-сообщения
transmit timestamp - местное время отправки текущего сообщения
authenticator (96 bit) - опция - ключ и шифрованная контрольная сумма
сообщения
Хотя для обмена информацией используется протокол UDP
(connectionless), сервера хранят информацию о соседях в переменных
состояния:
32-битные IP-адреса и 16-битные номера портов сервера и соседа,
определяющие ассоциацию
регистр фильтра: измеренные задержка/смещение и отдельный экземпляр
задержки/смещения
задержка, смещение, дисперсия
источник синхронизации: сосед, определенный алгоритмом выбора
местные часы
Для защиты от помех и ошибок передачи (UDP!) используются
следующие методы:
Если в течении 8 последовательных интервалов опроса от соседа не было
сообщений, то он считается недостижимым.
Делается проверка времен: если время передачи совпадает с
предыдущим сообщением, то это несомненно дубль; если originate timestamp в
сообщении не совпадает со значением передачи в переменных данной
ассоциации, то нас пытаются обмануть.
Делаются дополнительные защиты от очень старых сообщений и не полностью
синхронизованных ассоциаций.
Аутентификатор состоит из ключа и шифрованной
контрольной суммы - деляется с помощью алгоритма DES и
DES cipher block-chaning (CBC),
обеспечивает непрерывную цепочку сообщений между узлами, в которую
невозможно влезть (необходима компенсация времени шифровки).
Используются алгоритмы, время работы которых не зависит от ключа и шифруемого текста.
Версия 4 обеспечивает
большую
точность за счет учета дрожания (jitter) источника и скорости работы сети,
улучшенных алгоритмов обработки и подстройки локальных часов,
более быстрой "сходимости" при запуске (минуты вместо дней).
Это позволяет уменьшить частоту опроса клиентом серверов.
Добавлены возможности наносекундного разрешения локальных часов (Linux?),
управления с помощью SNMP и
автоматической конфигурации клиентов (multicast) с обеспечением безопасности
методами криптографии. В дополнение к алгоритмам симметричного шифрования
(к DES CBC добавлен MD5) используется алгоритм с открытым ключом (autokey,
работы не завершены).
chrony (chronyd как клиент и сервер) - реализация клиента и сервера протокола NTP.
Основным преимуществом перед ntpd декларируется возможность синхронизации времени клиентом при непостоянном доступе к сети
или непостоянной работе (виртуальные машины, гибернация), большая точность (миллисекунды в Интернет, десятки микросекунд в локальной сети,
меньше микросекунды пи использовании PTP).
+ возможность синхронизации при нестабильном сетевом подключении
+ готовность клиента к ассиметричному джитеру
+ произвольный шаг
+ предел синхронизации может быть более 1000 секунд
+ максимальный уход 100000 ppm вместо 500 ppm
+ температурная компенсация
+ возможность синхронизации при использовании режима сохранения энергии
- клиент не умеет broadcast, multicast и manycast
+ можно настроить порт клиента и сервера
- сервер не умеет multicast и manycast
- отсутствует autokey, кстати, небезопасный
+ имеется поддержка аппаратных отметок времени в пакетах
- не реализованы драйверы аппаратных часов, предлагается обращаться к внешним программам (SHM или сокеты)
+ поддержка режима реального времени
? особенности обработки лишней секунды
- отсутствие возможности удалённой конфигурации (зато порт не открыт по умолчанию вместе с возможностью удалённого управления и умножителем трафика!)
Изменения
пакет chrony 3.2 в RHEL 7.5, относительно chrony 3.1
поддержка режима NTP interleaved
опции mindelay и asymmetry в директивах описания сервера, соседа и пула
опции extpps и pps и width директивы refclock
опция rxfilter директивы hwtimestamp
возможность запретить управлять системными часами (-x)
журнал в файл вместо syslog (-l)
возможность указать несколько ключей командной строки (?)
возможность запуска без привилегий суперпользователя и ключе "-Q"
? аппаратная синхронизация на групповых Ethernet интефейсах (bonding, bridging)
пакет chrony 3.1 в RHEL 7.4
пакет chrony 2.1.1 в RHEL 7.0
Ключи запуска chronyd:
-4 # только IPv4
-6 # только IPv6
-f /etc/chrony.conf # файл с настройками
-n # не отсоединяться от терминала
-d # не отсоединяться от терминала и выводить на терминал вместо syslog
-l имя-файла # выводить сообщения в файл вместо syslog
-q # установить системные часы и завершиться
-Q # вывести требуемое смещение, но не устанавливать системные часы, выполняется без привилегий суперпользователя
-r # загрузить историю обращений к серверам и источникам из файлов ("chronyc dump") и удалить файлы
-R # игнорировать положительные смещения в директивах initstepslew и makestep
-s # установить системное время по часам реального времени (RTC)
-t секунд # ожидание при использовании "-q" и "-Q"
-u пользователь # chrony, под каким пользователем работать после сброса привилегий
-F режим # 0; режим использования фильтров системных вызовов: 0 - не фильтровать, 1 - убивать процесс, если он вызвал запрещённый системный вызов,
-1 - выдавать сигнал SYSSIG
-P приоритет # реального времени (от 0 до 100)
-m # не позволять вытеснять в swap
-x # не изменять системное время, но можно работать как NTP сервер
-v # вывести версию и опции сборки
Файл настроек (по умолчанию /etc/chrony.conf) имеет строчный формат, каждая директива на отдельной строке.
Директивы могут быть указаны в командной строке.
Комментарии начинаются с символов "#", "%", ";" или "!".
Основные директивы:
клиент
server имя-хоста-или-IP [опции] # описывет источник времени, вышестоящий в иерархии; опции:
minpoll степень-2-секунд # по умолчанию - 6, минимальный интервал опроса, может быть отрицательная степень (-1 - это 0.5 секунды)
maxpoll степень-2-секунд # по умолчанию - 10
iburst # интервал между первыми 4 опросами будет 2 секунды
key номер # номер пароля из keyfile, пароль используется для генерации контрольной суммы пакетов
maxdelay секунд # по умолчанию - 3, игнорировать задержавшиеся в пути ответы
prefer
noselect # не использовать, но отслеживать
trust # считать правильным, если нет противоречий с другими доверенными источниками
require # для установки часов д.б. выбран хотя бы 1 такой источник
port 123
presend степень-2-секунд # предварительный запрос для обновления ARP кеша
minstratum уровень # не использовать некачественный источник
version версия-протокола
pool имя-DNS [опции] # имя DNS описывает несколько IP-адресов серверов, возможно изменяющихся во времени
peer имя-хоста-или-IP [опции] # описывает равноправный сервер NTP; не рекомендуется без опции key; рекомендуется заменить на server в двух направлениях
initstepslew секунд сервер ... # если при старте chronyd расхождение с серверами больше указанного,
то поменять системное время скачком вместо плавной подстройки
refclock ... # описание аппаратного источника времени
manual # разрешить использовать команду "chronyc settime"
acquisitionport UDP-порт # для исходящих запросов
bindacqaddress IP-адрес # к какому IP адресу привязывать запросы клиента
dumpdir каталог # место хранения истории измерений
dumponexit # сохранять историю измерений при выходе (устарело?)
maxsamples число # максимальное количество отсчётов, хранимых для каждого источника, по умолчанию - 0, т.е. бесконечность
minsamples число # минимальное количество отсчётов, хранимых для каждого источника, по умолчанию - 6
maxdistance секунд # источник не д.б. дальше указанного (включая дисперсию)
maxjitter секунд
minsource число # 1, д.б. не менее указанного количества подходящих источников
corrtimeratio отношение # по умолчанию - 3, увеличение уменьшает ошибку частоты системных часов, но увеличивает время подстройки
driftfile /var/lib/chrony/drift # место хранения характеристик местных часов, позволяет подстраивать системное время до завершения
синхронизации с источником
leapsecmode {system | step | slew | ignore} # что делать с лишними секундами между UTC и TAI; по умолчанию - system (ядро делает скачок)
makestep секунд число-изменений # если расхождение времени больше указанного, то изменять время скачком первые "число" раз
maxchange лимит число-изменений число-превышений # если расхождение времени больше лимита (в секундах) после указанного числа изменений,
то не синхронизовать время и выйти после указанного числа превышений; по умолчанию - ?
maxdrift число-в-ppm # максимально допустимая ошибка частоты аппаратных часов; по умолчанию - 500000, драйвер Linux не умеет более 100000
maxupdateskew лимит-ухода # по умолчанию - 1000 ppm, считать измерения ненадёжными, если уход больше указанного лимита;
для локальной сети д.б. порядка 10
maxslewrate число-в-ppm # максимальная скорость подстройки системных часов (см. также corrtimeratio); по умолчанию - 83333.333 (1/12)
tempcomp ... # температурная компенсация
сервер
allow {all | IP-адрес/длина-маски-сети} # разрешить доступ к NTP серверу, по умолчанию доступ запрещён, логика упорядочения директив allow и deny мутная
deny {all | IP-адрес/длина-маски-сети}
bindaddress IP-адрес # к какому IP адресу привязывать сервер
port порт # по умолчанию - 123
broadcast интервал-в-секундах IP-адрес [порт]
clientloglimit байт # размер журнала доступа клиентов, по умолчанию - тысячи клиентов
noclientlog # не хранить журнал доступа (не будет работать "chronyc clients")
local опции # сам себе источник времени
stratum слой # серверу будет приписан указанный слой при отсутствии синхронизации с внешним источником; по умолчанию - 10
distance секунд # лимит времени доступа к источнику (задержка/2+дисперсия), после которго сервер будет считать себя самостоятельным; по умолчанию - 1
orphan # сервера из того же слоя не воспринимаются как источники, необходимо, чтобы не колбасило при временной изоляции сети
ntpsigndsocket каталог # smbd может подписывать ответы на запросы клиентов MS-SNTP
ratelimit # ограничения на ответы клиенту, см. clientloglimit
interval степень-2-секунд # минимальный интервал между запросами, по умолчанию - 3 (8 секунд)
burst число # количество первоначальных запросов в обход лимита на интервал, по умолчанию - 8i
smoothtime максимальное-изменение-частоты-ppm частота-изменения-частоты-ppm [leaponly] # сглаживание времени перед отдачей клиентам,
не рекомендуется если клиенты используют несколько серверов
управление (команды chronyc)
bindcmdaddress IP-адрес-или-сокет # к какому IP адресу или сокету привязывать управление;
по умолчанию - 127.0.0.1:323 и [::1]:323 и /var/run/chrony/chronyd.sock (/var/run/chrony имеет права доступа 750 для chrony:chrony);
для запрета указать "/"
cmdport -UDP-порт # 0 - запретить; по умолчанию - 323
cmdallow { IP-адрес/длина | all } # разрешить управляющий доступ (chronyc) к NTP серверу, по умолчанию доступ разрешён с 127.0.0.1
cmddeny { IP-адрес/длина | all }
cmdratelimit # ограничения на запросы мониторинга по сети; запросы к локальному интерфейсу не ограничиваются; опции - см. ratelimit
часы реального времени
hwclockfile имя-файла # файл /etc/adjtime, используемый hwclock (скорость ухода часов реального времени и текущий уход;
часы реального времени содержат локальное время или UTC); по умолчанию - файла нет
rtcautotrim секунд # подводить часы реального времени в соответствии с системными часами при превышении расхождения, обязательно rtcfile
rtcfile имя-файла # куда писать измерения RTC (/var/lib/chrony/rtc), несовместим с rtcsync
rtcsync # не отслеживать точность часов реального времени, сохранять системное время в часы реального времени каждые 11 минут
rtconutc # часы реального времени в UTC; по умолчанию - нет (часы реального времени показывают локальное время); см. hwclockfile
журналы
logdir каталог # куда писать журналы (/var/log/chrony)
log # записывать указанный журнал
rawmeasurements # каждый пакет от источника записывается в measurements.log
measurements # прошедшие проверку пакеты от синхронизированных источников в measurements.log
statistics # статистика источника в statistics.log (время, IP, ожидаемое стандартное отклонение, ожидаемое смещение и пр.)
tracking # изменения в работе локального времени относительно источника в tracking.log (время, IP, стратум, отклонение частоты в ppm,
ошибка изменения частоты в ppm, смещение, leap-секунда, количество комбинированных источников, ожидаемое стандартное отклонение смещения,
недоделанная коррекция смешения, задержка и дисперсия источника,
максимальная ожидаемая ошибка (смещение+задержка+дисперсия_задержки+недоделанная_коррекция)
rtc # статистика часов реального времени в rtc.log, если отслеживается
refclocks # статистика аппаратного источника времени в refclocks.log
tempcomp # статистика температурной компенсации в tempcomp.log
logchange секунд # по умолчанию - 1; при превышении указанного предела генерируется сообщение на syslog
mailonchange адрес секунд # при превышении указанного предела посылается письмо на указанный адрес
прочее
hwtimestamp имя-интерфейса [опции] # использовать PTP, недопустимо использовать один интерфейс с ptp4l (linuxptp);
рекомендуется "server имя minpoll 0 maxpoll 0 xleave", в журнале д.б. записи вида "chronyd: Enabled HW timestamping on ...";
подхватился ли можно понять по "chronyc ntpdata"
include шаблон
keyfile имя-файла # /etc/chrony.keys, содержит строки с номерами и паролями для генерации MAC (message authentication code)
lock_all # не вытеснять chromyd из памяти
pidfile имя-файла
sched_priority приоритет-реального-времени
user имя-пользователя # chrony
Утилита chronyc позволяет управлять сервером chronyd в режиме командной строки
локально (сокет /var/run/chrony/chronyd.sock, /var/run/chrony имеет права доступа 750 для chrony:chrony) или по сети, по умолчанию - только локально и от 127.0.0.1.
По сети в новых версиях доступны только команды мониторинга: activity, manual list, rtcdata, smoothing, sources, sourcestats, tracking, waitsync.
Изменения конфигурации, внесённые утилитой chronyc, будут утеряны при перезапуске chronyd.
Ключи chronyc:
-4 # только IPv4
-6 # только IPv4
-n # не преобразовывать DNS имена в IP адреса
-c # вывод в формате CSV, без преобразований величин
-h имя-хоста
-p управляющий-порт
-v # вывод версии и завершение работы
Основные команды chronyc:
help
exit | quit
activity # что вообще происходит?! сколько у нас серверов и соседей в различных состояниях
serverstats # количество полученных и потерянных пакетов, команд
tracking # состояние синхронизации: идентификатор источник (IP адрес, 7F7F0101 - локальный источник),
наш стратум, смещение системного времени от предполагаемого, смещение при последнем измерении, среднее смещение,
отклонение частоты системного времени в ppm, сетевая задержка то стратума 1, отклонение задержки, интервал измерений, лишняя секунда
sources [-v] # информация о текущем состоянии источников: режим, состояние, IP адрес, стратум, интервал (степень 2), доступность, смещение,
полная ошибка
sourcestats [-v] # статистика источников
ntpdata [адрес] # подробности из пакета NTP
makestep # изменить системное время немедленно и грубо
waitsync # ожидать синхронизации
reselect # выбрать источник
add peer адрес
add server адрес
delete адрес
offline адрес
online адрес
refresh # заново определить IP адреса по DNS именам
manual {on | off } # разрешить команду settime
settime время # установить время вручную в формате getdate
accheck адрес # проверить доступность сервера клиенту с указанного адреса
clients # получить список клиентов
allow [all | подсеть] # разрешить доступ клиентам
deny [all | подсеть]
local off # мы не источник
local опции
smoothing # работает ли сглаживание
smoothtime {activate | reset}
rtcdata # состояние часов реального времени
cyclelogs # переоткрыть файлы журналов (позволяет их переименовать)
dump # записать историю измерений в каталог, указанный директивой dumpdir
Имеется служба chronyd.service для запуска NTP сервера chrony в systemctl (/usr/lib/systemd/system/chronyd.service),
ключи chronyd можно задать в /etc/sysconfig/chronyd (по умолчанию пусто).
Отсутствует reload.
Служба chrony-wait.service (/usr/lib/systemd/system/chrony-wait.service) позволяет организовать ожидание завершения синхронизации (600 секунд).
Имеется скрипт /etc/dhcp/dhclient.d/chrony.sh для обработки запросов DHCP
(вызывает скрипт /usr/libexec/chrony-helper с параметром update_daemon).
Информация о серверах NTP от DHCP хранится в /var/lib/dhclient/chrony.servers.ИмяИнтерфейса.
Скрипт /usr/libexec/chrony-helper также умеет обрабатывать SRV записи DNS типа _ntp._udp.
Использует chronyc.
как его отключить? Цепляет сам себя. Пришлось править настройки DHCP. Для ntpd работало размещение "PEERNTP=no" в /etc/sysconfig/network
Скрипт /etc/NetworkManager/dispatcher.d/20-chrony вызывается при поднятии и опускании сетевых интерфейсов
и вызывает chronyc для редактирования списка NTP серверов по ответам DHCP.
/var/lib/chrony/rtc
Скрипт для архивации журналов - /etc/logrotate.d/chrony.
Для псевдоизолированной сети настраивал следующим образом (схема из времён, когда ещё не было режима orphan):
сервер ntfref имеет доступ к внешним NTP серверам (server IP-адрес; ...; driftfile /var/lib/chrony/drift; rtcsync; local stratum 10; allow ...
сервера ntp1 и ntp2 обращаются к ntfref и пирят друг друга (driftfile /var/lib/chrony/drift; rtcsync; local stratum 10; allow ...)
В любом случае для надежной работы рекомендуется
организовать от 3 до 5 локальных серверов NTP, объединенных "соседскими"
связями и каждый из которых синхронизуется не менее чем с 3 внешними серверами
желательно с использованием различных маршрутов доступа. Крайне нежелательно
использовать несимметричные маршруты (туда по модему, обратно по спутниковому
каналу).
RFC 5905 June 2010 (Network Time Protocol Version 4: Protocol and Algorithms Specification)
RFC 5906 June 2010 (Network Time Protocol Version 4: Autokey Specification)
RFC 1708 D. Gowin, "NTP PICS PROFORMA For the Network Time Protocol Version 3", 10/26/1994. (бланк, заполняемый владельцем сервиса NTP)
RFC 1589 D. Mills, "A Kernel Model for Precision Timekeeping", 03/03/1994. (как реализовать управление временем (в частности, в SunOS), чтобы можно было стыковаться с NTP; наверное, для разработчиков ядра Unix это интересно ;)
RFC 1305 D. Mills, "Network Time Protocol (v3)", 04/09/1992. (отменил RFC-1119, RFC-1059, RFC-958)
RFC 1165 J. Crowcroft, J. Onions, "Network Time Protocol (NTP) over the OSI Remote Operations Service", 06/25/1990. (работа NTP в условиях сервиса, ориентированного на соединение - не наш случай)
RFC 1129 D. Mills, "Internet time synchronization: The Network Time Protocol", 10/01/1989. (более свежая версия текста)
RFC 1128 D. Mills, "Measured performance of the Network Time Protocol in the Internet system", 10/01/1989. (итог исследования: 1% хостов поддерживает NTP, 30% из них дает точность 30мс, 99% дает точность 10 секунд, NTP дает точность в 1000 раз выше, чем TIME или ICMP Timestamp)
RFC 1119 D. Mills, "Network Time Protocol version 2 specification and implementation", 09/01/1989. (Obsoletes RFC1059) (STD 12) (Obsoleted by RFC1305)
RFC 1059 D. Mills, "Network Time Protocol version 1 specification and implementation", 07/01/1988. (Obsoletes RFC0958) (Obsoleted by RFC1119)
RFC 958 D. Mills, "Network Time Protocol NTP", 09/01/1985. (Obsoleted by RFC1059)