Как синхронизация времени стала безопасной

9kpzpokuvitilnpswiw7gl-djhw.jpeg

Как сделать так, чтобы время per se не врало, если у вас есть миллион больших и малых устройств, взаимодействующих по TCP/IP? Ведь на каждом из них есть часы, а время должно быть верным на всех. Эту проблему без ntp невозможно обойти.

Представим себе на одну минуту, что в одном сегменте промышленной ИТ инфраструктуры возникли трудности с синхронизацией сервисов по времени. Немедленно начинает сбоить кластерный стек Enterprise ПО, распадаются домены, мастера и Standby узлы безуспешно стремятся восстановить status quo.

Возможна также ситуация, когда злоумышленник намеренно старается сбить время через MiTM, или DDOS атаку. В такой ситуации может произойти все что угодно:

  • истечет срок действия паролей учетных записей пользователей;
  • истечет срок действия X.509 сертификатов;
  • двухфакторная аутентификация TOTP перестанет работать;
  • бэкапы «устареют» и система удалит их;
  • сломается DNSSec.


Понятно, что каждый первый департамент ИТ заинтересован в надежной работе служб синхронизации времени, и хорошо бы они были надежны и безопасны в промышленной эксплуатации.

Сломать NTP за 25 минут


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

Основная претензия к классическому NTP в отсутствии надежных механизмов защиты от атак злоумышленников. Предпринимались разнообразные попытки решить эту проблему. Для этого сначала внедрили механизм заранее установленных ключей (PSK) для обмена симметричными ключами.

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

Тогда придумали AutoKey, но сразу же в нем обнаружили ряд серьезных уязвимостей в самом дизайне алгоритма и от него пришлось отказаться. Все дело в том, что начальное число (seed) содержит всего лишь 32-бита, оно слишком мало и не содержит достаточно вычислительной сложности для лобовой атаки.

  • Key ID — симметричный 32-битный ключ;
  • MAC (message authentication code) — контрольная сумма NTP пакета;


Autokey рассчитывается следующим образом.

Autokey=H(Sender-IP||Receiver-IP||KeyID||Cookie)


Где H () — криптографическая хэш функция.

Для расчета контрольной суммы пакеты используется та же функция.

MAC=H(Autokey||NTP packet)


Так получается, что вся целостность проверок пакетов держится на аутентичности кукис. Завладев ими, можно восстановить autokey и затем подделать MAC. Однако сервер NTP при их генерации использует начальное число (seed). Именно тут кроется подвох.

Cookie=MSB_32(H(Client IP||Server IP||0||Server Seed))


Функция MSB_32 отрезает от результата вычисления md5 хэша 32 старших бита. Клиентский куки не меняется до тех пор, пока параметры сервера неизменны. Дальше злоумышленнику остается лишь восстановить начальное число и получить возможность самостоятельно генерить куки.

Для начала следует подключиться к серверу NTP в качестве клиента и получить куки. После этого методом перебора злоумышленник восстанавливает начальное число следуя простому алгоритму.

Алгоритм атаки на вычисление начального числа методом перебора.

   for i=0:2^32 − 1 do
        Ci=H(Server-IP||Client-IP||0||i)
        if Ci=Cookie then
            return i
        end if 
    end for


IP адреса известны, так что остается лишь создать 232 хэша до тех пор пока созданный куки не совпадет с тем, что получен от NTP сервера. На обычной домашней станции с Intel Core i5 на это уйдет 25 мин.

NTS — новый Autokey


Мириться с такими дырами в безопасности Autokey было невозможно и в 2012 г. появилась новая версия протокола. В целях скомпрометированного названия решили провести ребрендинг, так Autokey v. 2 окрестили Network Time Security.

Протокол NTS является расширением безопасности NTP и в настоящее время поддерживает лишь одноадресный режим (unicast). Он дает надежную криптографическую защиту от манипуляций пакетами, предотвращает отслеживание, хорошо масштабируется, устойчив к потере сетевых пакетов и приводит к наименьшим потерям точности, возникающим в процессе защиты соединения.

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

okzb2rsw6evj7ntmhcqxz992nh0.png

NTS состоит из двух протоколов нижнего уровня: Network Time Security Key Exchange (NTS-KE), инициализация безопасного соединения поверх TLS, и NTPv4 — последней инкарнации протокола NTP. Чуть подробнее об этом ниже.

Первый этап — NTS KE


На данном этапе NTP клиент инициирует TLS 1.2/1.3 сеанс по отдельному TCP соединению с сервером NTS KE. Во время этой сессии происходит следующее.

  • Стороны определяют параметры AEAD алгоритма для второго этапа.
  • Стороны определяют второй протокол нижнего уровня, но на данный момент лишь NTPv4поддерживается.
  • Стороны определяют IP адрес и порт NTP сервера.
  • NTS KE сервер выдает куки под NTPv4.
  • Стороны извлекают из материала куки пару симметричных ключей (C2S и S2C).


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

Второй этап — NTP под защитой NTS


На втором этапе клиент безопасно синхронизирует время с NTP сервером. Для этой цели он передает четыре специальных расширения (extension field) в структуре NTPv4 пакета.

  • Unique Identifier Extension содержит случайный nonce для предотвращения атак путем повтора.
  • NTS Cookie Extension содержит один из имеющихся в наличие у клиента NTP куки. Поскольку только клиент располагает симметричными AAED ключами C2S и S2C, сервер NTP должен извлечь их из материала куки.
  • NTS Cookie Placeholder Extension способ для клиента запросить дополнительные куки с сервера. Это расширение необходимо, чтобы ответ сервера NTP не был намного длиннее, чем запрос. Это позволяет предотвратить атаки усиления.
  • NTS Authenticator and Encrypted Extension Fields Extension содержит шифр алгоритма AAED с C2S ключем, заголовком NTP, временными отметками, и упомянутыми выше EF в качестве сопутствующих данных. Без этого расширения возможно подделать временные отметки.


ibv36nfmbgnznq8hhsfupcpu6v4.png

Получив запрос от клиента, сервер проверяет подлинность NTP пакета. Для этого он должен расшифровать куки, извлечь алгоритм AAED и ключи. После успешной проверки NTP пакета на валидность сервер отвечает клиенту в следующем формате.

  • Unique Identifier Extension зеркальная копия клиентского запроса, мера против атак путем повтора.
  • NTS Cookie Extension больше куки для продолжения сеанса.
  • NTS Authenticator and Encrypted Extension Fields Extension содержит шифр AEAD с S2C ключем.


Второе рукопожатие можно повторить много раз, минуя первый этап, так как каждый запрос и ответ дает клиенту дополнительные куки. Это дает то преимущество, что относительно ресурсоемкие TLS операции вычисления и передачи PKI данных делятся на число повторных запросов. Это особенно удобно для специализированных FPGA хронометров, когда весь основной функционал можно упаковать в несколько функций из области симметричной криптографии, передав весь TLS стек на другое устройство.

NTPSec


В чем особенность NTP? Несмотря на то, что автор проекта Dave Mills старался как можно лучше документировать свой код, редкий программист сумеет разобраться в хитросплетениях алгоритмов синхронизации времени 35-детней давности. Часть кода написана до эпохи POSIX, а Unix API тогда сильно отличался от того, что используется в наши дни. Кроме того, нужны знания по статистике, чтобы очистить сигнала от помех на шумных линиях.

NTS была не первой попыткой починить NTP. После того, как злоумышленники научились использовать уязвимости NTP для усиления DDoS атак, стало ясно, что нужны радикальные перемены. И пока готовились и доводились до ума черновики NTS, National Science Foundation США в конце 2014 г. срочно выделил грант на модернизацию NTP.

Рабочую группу возглавил не абы кто, а Эрик Стивен Реймонд — один из основателей и столпов сообщества Open Source и автор книги Собор и Базар. Первым делом Эрик со товарищи попробовали перенести код NTP из платформы BitKeeper на git, но не тут-то было. Лидер проекта Harlan Stenn был против этого решения и переговоры зашли в тупик. Тогда было решено форкнуть код проекта, так возник NTPSec.

Солидный опыт, в том числе работа над GPSD, математический бэкграунд и магический навык чтения древнего кода — Эрик Реймонд был именно тем хакером, который мог вытащить такой проект. В команде нашелся специалист по миграции кода и всего за 10 недель NTP обосновалсяна GitLab-е. Работа закипела.

Команда Эрика Раймонда взялась за дело так же, как Огюст Роден при работе с глыбой камня. Удалив 175 KLOC старого кода, им удалось значительно сократить площадь атаки, закрыв множество дыр безопасности.

Вот неполный список попавших под раздачу:

  • Недокументированные, устаревшие, устаревшие или сломанные refclock.
  • Неиспользуемая библиотека ICS.
  • libopts/autogen.
  • Старый код для Windows.
  • ntpdc.
  • Autokey.
  • C код ntpq переписан на Python.
  • C код sntp/ntpdig переписан на Python.


Помимо очистки кода были и у проекта были и другие задачи. Вот неполный список достижений:

  • Значительно усилена защита кода от переполнения буфера. Чтобы предотвратить переполнение буфера, все небезопасные строковые функции (strcpy / strcat / strtok / sprintf / vsprintf / gets) заменили безопасными версиями, которые реализуют ограничение размера буфера.
  • Добавлена поддержка NTS.
  • Десятикратно повысили точность временного шага с помощью привязки физического оборудования. Это связано с тем, что современные компьютерные часы стали гораздо точнее тех, что были в момент зарождения NTP. Больше всех от этого выиграли GPSDO и выделенные радиостанции времени.
  • Количество языков программирования сократилось до двух. Вместо скриптов Perl, awk и даже S, теперь сплошной Python. За счет этого больше возможностей повторного использования кода.
  • Вместо лапши скриптов autotools проект стал использовать систему сборки программного обеспечения waf.
  • Обновили и реорганизовали документацию проекта. Из противоречивой, и местами архаичной коллекции документов создали вполне сносную документацию. Каждый ключ командной строки и каждая сущность конфигурации теперь имеют единую версию правды. Кроме того, страницы руководства и веб документация теперь создаются из одних и тех же основных файлов.


NTPSec доступен для ряда Linux дистрибутивов. В данный момент последняя стабильная версия 1.1.8, для Gentoo Linux — предпоследняя.

(1:696)$ sudo emerge -av ntpsec
These are the packages that would be merged, in order:
Calculating dependencies... done!
[ebuild   R    ] net-misc/ntpsec-1.1.7-r1::gentoo  USE="samba seccomp -debug -doc -early -gdb -heat -libbsd -nist -ntpviz -rclock_arbiter -rclock_generic -rclock_gpsd -rclock_hpgps -rclock_jjy -rclock_local -rclock_modem -rclock_neoclock -rclock_nmea -rclock_oncore -rclock_pps -rclock_shm -rclock_spectracom -rclock_trimble -rclock_truetime -rclock_zyfer -smear -tests" PYTHON_TARGETS="python3_6" 0 KiB
Total: 1 package (1 reinstall), Size of downloads: 0 KiB
Would you like to merge these packages? [Yes/No]


Chrony


Была еще одна попытка заменить старый NTP более безопасный аналог. Chrony в отличие от NTPSec написан с нуля и предназначен для надежной работы в широком диапазоне условий, включая нестабильные сетевые соединения, частичная доступность или перегрузки сети и изменения температуры. Кроме того chrony обладает и другими преимуществами:

  • chrony может быстрее синхронизировать системные часы с большей точностью;
  • chrony меньше, потребляет меньше памяти и обращается к процессору только тогда, когда это необходимо. Для экономии ресурсов и энергии это большой плюc;
  • chrony поддерживает метки времени на аппаратном уровне в Linux, что обеспечивает чрезвычайно точную синхронизацию в локальных сетях.


Впрочем, в chrony отсутствуют некоторые возможности старого NTP такие, как широковещательный и многоадресный (multicast) клиент / сервер. В добавок классический NTP поддерживает большее число ОС и платформ.

Для отключения функциональности сервера и NTP запросов к процессу chronyd достаточно прописать port 0 в файл chrony.conf. Это делается в тех случаях, когда нет нужды обслуживать время для NTP клиентов или одноранговых узлов. Начиная с версии 2.0, порт сервера NTP открыт только в тех случаях, когда доступ разрешен директивой allow или соответствующей командой, либо же настроен одноранговый узел NTP, или используется директива broadcast.

Программа состоит из двух модулей.

  • chronyd — сервис, работающий в фоновом режиме. Он получает информацию о разнице системных часов с внешним сервером времени и корректирует локальное время. Он также реализует протокол NTP и может выступать в качестве клиента или сервера.
  • chronyc — утилита командной строки для мониторинга и контроля программы. Используется для тонкой настройки различных параметров сервиса, например позволяет добавлять или удалять серверы NTP в то время, как chronyd продолжает работать.


Начиная с 7-й версии RedHat Linux использует chrony в качестве службы синхронизации времени. Пакет также доступен для остальных дистрибутивов Linux. Последняя стабильная версия 3.5, готовится к выходу v4.0.

(1:712)$ sudo emerge -av chrony
These are the packages that would be merged, in order:
Calculating dependencies... done!
[binary  N     ] net-misc/chrony-3.5-r2::gentoo  USE="adns caps cmdmon ipv6 ntp phc readline refclock rtc seccomp (-html) -libedit -pps (-selinux)" 246 KiB
Total: 1 package (1 new, 1 binary), Size of downloads: 246 KiB
Would you like to merge these packages? [Yes/No]


Как настроить собственный удаленный сервер chrony в интернете для синхронизации времени в офисной сети. Далее пример настройки на VPS.

Пример настройки Chrony на RHEL / CentOS на VPS


Давайте теперь немного потренируемся и поднимем свой собственный NTP сервер на VPS. Это очень просто, достаточно выбрать подходящий тариф на сайте RuVDS, получить готовый сервер и набрать с десяток несложных команд. Для наших целей вполне подойдет такой вариант.

86olu8or4hi_myh7oqob6vt3n_i.png

Переходим к настройке сервиса и первым делом ставим пакет chrony.

[root@server ~]$ yum install chrony


RHEL 8 / CentOS 8 используют другой пакетный менеджер.

[root@server ~]$ dnf install chrony


После установки chrony нужно запустить и активировать сервис.

[root@server ~]$ systemctl enable chrony --now


При желании можно внести правки в /etc/chrony.conf, заменив сервера NPT на ближайшие локальные для сокращения времени отклика.

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server 0.ru.pool.ntp.org iburst
server 1.ru.pool.ntp.org iburst
server 2.ru.pool.ntp.org iburst
server 3.ru.pool.ntp.org iburst


Далее настраиваем синхронизацию NTP сервера с узлами из указанного пула.

[root@server ~]$ timedatectl set-ntp true
[root@server ~]$ systemctl restart chronyd.service


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

[root@server ~]$ firewall-cmd --add-service=ntp --permanent 
[root@server ~]$ firewall-cmd --reload


На стороне клиента достаточно правильно выставить часовой пояс.

[root@client ~]$ timedatectl set-timezone Europe/Moscow


В файле /etc/chrony.conf указывает IP или название хоста нашего VPS сервера, на котором запущен NTP server chrony.

server my.vps.server


И наконец запуск синхронизации времени на клиенте.

[root@client ~]$ systemctl enable --now chronyd
[root@client ~]$ timedatectl set-ntp true


В следующий раз расскажу, какие есть варианты синхронизации времени без интернета.

guabcgmwuqoopx1ar80sjpz6keq.png

de0yl-6ppopvisr_a80b4yuhjj8.png

© Habrahabr.ru