¿Cómo hacer para que el tiempo per se no mienta, si tienes un millón de dispositivos grandes y pequeños interactuando a través de TCP/IP? Porque en cada uno de ellos hay un reloj, y el tiempo debe ser correcto en todos. Este problema no se puede evitar sin NTP.
Imaginemos por un minuto que en un segmento de la infraestructura de TI industrial hay dificultades para sincronizar servicios por tiempo. Inmediatamente comienza a fallar el stack de software empresarial, los dominios colapsan, los nodos maestros y en espera luchan infructuosamente por restaurar el status quo.
También puede darse la situación en que un atacante intente deliberadamente alterar el tiempo a través de un ataque MiTM o DDoS. En tal caso, puede ocurrir cualquier cosa:
- los plazos de caducidad de las contraseñas de las cuentas de usuario expirarán;
- los certificados X.509 caducarán;
- la autenticación de dos factores TOTP dejará de funcionar;
- las copias de seguridad se volverán "obsoletas" y el sistema las eliminará;
- se romperá DNSSec.
Es evidente que cada primer departamento de TI está interesado en el funcionamiento confiable de los servicios de sincronización de tiempo, y sería ideal que fueran confiables y seguros en explotación industrial.
Romper NTP en 25 minutos
Los protocolos de red - los millennials tienen una particularidad, han estado obsoletos desde hace tiempo La principal queja contra el NTP clásico es la falta de mecanismos de protección confiables contra ataques de intrusos. Se han hecho diversos intentos para resolver este problema. Para ello se introdujo primero un mecanismo de claves preestablecidas (PSK) para el intercambio de claves simétricas.
Desafortunadamente, este método no cumplió debido a una razón simple: no escala bien. Se requiere una configuración manual en el lado del cliente dependiendo del servidor. Esto significa que no se puede simplemente añadir otro cliente. Si algo cambia en el servidor NTP, hay que reconfigurar todos los clientes.
Entonces se ideó AutoKey, pero se descubrieron de inmediato varias vulnerabilidades serias en el propio diseño del algoritmo y se tuvo que abandonar. Todo se debe a que el número inicial (seed) contiene solo 32 bits, lo cual es muy poco y no contiene suficiente complejidad computacional para un ataque de fuerza bruta.
Entonces se ideó AutoKey, pero inmediatamente se descubrieron una serie de vulnerabilidades graves en el propio diseño del algoritmo, lo que llevó a descartarlo. El problema es que el número inicial (seed) contiene solo 32 bits, lo cual es demasiado poco y no ofrece suficiente complejidad computacional para un ataque por fuerza bruta.
- ID de clave — clave simétrica de 32 bits;
- MAC (código de autenticación de mensaje) — suma de verificación del paquete NTP;
Autokey se calcula de la siguiente manera.
Autokey=H(Sender-IP||Receiver-IP||KeyID||Cookie)Donde H() es una función hash criptográfica.
Para calcular la suma de verificación del paquete se utiliza la misma función.
MAC=H(Autokey||paquete NTP)Así que resulta que toda la integridad de las verificaciones de paquetes se basa en la autenticidad de las cookies. Al apoderarse de ellas, se puede recuperar autokey y luego falsificar el MAC. Sin embargo, el servidor NTP utiliza un número inicial (seed) al generarlas. Aquí es donde se encuentra la trampa.
Cookie=MSB_32(H(IP del cliente||IP del servidor||0||Server Seed))La función MSB_32 corta los 32 bits más significativos del resultado del cálculo del hash md5. La cookie del cliente no cambia mientras los parámetros del servidor sean inalterados. A partir de ahí, al atacante solo le queda recuperar el número inicial y obtener la capacidad de generar cookies por sí mismo.
Para empezar, debe conectarse al servidor NTP como cliente y obtener cookies. Después de eso, mediante prueba y error, el atacante recupera el número inicial siguiendo un algoritmo simple.
Algoritmo de ataque para calcular el número inicial mediante prueba y error.
for i=0:2^32 − 1 do
Ci=H(IP del servidor||IP del cliente||0||i)
if Ci=Cookie then
return i
end if
end forLas direcciones IP son conocidas, por lo que solo queda crear 2^32 hashes hasta que la cookie generada coincida con la que se obtuvo del servidor NTP. En una estación doméstica normal con un Intel Core i5, esto tomará 25 minutos.
NTS — nuevo Autokey
No era posible convivir con tales fallos de seguridad en Autokey, y en 2012 surgió el protocolo. En un esfuerzo por diferenciar su nombre comprometido, se decidió realizar un rebranding, así que Autokey v.2 fue apodado Network Time Security.
El protocolo NTS es una extensión de seguridad del NTP y actualmente solo admite modo unidireccional (unicast). Proporciona una protección criptográfica fiable contra manipulaciones de paquetes, previene el rastreo, se escala bien, es resistente a la pérdida de paquetes de red y da como resultado las menores pérdidas de precisión que surgen durante la protección de la conexión.
La conexión NTS consta de dos etapas, en las que se utilizan protocolos de nivel inferior. En la primera etapa, el cliente y el servidor acuerdan varios parámetros de conexión e intercambian cookies que contienen claves junto con todo el conjunto de datos asociado. En la segunda en la etapa se lleva a cabo la sesión NTS protegida entre el cliente y el servidor NTP.

NTS consta de dos protocolos de nivel inferior: Intercambio de Claves de Seguridad de Tiempo de Red (NTS-KE), que inicia una conexión segura sobre TLS, y NTPv4, la última versión del protocolo NTP. Un poco más sobre esto a continuación.
La primera etapa es NTS KE
En esta etapa, el cliente de NTP inicia una sesión TLS 1.2/1.3 sobre una conexión TCP separada con el servidor NTS KE. Durante esta sesión, ocurre lo siguiente.
- Las partes determinan los parámetros del algoritmo para la segunda etapa.
- Las partes determinan el segundo protocolo de nivel inferior, pero en este momento solo se soporta NTPv4.
- Las partes definen la dirección IP y el puerto del servidor NTP.
- El servidor NTS KE emite cookies para NTPv4.
- Las partes extraen de las cookies un par de claves simétricas (C2S y S2C).
Este enfoque tiene una gran ventaja en el sentido de que toda la carga por la transmisión de información secreta de los parámetros de conexión recae sobre un protocolo TLS probado y confiable. Esto elimina la necesidad de inventar una solución propia para el apretón de manos seguro de NTP.
La segunda etapa es NTP protegido por NTS
En la segunda etapa, el cliente sincroniza el tiempo de manera segura con el servidor NTP. Para ello, envía cuatro extensiones especiales (extension field) en la estructura del paquete NTPv4.
- La extensión Unique Identifier contiene un nonce aleatorio para prevenir ataques de repetición.
- La extensión NTS Cookie contiene una de las cookies NTP que posee el cliente. Dado que solo el cliente tiene las claves simétricas C2S y S2C, el servidor NTP debe extraerlas del material de la cookie.
- La extensión NTS Cookie Placeholder es un medio para que el cliente solicite cookies adicionales del servidor. Esta extensión es necesaria para que la respuesta del servidor NTP no sea mucho más larga que la solicitud. Esto ayuda a prevenir ataques de amplificación.
- La extensión NTS Authenticator and Encrypted Extension Fields contiene el cifrado del algoritmo AAED con la clave C2S, el encabezado NTP, marcas de tiempo y las mencionadas anteriormente EF como datos auxiliares. Sin esta extensión, es posible falsificar marcas de tiempo.

Al recibir una solicitud del cliente, el servidor verifica la autenticidad del paquete NTP. Para ello, debe descifrar la cookie y extraer el algoritmo AAED y las claves. Tras verificar con éxito la validez del paquete NTP, el servidor responde al cliente en el siguiente formato.
- La extensión Unique Identifier es una copia espejo de la solicitud del cliente, una medida contra ataques de repetición.
- La extensión NTS Cookie almacena más cookies para mantener la sesión.
- La extensión NTS Authenticator y Campos de Extensión Encriptados contiene un cifrado AEAD con una clave S2C.
El segundo apretón de manos se puede repetir muchas veces, omitiendo la primera etapa, ya que cada solicitud y respuesta le otorgan al cliente cookies adicionales. Esto otorga la ventaja de que las operaciones de TLS, que consumen recursos, relacionadas con los cálculos y la transmisión de datos PKI, se distribuyen a lo largo de varias solicitudes repetidas. Esto es especialmente conveniente para cronómetros FPGA especializados, cuando se puede empaquetar toda la funcionalidad principal en varias funciones de criptografía simétrica, trasladando toda la pila TLS a otro dispositivo.
NTPSec
¿Cuál es la peculiaridad de NTP? A pesar de que el autor del proyecto, Dave Mills, se esforzó por documentar su código lo mejor posible, pocos programadores podrán desentrañar los enredos de los algoritmos de sincronización de tiempo con 35 años de antigüedad. Parte del código fue escrito antes de la era POSIX, y la API de Unix de aquel entonces se difería mucho de la que se usa hoy en día. Además, se requieren conocimientos de estadística para limpiar la señal de interferencias en líneas ruidosas.
NTS no fue el primer intento de arreglar NTP. Después de que los atacantes aprendieran a explotar vulnerabilidades en NTP para amplificar ataques de DDoS, se hizo evidente que se necesitaban cambios radicales. Y mientras se preparaban y refinaban los borradores de NTS, la Fundación Nacional de Ciencias de EE. UU. urgía a finales de 2014 a otorgar una subvención para la modernización de NTP.
El grupo de trabajo fue liderado por nada menos que — uno de los fundadores y pilares de la comunidad de código abierto y autor del libro . Lo primero que Eric y sus compañeros intentaron fue trasladar el código de NTP de la plataforma BitKeeper a git, pero no fue posible. El líder del proyecto, Harlan Stenn, se opuso a esta decisión y las negociaciones llegaron a un punto muerto. Entonces se decidió bifurcar el código del proyecto, y así nació NTPSec.
Con sólida experiencia, incluidas contribuciones a GPSD, un fondo matemático y una mágica habilidad para leer código antiguo, Eric Raymond era precisamente el hacker que podía liderar un proyecto así. En el equipo se encontraba un especialista en migración de código y en solo 10 semanas NTP en GitLab. El trabajo comenzó.
El equipo de Eric Raymond se puso a trabajar con la misma dedicación que Auguste Rodin al trabajar con un bloque de piedra. Al eliminar 175 KLOC de código antiguo, lograron reducir significativamente la superficie de ataque, cerrando muchas brechas de seguridad.
Aquí hay una lista incompleta de lo que se ha visto afectado:
- Relojes de referencia no documentados, obsoletos, desactualizados o rotos.
- Biblioteca ICS no utilizada.
- libopts/autogen.
- Código antiguo para Windows.
- ntpdc.
- Autokey.
- El código C de ntpq se ha reescrito en Python.
- El código C de sntp/ntpdig se ha reescrito en Python.
Además de limpiar el código, el proyecto tuvo otras tareas. Aquí hay una lista incompleta de logros:
- Se ha reforzado significativamente la protección del código contra desbordamientos de búfer. Para evitar desbordamientos de búfer, se han reemplazado todas las funciones de cadena inseguras (strcpy / strcat / strtok / sprintf / vsprintf / gets) por versiones seguras que implementan restricciones de tamaño de búfer.
- Se añadió soporte para NTS.
- Se ha aumentado la precisión del intervalo de tiempo diez veces mediante la sincronización con hardware físico. Esto se debe a que los relojes de computadora modernos son mucho más precisos que los de la época en que nació NTP. GPSDO y estaciones de tiempo dedicadas fueron las que más se beneficiaron.
- El número de lenguajes de programación se ha reducido a dos. En lugar de los scripts en Perl, awk e incluso S, ahora es todo Python. Esto permite más reutilización de código.
- En lugar de un enredo de scripts, autotools, el proyecto ahora utiliza un sistema de construcción de software. .
- Se actualizó y reorganizó la documentación del proyecto. Se creó una documentación razonable a partir de una colección contradictoria y, a veces, arcaica de documentos. Cada opción de línea de comandos y cada entidad de configuración ahora tiene una única versión de la verdad. Además, las páginas del manual y la documentación web ahora se generan a partir de los mismos archivos base.
NTPSec está disponible para varias distribuciones de Linux. Actualmente, la última versión estable es 1.1.8, para Gentoo Linux — la penúltima.
(1:696)$ sudo emerge -av ntpsec
Estos son los paquetes que se fusionarían, en orden:
Calculando dependencias... ¡hecho!
[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 paquete (1 reinstalación), Tamaño de las descargas: 0 KiB
¿Te gustaría fusionar estos paquetes? [Sí/No]
Chrony
Hubo otro intento de reemplazar el antiguo NTP por un análogo más seguro. Chrony, a diferencia de NTPSec, fue escrito desde cero y está diseñado para funcionar de manera confiable en una amplia gama de condiciones, incluyendo conexiones de red inestables, disponibilidad parcial o congestión de red y cambios de temperatura. Además, chrony tiene otras ventajas:
- chrony puede sincronizar los relojes del sistema más rápido y con mayor precisión;
- chrony es más compacto, consume menos memoria y accede al procesador solo cuando es necesario. Esto es un gran plus para la conservación de recursos y energía;
- chrony soporta marcas de tiempo a nivel de hardware en Linux, lo que asegura una sincronización extremadamente precisa en redes locales.
Sin embargo, chrony carece de algunas capacidades del antiguo NTP, como el cliente/servidor tipo broadcast y multicast. Además, el NTP clásico soporta un mayor número de sistemas operativos y plataformas.
Para desactivar la funcionalidad del servidor y las solicitudes NTP al proceso chronyd, es suficiente con escribir port 0 en el archivo chrony.conf. Esto se hace en casos donde no es necesario proporcionar la hora a los clientes NTP o nodos en pares. Desde la versión 2.0, el puerto del servidor NTP solo se abre cuando se permite el acceso mediante la directiva allow o una instrucción correspondiente, o si se configura un nodo en pares NTP, o se utiliza la directiva broadcast.
El programa consta de dos módulos.
- chronyd es el servicio que opera en segundo plano. Obtiene información sobre la diferencia de los relojes del sistema con un servidor de tiempo externo y corrige la hora local. También implementa el protocolo NTP y puede actuar como cliente o servidor.
- chronyc es una utilidad de línea de comandos para monitorear y controlar el programa. Se utiliza para afinar varios parámetros del servicio, por ejemplo, permite agregar o eliminar servidores NTP mientras chronyd continúa funcionando.
Desde la séptima versión de RedHat Linux chrony como un servicio de sincronización de tiempo. El paquete también está disponible para otras distribuciones de Linux. La última versión estable es la 3.5, se está preparando el lanzamiento de la v4.0.
(1:712)$ sudo emerge -av chrony
Estos son los paquetes que se fusionarían, en orden:
Calculando dependencias... ¡hecho!
[binaro 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 paquete (1 nuevo, 1 binario), Tamaño de descargas: 246 KiB
¿Te gustaría fusionar estos paquetes? [Sí/No]
Cómo configurar su propio servidor remoto chrony en Internet para sincronizar la hora en una red de oficina. A continuación, un ejemplo de configuración en VPS.
Ejemplo de configuración de Chrony en RHEL / CentOS en VPS
Ahora vamos a practicar un poco y levantaremos nuestro propio servidor NTP en VPS. Es muy sencillo, solo hay que elegir un plan adecuado en el sitio de RuVDS, obtener un servidor listo y ejecutar un par de comandos sencillos. Para nuestros propósitos, esta opción es más que adecuada.

Pasamos a la configuración del servicio y lo primero que haremos es instalar el paquete chrony.
[root@server ~]$ yum install chronyRHEL 8 / CentOS 8 utilizan un gestor de paquetes diferente.
[root@server ~]$ dnf install chronyDespués de instalar chrony, es necesario iniciar y activar el servicio.
[root@server ~]$ systemctl enable chrony --nowSi lo desea, puede hacer modificaciones en /etc/chrony.conf, reemplazando los servidores NTP por los más cercanos para reducir el tiempo de respuesta.
# 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
A continuación, configuramos la sincronización del servidor NTP con los nodos del grupo especificado.
[root@server ~]$ timedatectl set-ntp true
[root@server ~]$ systemctl restart chronyd.service
También es necesario abrir el puerto NTP al exterior, de lo contrario, el cortafuegos bloqueará las conexiones entrantes de los nodos clientes.
[root@server ~]$ firewall-cmd --add-service=ntp --permanent
[root@server ~]$ firewall-cmd --reload
En el lado del cliente, es suficiente ajustar correctamente la zona horaria.
[root@client ~]$ timedatectl set-timezone Europe/MoscowEn el archivo /etc/chrony.conf, especifique la IP o el nombre del host de nuestro servidor VPS donde se está ejecutando el servidor NTP chrony.
server my.vps.serverY finalmente, iniciamos la sincronización de la hora en el cliente.
[root@client ~]$ systemctl enable --now chronyd
[root@client ~]$ timedatectl set-ntp true
La próxima vez contaré qué opciones hay para sincronizar la hora sin Internet.
Fuente: habr.com
