Что такое ntp клиент

Что такое ntp клиент

Network Time Protocol — сетевой протокол для синхронизации внутренних часов компьютера с использованием сетей с переменной латентностью, основанных на коммутации пакетов.

Хотя традиционно NTP использует для своей работы протокол UDP, он также способен работать и поверх TCP. Система NTP чрезвычайно устойчива к изменениям латентности среды передачи.

Время, представляется в системе NTP 64-битным числом, состоящим из 32-битного счетчика секунд и 32-битного счетчика долей секунды, позволяя передавать время в диапазоне 2 32 секунд, с теоретической точностью 2 -32 секунды. Поскольку шкала времени в NTP повторяется каждые 2 32 секунды (136 лет), получатель должен хотя бы примерно знать текущее время (с точностью 68 лет). Также следует учитывать, что время отсчитывается с полуночи 1 января 1900 года, а не с 1970, поэтому из времени NTP нужно вычитать почти 70 лет (с учетом високосных лет), чтобы корректно совместить время с Windows или Unix-системами.

Как это работает

NTP-серверы работают в иерархической сети, каждый уровень иерархии называется ярусом (stratum). Ярус 0 представлен эталонными часами. За эталон берется сигнал GPS (Global Positioning System) или службы ACTS (Automated Computer Time Service). На нулевом ярусе NTP-серверы не работают.

NTP-серверы яруса 1 получают данные о времени от эталонных часов. NTP-серверы яруса 2 синхронизируются с серверами яруса 1. Всего может быть до 15 ярусов.

NTP-серверы и NTP-клиенты получают данные о времени от серверов яруса 1, хотя на практике NTP-клиентам лучше не делать этого, поскольку тысячи индивидуальных клиентских запросов окажутся слишком большой нагрузкой для серверов яруса 1. Лучше настроить локальный NTP-сервер, который ваши клиенты будут использовать для получения информации о времени.

Иерархическая структура протокола NTP является отказоустойчивой и избыточной. Рассмотрим пример его работы. Два NTP-сервера яруса 2 синхронизируются с шестью различными серверами яруса 1, каждый — по независимому каналу. Внутренние узлы синхронизируются с внутренними NTP-серверами. Два NTP-сервера яруса 2 координируют время друг с другом. В случае отказа линии связи с сервером яруса 1 или с одним из серверов уровня 2 избыточный сервер уровня 2 берет на себя процесс синхронизации.

Аналогично узлы и устройства яруса 3 могут использовать любой из серверов яруса 2. Что еще более важно, так это то, что наличие избыточной сети серверов NTP гарантирует постоянную доступность серверов времени. Синхронизируясь с несколькими серверами точного времени, NTP использует данные всех источников, чтобы высчитать наиболее точное временя.

Стоит отметить, что протокол NTP не устанавливает время в чистом виде. Он корректирует локальные часы с использованием временного смещения, разницы между временем на NTP-сервере и локальных часах. Серверы и клиенты NTP настраивают свои часы, синхронизируясь с текущим временем постепенно либо единовременно.

Со времени начала использования компьютеров (сперва в специализированных системах, в потом и в повседневной жизни) появилась задача поддерживать точность хода системных часов, т.е. иметь точно синхронизированное время с остальными компьютерами и системами. Особенно точность времени критична в распределенных системах, которые критичны к порядку вычисления задач, обработки данных и т.п.

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

Также немаловажно, чтобы сама сеть компьютеров имела те только синхронизированное время, но и это время было точным с другими системами по всей планете. Т.е. время по всей территории планеты было одинаковым (или достаточно близким).

Протоколы DAYTIME и TIME

Первыми протоколами точного времени, используемым на компьютерах, были DAYTIME (RFC 867) и TIME (RFC 868). Первый предназначался для сообщения даты и времени в понятном человеку виде, второй — понятном компьютеру виде. Формат ответа DAYTIME строго не регламентируется и не предназначен для машинной обработки — предполагается лишь, что человеку, прочитавшему полученную строку, станет ясно текущее время.

Протокол TIME, напротив, предназначен для обмена времени между машинами. На подключившийся к TIME-серверу компьютер приходит UDP-пакет, содержащий единственное 32-битное беззнаковое число, соответствующе числу прошедших с 1 января 1900 г. секунд по UTC. Поскольку такое число переполняется через 136 лет, этот протокол способен функционировать только до 2036 г.

Читайте также:  Байты в мегабиты в секунду

Протокол NTP

Понятно, что ни DAYTIME, ни TIME не могут обеспечить необходимую точность синхронизации времени. В связи с этим, в 1985 г. Дэвидом Л. Миллсом (David L. Mills) из университета Дэлавера был разработан сетевой протокол синхронизации времени NTP, точнее его начальная, позднее названная нулевой (NTPv0) версия, описанная в RFC 958. Протокол NTP использует алгоритм Марзулло (предложен Кейтом Марзулло (Keith Marzullo) из Университета Калифорнии, Сан-Диего), включая такую особенность, как учёт времени передачи. В версии 4 способен достигать точности 10 мс при работе через Интернет, и до 0,2 мс внутри локальных сетей.

Описывать сами протоколы, а тем более их работу и взаимодействие мы не будем — этому посвящено много статей в Интернете — начиная с официальных документов RFC и заканчивая обзорами. Отметим лишь, что NTP для синхронизации использует протокол UDP и 123 порт, DAYTIME — 13 порт TCP/UDP, TIME — 37 порт TCP/UDP.

Протокол NTP совершенствовался не один раз: NTPv1 (1988 г, RFC 1059), NTPv2 (1989 г., RFC1119), NTPv3 (1992 г., RFC1305), NTPv4 (1996 г., RFC2030).

Для определения точности или значимости того или иного NTP-сервера используют параметр Stratum (стратум) — целое число от 1 до 15. Стратум 1 соответствует серверам, имеющим непосредственно связь с эталонном времени, стратум 2 — сервер, получающий сведения о времени от серверов первого стратума и т.д. При построении цепочки связей значение стратума увеличивается на 1.

Принцип определения точного времени

Работа алгоритма NTP достаточно проста и может быть проиллюстрированна задачей Рэймонда М. Смаллиана (1978 г.):

У одного человека не было наручных часов, но зато дома висели точные настенные часы, которые он иногда забывал заводить. Однажды, забыв очередной раз завести часы, он отправился в гости к своему другу, провел у того вечер, а вернувшись домой, сумел правильно поставить часы. Каким образом ему удалось это сделать, если время в пути заранее известно не было?

Ответ таков: выходя из дома, человек заводит часы и запоминает, в каком положении находятся стрелки. Придя к другу и уходя из гостей, он отмечает время своего прихода и ухода. Это позволяет ему узнать, сколько он находился в гостях. Вернувшись домой и взглянув на часы, человек определяет продолжительность своего отсутствия. Вычитая из этого времени то время, которое он провел в гостях, человек узнает время, затраченное на дорогу туда и обратно. Прибавив ко времени выхода из гостей половину времени, затраченного на дорогу, он получает возможность узнать время прихода домой и перевести соответствующим образом стрелки своих часов.

Таким образом, по четырём данным: время отправки запроса (по часам клиента); время получения запроса сервером (по часам сервера); время отправки ответа сервером (по часам сервера); время получения ответа (по часам клиента) можно найти время пакета в пути туда и обратно, а затем — откорректировать локальное время.

При этих расчетах мы пользуемся тремя важными предположениями:

  1. Пакет проходит путь от клиента до сервера и обратно за равное время.
  2. Скорость хода часов клиента и сервера равна.
  3. На вычисление нового локального времени не уходит дополнительное время.

На самом деле все эти предположения, строго говоря, не верны, и получить точное значение серверного времени с помощью одного NTP-запроса невозможно. Поэтому для синхронизации часов обычно используется несколько NTP-серверов, на которые постоянно шлются запросы. Накапливая статистику за длительное время, математическими методами можно определить точность показаний каждого из серверов, скорость хода часов на каждом из них, и т.п. величины, используя которые, можно добиться математически доказуемой точности синхронизации. Конкретные используемые методы описаны в RFC и чрезвычайно сложны. Кстати, из-за третьего предположения, использование синхронизации по NTP по несимметричным каналам связи (спутниковые и т.п.) не правомерно.

Читайте также:  Killing floor 2 самый сильный класс

Кроме собственно обмена показаниями времени, в NTP начиная с версии 2 включён механизм обмена метаинформацией в виде "управляющих сообщений" NTP. Формат самих управляющих сообщений не задан в RFC, но существующий стандарт де-факто позволяет с их помощью запрашивать у NTP-сервера такие параметры, как адреса всех его клиентов и вышестоящих серверов, задержку до каждого из них и т.п.

NTP позволяет добиться высокоточной синхронизации времени в сети синхронизирующихся серверов, каждый из которых получает показания из нескольких источников, обрабатывает их, и передаёт дальше. Он применим только внутри небольших локальных сетей и сетей с малыми задержками пакетов; в Интернете он практически неприменим из-за большой (и, что важно, случайной) задержки пакетов, которая на порядки превосходит разницы в показаниях часов клиента и сервера. Такая NTP-сеть характеризуется масштабируемостью и устойчивостью к сбоям — даже в случае отказа часов одного из серверов остальные немедленно это заметят и перестанут использовать его показания.

Протокол SNTP

Помимо NTP, существует упрощенная версия этого протокола — SNTP (Simple Network Time Protocol). Он реализован для синхронизации времени конечным клиентом, поскольку все преимущества протокола NTP проявляются именно в сети серверов, а для получения показаний конечным пользователем NTP излишне сложен. Поэтому для синхронизации времени конечными компьютерами и серверами был предложен протокол SNTP (SNTPv3: 1992 г., RFC1361 и 1995 г., RFC1769; SNTPv4 включён как подпротокол в NTPv4).

На самом деле SNTP — это не новый протокол, а способ использования NTP-пакетов и NTP-серверов в приложениях, где не требуется высокоточное время, либо оно недостижимо. В этом случае клиент использует только часть информации UDP-пакета NTP-сервера. SNTP-клиент может работать с любыми версиями NTP-серверов, и кроме них — с особыми SNTP-серверами, которые в откликах заполняют только необходимые данные UDP-пакета.

Таким образом, "облегченный" SNTP образует не сеть синхронизирующихся серверов, а пары "клиент-сервер". Любой NTP-сервер является одновременно SNTP-сервером. Клиент, который не передаёт полученное время дальше, может работать как NTP- или SNTP-клиент, в зависимости от условий. Для SNTP, как и для NTP, зарезервирован 123-й UDP-порт.

Всем привет, сегодня напишем свой простенький NTP клиент. В основном, разговор зайдет о структуре пакета и способе обработки ответа с NTP сервера. Код будет написан на питоне, потому что, как мне кажется, лучшего языка для подобных вещей просто не найти. Знатоки обратят внимание на схожесть кода с кодом ntplib — я «вдохновлялся» именно им.

Итак, что вообще такое NTP? NTP – протокол взаимодействия с серверами точного времени. Этот протокол используется во многих современных машинах. Например, служба w32tm в windows.

Всего существует 5 версий NTP протокола. Первая, 0-я версия (1985 г, RFC958)), в данный момент считается устаревшей. Сейчас используются более новые, 1-я (1988, RFC1059), 2-я(1989, RFC1119), 3-я(1992, RFC1305) и 4-я(1996, RFC2030). 1-4 версии являются совместимыми друг с другом, они отличаются лишь алгоритмами работы серверов.

Формат пакета

Leap indicator (индикатор коррекции) — число, показывающее предупреждение о секунде координации. Значение:

  • 0 – нет коррекции
  • 1 – последняя минута дня содержит 61 секунду
  • 2 – последняя минута дня содержит 59 секунд
  • 3 – неисправность сервера (время не синхронизировано)

Version number (номер версии) – номер версии протокола NTP (1-4).

Mode (режим) — режим работы отправителя пакета. Значение от 0 до 7, наиболее частые:

  • 3 – клиент
  • 4 – сервер
  • 5 – широковещательный режим

Stratum (уровень наслоения) – количество промежуточных слоев между сервером и эталонными часами (1 – сервер берет данные непосредственно с эталонных часов, 2 – сервер берет данные с сервера с уровнем 1 и т.д.).
Poll — целое число со знаком, представляющее максимальный интервал между последовательными сообщениями. NTP-клиент указывает здесь интервал, с которым он предполагает опрашивать сервер, а NTP-сервер – интервал, с которым он предполагает, чтобы его опрашивали. Значение равно двоичному логарифму секунд.
Precision (точность) — целое число со знаком, представляющее точность системных часов. Значение равно двоичному логарифму секунд.
Root delay (задержка сервера) – время, за которое показания часов доходят до NTP-сервера, как число секунд с фиксированной точкой.
Root dispersion (разброс показаний сервера) — разброс показаний часов NTP-сервера как число секунд с фиксированной точкой.
Ref id (идентификатор источника) – id часов. Если сервер имеет стратум 1, то ref id – название атомных часов (4 ASCII символа). Если сервер использует другой сервер, то в ref id записан адрес этого сервера.
Последние 4 поля представляют из себя время – 32 бита – целая часть, 32 бита – дробная часть.
Reference — последние показания часов на сервере.
Originate – время, когда пакет был отправлен (заполняется сервером – об этом ниже).
Receive – время получения пакета сервером.
Transmit – время отправки пакета с сервера клиенту (заполняется клиентом, об этом тоже ниже).

Читайте также:  Файл windows system32 winload efi

Два последних поля рассматривать не будем.

Напишем наш пакет:

Чтобы слать (и принимать) пакет на сервер, мы должны уметь превращать его в массив байт.
Для этой (и обратной) операции напишем две функции — pack() и unpack():

Отправка пакета на сервер

На сервер необходимо отправить пакет с заполненными полями Version, Mode и Transmit. В Transmit необходимо указать текущее время на локальной машине (количество секунд с 1 января 1900 г), версия — любая из 1-4, режим — 3 (режим клиента).

Сервер, приняв запрос, заполняет в NTP-пакете все поля, скопировав в поле Originate значение из Transmit, пришедшее в запросе. Для меня является загадкой, почему клиент не может сразу заполнить значение своего времени в поле Originate. В итоге, когда пакет приходит обратно, у клиента есть 4 значения времени – время отправки запроса (Originate), время получения запроса сервером (Receive), время отправки ответа сервером (Transmit) и время получения ответа клиентом – Arrive (нет в пакете). С помощью этих значений мы можем установить корректное время.

Обработка данных с сервера

Обработка данных с сервера аналогична действиям английского джентльмена из старой задачи Рэймонда М. Смаллиана (1978): «У одного человека не было наручных часов, но зато дома висели точные настенные часы, которые он иногда забывал заводить. Однажды, забыв очередной раз завести часы, он отправился в гости к своему другу, провел у того вечер, а вернувшись домой, сумел правильно поставить часы. Каким образом ему удалось это сделать, если время в пути заранее известно не было?» Ответ таков: «Выходя из дома, человек заводит часы и запоминает, в каком положении находятся стрелки. Придя к другу и уходя из гостей, он отмечает время своего прихода и ухода. Это позволяет ему узнать, сколько он находился в гостях. Вернувшись домой и взглянув на часы, человек определяет продолжительность своего отсутствия. Вычитая из этого времени то время, которое он провел в гостях, человек узнает время, затраченное на дорогу туда и обратно. Прибавив ко времени выхода из гостей половину времени, затраченного на дорогу, он получает возможность узнать время прихода домой и перевести соответствующим образом стрелки своих часов.»

Находим время работы сервера над запросом:

  1. Находим время пути пакета от клиента к серверу: ((Arrive – Originate) — (Transmit – Receive)) / 2
  2. Находим разницу между временем клиента и сервера:
    Receive — Originate — ((Arrive – Originate) — (Transmit – Receive)) / 2 =
    2 * Receive — 2 * Originate – Arrive + Originate + Transmit – Receive =
    Receive – Originate – Arrive + Transmit

Добавляем полученное значение к локальному времени и радуемся жизни.

Ссылка на основную публикацию
Adblock detector