Сервер точного времени на базе ntpd FreeBSD


В Сети имеется большое количество информации о синхронизации времени на компьютерах с Linux/Unix, однако, основная масса статей дает немного устаревшие рекомендации и очень кратко рассматривает вопросы выявления и устранения возможных проблем. В данной статье я постарался устранить вышеназванные недостатки.
Постановка задачи

В процессе создания любой корпоративной сети возникает вопрос организации синхронизации времени. Синхронизация времени базируется на протоколах NTP (Network Time Protocol) и SNTP (Simple Network Time Protocol). В большинстве случаев на одном из серверов корпоративной сети разворачивается главный сервер точного времени (далее - главный NTP-сервер), который синхронизируется с публичными серверами точного времени Интернета (далее - публичными NTP-серверами), и является источником точного времени для всех остальных компьютеров корпоративной сети. По умолчанию в состав операционной системы FreeBSD входит NTP-сервер ntpd(8). Данная статья посвящена его использованию в роли главного NTP-сервера корпоративной сети, организации синхронизации времени на компьютерах с FreeBSD (с учетом небольших расхождений в именах и форматах файлов конфигурации приведенная информация подойдет практически для любой операционной системы семейства Linux/Unix), а также устранению проблем, связанных с синхронизацией времени.
Исходные данные

Для решения рассматриваемой задачи не требуется установка какого-либо программного обеспечения, однако, во избежание недоразумений следует отметить, что все описанные действия выполнялись на серверах с FreeBSD 7.x RELEASE. Если Вы используете более раннюю версию операционной системы, может возникнуть необходимость обновления ее исходных текстов и пересборки мира.
Выбор публичных NTP-серверов

Для справки следует отметить, что одним из важнейших параметров NTP-сервера является stratum (в русской интерпретации - страта) - величина, которая отражает уровень системных часов и может принимать значения: 0 - не специфицировано / недоступно, 1 - первичный (primary) эталон (например, атомные часы), 2-15 - вторичный (secondary) эталон, 16-255 - зарезервировано на будущее. Серверы, которые синхронизируются с серверами, имеющими stratum 1, получают stratum 2, серверы, которые синхронизируются с серверами, имеющими stratum 2, получают stratum 3 и т.д. В процессе выбора публичных NTP-серверов, с которыми будет синхронизироваться главный NTP-сервер, следует руководствоваться требованиями документа Rules of Engagement, которые не рекомендуют использовать публичные NTP-серверы, имеющие stratum 1, без веских оснований и призывают использовать не менее трех-пяти (из соображений надежности) публичных NTP-серверов, имеющих stratum 2. Список публичных NTP-серверов, имеющих stratum 2, содержится в документе Stratum Two Time Servers, из которого следует выбрать необходимое количество OpenAccess (публичных) NTP-серверов, расположенных в Вашей стране. Для проверки доступности и значения stratum выбранных серверов необходимо выполнить соответствующее число команд ntpdate -q <IP-адрес/FQDN NTP-сервера>. Эти команды служат для запроса времени и значений параметров stratum, offset, delay (последние два рассмотрены ниже) с удаленных NTP-серверов и не меняют состояние системных часов. Выводимые сообщения выглядят примерно так:server 93.185.187.89, stratum 2, offset 0.001863, delay 0.05652
2 Oct 11:00:31 ntpdate[47704]: adjust time server 93.185.187.89 offset 0.001863 sec


Если для всех NTP-серверов выводятся нулевые значения параметров и сообщения: "нет сервера, подходящего для синхронизации":server 93.185.187.89, stratum 0, offset 0.000000, delay 0.00000
2 Oct 11:05:47 ntpdate[47706]: no server suitable for synchronization found


Вам следует следует разрешить в брандмауэре входящий UDP-трафик со 123 порта серверов, расположенных в Интернет, и исходящий UDP-трафик на 123 порт серверов, расположенных в Интернет. Например, в случае ipfw(8) нужно добавить такие правила:

/sbin/ipfw -q add pass udp from any 123 to <внешний IP-адрес> in via <имя внешнего сетевого интерфейса>
/sbin/ipfw -q add pass udp from <внешний IP-адрес> to any 123 out via <имя внешнего сетевого интерфейса>


В момент написания статьи в Stratum Two Time Servers имелась информация о восьми публичных NTP-серверах, расположенных в России, при этом "мертвым" оказался только ntp.xland.ru, а остальные семь успешно используются в роли источников точного времени.
Настройка главного NTP-сервера

По умолчанию конфигурация ntpd хранится в файле /etc/ntp.conf. В моем случае этот файл имеет следующее содержимое:

server ntp1.kangran.su
server ntp21.imvp.ru
server ticktock.net.ru
server ntp.psn.ru
server ntp.ru
server ntp2.kangran.su
server ntp.letinet.ru
restrict default ignore
restrict ntp1.kangran.su nomodify noquery notrap
restrict ntp21.imvp.ru nomodify noquery notrap
restrict ticktock.net.ru nomodify noquery notrap
restrict ntp.psn.ru nomodify noquery notrap
restrict ntp.ru nomodify noquery notrap
restrict ntp2.kangran.su nomodify noquery notrap
restrict ntp.letinet.ru nomodify noquery notrap
restrict 127.0.0.1 nomodify notrap
restrict 192.168.0.0 mask 255.255.255.0 nomodify notrap
restrict 10.0.0.0 mask 255.255.255.0 nomodify notrap
logfile /var/log/ntp.log


В данном файле заданы следующие значения параметров: server ... - список публичных NTP-серверов, с которыми синхронизируется наш сервер, restrict... - ограничения доступа к серверу (строка 8 - ограничение по умолчанию - доступ запрещен, строки 9-15 - ограничения доступа со стороны публичных NTP-серверов - запрещено изменять состояние сервера, запрашивать время и отправлять сообщения об исключениях, строки 16-18 - ограничения доступа со стороны клиентов - запрещено изменять состояние сервера и отправлять сообщения об исключениях), logfile - имя лог-файла. Описание всех опций, которые можно задать в файле конфигурации ntpd, содержится в ntp.conf(5). Для того, чтобы ntpd запускался при запуске операционной системы и делал начальную корректировку времени (это не опечатка, теперь ntpd умеет делать грубую начальную корректировку времени без помощи ntpdate) необходимо добавить в файл /etc/rc.conf строки:

ntpd_enable="YES"
ntpd_sync_on_start="YES"

По умолчанию лог ntpd имеет имя ntp.log и находится в папке /var/log. Для того, чтобы newsyslog(8) выполнял его ротацию, необходимо добавить в файл /etc/newsyslog.conf строку:1 /var/log/ntp.log 644 3 100 * J

Данная строка обеспечивает усечение лога ntp при достижении размера 100 килобайт и сохранение трех предыдущих копий лога, сжатых архиватором bzip2(1) (Вы можете изменить эти параметры на свое усмотрение). На этом настройка внутреннего NTP-сервера завершается. Можно запустить сервер командой /etc/rc.d/ntpd start, а затем запросить его состояние командой /etc/rc.d/ntpd status. Если она выдаст сообщение ntpd is running as pid..., все нормально, если же - ntpd is not running, Вам следует найти и устранить ошибки в файлах конфигурации. После этого нужно подождать не менее получаса и выполнить команду ntpdate -q localhost. Если Вы внимательно следовали инструкциям, она выдаст сообщение о том, что NTP-сервер имеет stratum 3 и может использоваться для синхронизации времени:server 127.0.0.1, stratum 3, offset -0.000004, delay 0.02565
2 Oct 12:00:23 ntpdate[49320]: adjust time server 127.0.0.1 offset -0.000004 sec


Другим признаком корректной работы NTP-сервера можно считать появление в логе ntpd примерно таких сообщений:2 Oct 11:44:39 ntpd[37456]: synchronized to 62.117.76.139, stratum 2
2 Oct 11:44:39 ntpd[37456]: kernel time sync status change 6001
2 Oct 11:54:14 ntpd[37456]: synchronized to 193.124.11.11, stratum 2
2 Oct 12:00:43 ntpd[37456]: kernel time sync status change 2001
2 Oct 12:03:56 ntpd[37456]: synchronized to 62.117.76.139, stratum 2
2 Oct 12:05:00 ntpd[37456]: synchronized to 93.185.187.89, stratum 2
2 Oct 12:07:07 ntpd[37456]: synchronized to 80.93.53.29, stratum 2
2 Oct 12:07:07 ntpd[37456]: synchronized to 62.117.76.139, stratum 2
2 Oct 12:13:33 ntpd[37456]: synchronized to 80.93.53.29, stratum 2
2 Oct 12:15:54 ntpd[37456]: synchronized to 62.117.76.139, stratum 2

Диагностика главного NTP-сервера

Для диагностики состояния главного NTP-сервера удобнее всего использовать утилиту ntpq(8), предназначенную для запроса различной информации у NTP-сервера. ntpq может работать как в интерактивном, так и в пакетном режиме, рассмотрение всех ее возможностей выходит далеко за рамки этой статьи. В контексте решаемой задачи более чем достаточно команды запроса состояния пиров - ntpq -p. (другие формы этой команды - ntpq -c peers, peers в интерактивном режиме). Информацию, выводимую командой ntpq -p, лучше пояснить на примере: remote refid st t when poll reach delay offset jitter
==============================================================================
+93.185.187.89 62.149.0.30 2 u 645 1024 337 44.937 -3.099 3.926
*ntp21.imvp.ru 62.117.76.140 2 u 507 1024 377 31.954 -3.907 4.133
-rebus.pae.spb.r 192.36.144.22 2 u 38m 1024 374 41.957 6.018 0.454
+alpha.prao.psn. 77.236.33.77 2 u 218 1024 377 36.913 -4.135 27.032
+ntp.ru 62.117.76.140 2 u 214 1024 377 36.966 -3.930 4.508
-94.26.135.117 193.190.230.66 2 u 704 1024 377 39.915 0.475 3.805
-95.140.94.2 193.79.237.14 2 u 618 1024 375 42.965 5.219 2.563


Строки данной таблицы соответствует публичным NTP-серверам, которые определены в файле /etc/ntp.conf, cтолбцы содержат следующие значения: маркер: '*' - сервер, с которым в настоящий момент выполняется синхронизация, '#' - сервер отобран для синхронизации, но дистанция до него превышает максимально возможную, 'ο' - сервер отобран для синхронизации и использует сигнал PPS, '+' - сервер добавлен в список серверов, отобранных для синхронизации, 'x' - сервер использует некорректный алгоритм, '.' - сервер выбран из конца списка серверов, отобранных для синхронизации, '-' - сервер отвергнут группирующим алгоритмом, пробел - сервер имеет слишком высокий stratum и/или не может быть проверен; remote - FQDN или IP-адрес сервера; refid - IP-адрес сервера с которым в настоящий момент выполняется синхронизация сервера из столбца remote; st - stratum сервера; t - режим работы сервера: 'u' - unicast, 'm' - multicast, 'b' - broadcast, '-' - manycast; when - время, прошедшее с момента последнего ответа сервера в секундах или '-', если сервер еще ни разу не ответил (скорее всего, "умер", и сведения о нем пора удалить из файла конфигурации); poll - интервал опроса сервера в секундах (после запуска имеет небольшое значение, чтобы синхронизация происходила быстрее, с течением времени значение увеличивается); reach - состояние восьми последних попыток запроса времени у сервера в восьмеричном представлении (в случае успешной попытки устанавливается соответствующий бит); delay - задержка ответа сервера в секундах; offset - самое важное значение - различие локального времени и времени на сервере (с течением времени значение уменьшается, т.к. время становится более точным); jitter - дисперсия, дрожание фазы (более низкие значения обеспечивают более точную синхронизацию).
Синхронизация времени на остальных компьютерах с FreeBSD

Во избежание путаницы отмечу, что под "остальными компьютерами" в данном случае понимаются все компьютеры корпоративной сети с FreeBSD за исключением главного NTP-сервера. Средства FreeBSD позволяют реализовать два варианта синхронизации времени. Первый рассмотрен выше, и после замены публичных NTP-серверов на главный NTP-сервер подойдет для любого компьютера корпоративной сети с FreeBSD. Изменения касаются единственного файла конфигурации /etc/ntp.conf, который необходимо привести к следующему виду:

server <IP-адрес/FQDN внутреннего NTP-сервера>
restrict default ignore
restrict <IP-адрес/FQDN внутреннего NTP-сервера> nomodify noquery notrap
restrict 127.0.0.1 nomodify notrap


Второй вариант заключается в выполнении команды ntpdate -b <IP-адрес/FQDN внутреннего NTP-сервера> при запуске операционной системы и последующем выполнении команды ntpdate -s <IP-адрес/FQDN внутреннего NTP-сервера> каждый час. Ключ -b заставляет ntpdate принудительно использовать системный вызов settimeofday(2), предназначенный для грубой корректировки системного времени (по умолчанию, если локальное время время отличается от времени, полученного с NTP-сервера, менее чем на 0,5 секунд, ntpdate использует системный вызов adjtime(2), предназначенный для плавной корректировки системного времени), ключ -s включает перенаправление вывода в syslog(3). Таким образом эмулируется поведение NTP-сервера. Грубая корректировка времени при запуске операционной системы является очень важной операцией. Она позволяет избежать значительный скачок системного времени (и возможные проблемы в работе систем биллинга, статистики, СУБД и т.п.), который может произойти в том случае, если первая операция синхронизации времени будет выполнена позже, чем запустится операционная система, и локальное время будет отличаться от времени на NTP-сервере более чем на 0,5 секунд. Для того, чтобы команда грубой корректировки времени автоматически выполнялась при запуске операционной системы, следует добавить в файл /etc/rc.conf строки:

ntpdate_enable="YES"
ntpdate_hosts="<IP-адрес/FQDN внутреннего NTP-сервера>"

Для того, чтобы команда точной корректировки времени каждый час выполнялась с помощью cron(8), необходимо войти в систему под root'том, выполнить команду crontab -e, позволяющую внести изменения в crontab текущего пользователя (т.е. root'a), и добавить строку:1 0 * * * * /usr/sbin/ntpdate -s <IP-адрес/FQDN внутреннего NTP-сервера>

На этом настройка второго варианта завершается. Я рассказал о нем лишь потому, что он существует и может использоваться, однако, у меня ни разу не возникало оснований для отказа от первого варианта.

Заключение

Я надеюсь, что не забыл ничего важного, и приведенной информации будет достаточно для корректной настройки и последующей отладки NTP-серверов на компьютерах Вашей корпоративной сети с FreeBSD и другими операционными системами семейства Linux/Unix.

http://www.sergeysl.ru/freebsd-ntpd/

Обновлено: 12.03.2015