Comment faire en sorte que le temps en soi ne mente pas, si vous avez un million de grands et petits dispositifs interagissant par TCP/IP ? Chacun d'eux possède une horloge, et le temps doit être correct sur tous. Ce problème ne peut être contourné sans NTP.
Imaginons un instant qu'il y ait des difficultés de synchronisation des services dans un segment de l'infrastructure informatique industrielle. Le stack logiciel d'entreprise commence rapidement à mal fonctionner, les domaines se désintègrent, et les nœuds maîtres et de secours luttent en vain pour rétablir le statu quo.
Il peut également y avoir des situations où un attaquant tente délibérément de corrompre le temps par une attaque MiTM ou DDoS. Dans ce cas, tout peut se produire :
- les mots de passe des comptes utilisateurs peuvent expirer ;
- les certificats X.509 peuvent expirer ;
- l'authentification à deux facteurs TOTP peut cesser de fonctionner ;
- les sauvegardes peuvent devenir « périmées » et le système peut les supprimer ;
- DNSSEC peut échouer.
Il est clair que chaque département IT est intéressé par le bon fonctionnement des services de synchronisation du temps, et il serait souhaitable qu'ils soient fiables et sécurisés dans un environnement industriel.
Détruire NTP en 25 minutes
Les protocoles réseau – les millénials ont une particularité, ils existent depuis longtemps et ne sont plus pertinents, mais les remplacer n’est pas si facile, même lorsque l'on parvient à rassembler une masse critique d'enthousiastes et de financement.
La principale critique du NTP classique est l'absence de mécanismes fiables de protection contre les attaques des malveillants. Diverses tentatives ont été faites pour résoudre ce problème. On a d'abord introduit un mécanisme de clés préétablies (PSK) pour l'échange de clés symétriques.
Malheureusement, cette méthode ne s'est pas révélée efficace pour une raison simple : elle est mal évolutive. Une configuration manuelle est nécessaire du côté client en fonction du serveur. Cela signifie qu'il n'est pas si simple d'ajouter un autre client. Si quelque chose change sur le serveur NTP, tous les clients doivent être reconfigurés.
Ensuite, AutoKey a été imaginé, mais dès le début, plusieurs vulnérabilités sérieuses dans la conception même de l'algorithme ont été découvertes, et il a fallu y renoncer. Le problème est que le nombre initial (seed) ne contient que 32 bits, ce qui est trop peu et ne fournit pas une complexité suffisante pour une attaque de brute force.
- Key ID — une clé symétrique de 32 bits ;
- MAC (code d'authentification de message) — somme de contrôle du paquet NTP;
Autokey est calculé de la manière suivante.
Autokey=H(Adresse-IP-Expéditeur||Adresse-IP-Destinataire||Identifiant-Clé||Cookie)Où H() est une fonction de hachage cryptographique.
Pour le calcul de la somme de contrôle, la même fonction est utilisée pour les paquets.
MAC=H(Autokey||paquet NTP)Ainsi, toute l'intégrité des vérifications des paquets repose sur l'authenticité des cookies. En les récupérant, on peut retrouver l'autokey et ensuite falsifier le MAC. Cependant, le serveur NTP utilise un nombre initial (seed) lors de leur génération. C'est ici que réside le piège.
Cookie=MSB_32(H(Adresse IP Client||Adresse IP Serveur||0||Seed Serveur))La fonction MSB_32 coupe les 32 bits supérieurs du résultat du calcul du hachage md5. Le cookie client ne change pas tant que les paramètres du serveur restent inchangés. Ensuite, il ne reste plus qu'à l'attaquant à retrouver le nombre initial pour pouvoir générer lui-même des cookies.
Pour commencer, il faut se connecter au serveur NTP en tant que client et obtenir le cookie. Ensuite, par méthode de force brute, l'attaquant retrouve le nombre initial en suivant un algorithme simple.
L'algorithme d'attaque pour calculer le nombre initial par force brute.
for i=0:2^32 − 1 do
Ci=H(Adresse-IP-Serveur||Adresse-IP-Client||0||i)
if Ci=Cookie then
return i
end if
end forLes adresses IP sont connues, il ne reste plus qu'à créer 2^32 hachages jusqu'à ce que le cookie créé corresponde à celui reçu du serveur NTP. Sur une station de travail ordinaire avec un Intel Core i5, cela prendra 25 minutes.
NTS — nouveau Autokey
Il était impossible d'accepter de telles failles de sécurité dans Autokey et en 2012 est apparu le protocole. Dans un souci de compromis, il a été décidé de procéder à un rebranding, ainsi Autokey v.2 a été renommé Network Time Security.
Le protocole NTS est une extension de sécurité pour NTP et prend actuellement en charge uniquement le mode unicast. Il offre une protection cryptographique fiable contre les manipulations de paquets, prévient le suivi, se scalabilité bien, est résistant à la perte de paquets réseau et entraîne les moindres pertes de précision survenant lors de la protection de la connexion.
La connexion NTS se compose de deux étapes, au cours desquelles des protocoles de niveau inférieur sont utilisés. À la première étape, le client et le serveur conviennent de différents paramètres de connexion et échangent des cookies contenant des clés avec l'ensemble de données associé. À la deuxième étape, a lieu la véritable séance NTS sécurisée entre le client et le serveur NTP.

NTS se compose de deux protocoles de bas niveau : l'échange de clés de sécurité du temps réseau (NTS-KE), qui initialise une connexion sécurisée via TLS, et NTPv4 — la dernière version du protocole NTP. Un peu plus de détails ci-dessous.
Première étape — NTS KE
À cette étape, le client NTP initie une session TLS 1.2/1.3 sur une connexion TCP distincte avec le serveur NTS KE. Au cours de cette session, les éléments suivants se produisent.
- Les parties définissent les paramètres de l'algorithme pour la deuxième étape.
- Les parties définissent le deuxième protocole de bas niveau, mais pour le moment seul NTPv4 est supporté.
- Les parties définissent l'adresse IP et le port du serveur NTP.
- Le serveur NTS KE délivre des cookies pour NTPv4.
- Les parties extraient des cookies une paire de clés symétriques (C2S et S2C).
Cette approche présente l'avantage majeur de faire porter toute la charge de transmission des informations secrètes des paramètres de connexion sur un protocole TLS éprouvé et fiable. Cela élimine ainsi le besoin d'inventer un nouveau moyen de négociation NTP sécurisé.
Deuxième étape — NTP protégé par NTS
À la deuxième étape, le client synchronise en toute sécurité l'heure avec le serveur NTP. Pour cela, il transmet quatre extensions spéciales (extension field) dans la structure du paquet NTPv4.
- L'extension d'identifiant unique contient un nonce aléatoire pour prévenir les attaques par répétition.
- L'extension de cookie NTS contient l'un des cookies NTP dont dispose le client. Comme seul le client dispose des clés symétriques C2S et S2C, le serveur NTP doit les extraire des cookies.
- L'extension d'espace réservé pour le cookie NTS est un moyen pour le client de demander des cookies supplémentaires au serveur. Cette extension est nécessaire pour éviter que la réponse du serveur NTP ne soit beaucoup plus longue que la requête. Cela permet de prévenir les attaques par amplification.
- L'extension des champs d'authentification et de chiffrement NTS contient le chiffrement de l'algorithme AAED avec la clé C2S, l'en-tête NTP, des horodatages, et les EF mentionnés ci-dessus comme données auxiliaires. Sans cette extension, il est possible de falsifier les horodatages.

Après avoir reçu la requête du client, le serveur vérifie l'authenticité du paquet NTP. Pour cela, il doit déchiffrer le cookie, extraire l'algorithme AAED et les clés. Après une validation réussie du paquet NTP, le serveur répond au client dans le format suivant.
- L'extension d'identifiant unique est une copie miroir de la requête du client, une mesure contre les attaques par répétition.
- L'extension de cookie NTS est un cookie supplémentaire pour poursuivre la session.
- L'extension NTS Authenticator et des Champs d'Extension Encrypés contient un chiffrement AEAD avec une clé S2C.
La seconde poignée de main peut être répétée plusieurs fois, évitant la première étape, car chaque requête et réponse fournit au client des cookies supplémentaires. Cela présente l'avantage de répartir le calcul intensif et la transmission des données PKI de TLS sur un nombre de requêtes répétées. C'est particulièrement pratique pour les chronomètres FPGA spécialisés, lorsque toute la fonctionnalité principale peut être regroupée en plusieurs fonctions de cryptographie symétrique, transférant toute la pile TLS sur un autre appareil.
NTPSec
Quelle est la particularité du NTP ? Bien que l'auteur du projet, Dave Mills, ait tenté de documenter son code au mieux, il est rare qu'un programmeur puisse comprendre les méandres d'algorithmes de synchronisation temporelle vieux de 35 ans. Une partie du code a été écrite avant l'ère POSIX, et l'API Unix de l'époque différait considérablement de celle utilisée aujourd'hui. De plus, des connaissances en statistique sont nécessaires pour nettoyer le signal des interférences sur des lignes bruyantes.
NTS n'était pas la première tentative de réparer le NTP. Après que des attaquants aient appris à exploiter les vulnérabilités du NTP pour renforcer les attaques DDoS, il est devenu évident qu'un changement radical était nécessaire. Pendant que les brouillons de NTS étaient préparés et finalisés, la National Science Foundation des États-Unis a rapidement alloué des fonds en fin 2014 pour moderniser le NTP.
Le groupe de travail était dirigé par nul autre que — un des fondateurs et des piliers de la communauté Open Source et auteur du livre . Dans un premier temps, Eric et ses collègues ont essayé de migrer le code du NTP de la plateforme BitKeeper vers git, mais sans succès. Le leader du projet, Harlan Stenn, était contre cette décision, et les négociations ont échoué. Ils ont donc décidé de forker le code du projet, donnant naissance à NTPSec.
Avec une solide expérience, notamment en travaillant sur le GPSD, un bagage mathématique et un talent magique pour lire du vieux code, Eric Raymond était exactement le hacker capable de réaliser un tel projet. Un spécialiste de la migration de code a rejoint l'équipe, et en seulement 10 semaines, NTP sur GitLab. Le travail a commencé avec enthousiasme.
L'équipe d'Eric Raymond s'est attaquée à la tâche avec la même détermination qu'Auguste Rodin face à un bloc de pierre. En supprimant 175 KLOC de code ancien, ils ont réussi à réduire considérablement la surface d'attaque, fermant de nombreuses failles de sécurité.
Voici une liste non exhaustive des victimes :
- Refclock non documentés, obsolètes, ou cassés.
- Bibliothèque ICS inutilisée.
- libopts/autogen.
- Ancien code pour Windows.
- ntpdc.
- Autokey.
- Le code C de ntpq a été réécrit en Python.
- Le code C de sntp/ntpdig a été réécrit en Python.
En plus du nettoyage du code, le projet a également eu d'autres objectifs. Voici une liste non exhaustive des réalisations :
- La protection du code contre les débordements de tampon a été considérablement renforcée. Pour éviter les débordements de tampon, toutes les fonctions de chaîne de caractères non sécurisées (strcpy / strcat / strtok / sprintf / vsprintf / gets) ont été remplacées par des versions sécurisées, qui implémentent une limitation de la taille du tampon.
- Support NTS ajouté.
- La précision des pas temporels a été décuplée grâce à l'intégration de matériel physique. Cela s'explique par le fait que les horloges d'ordinateur modernes sont beaucoup plus précises que celles disponibles au début de NTP. GPSDO et les stations de temps dédiées en ont le plus bénéficié.
- Le nombre de langages de programmation a été réduit à deux. Au lieu des scripts Perl, awk et même S, nous utilisons maintenant uniquement Python. Cela permet d'avoir plus de possibilités de réutilisation du code.
- Au lieu d'un enchevêtrement de scripts autotools, le projet utilise un système de construction de logiciels. .
- La documentation du projet a été mise à jour et réorganisée. De la collection contradictoire et parfois archaïque de documents, une documentation acceptable a été créée. Chaque option de ligne de commande et chaque entité de configuration possède maintenant une version unique de la vérité. De plus, les pages de manuel et la documentation Web sont maintenant générées à partir des mêmes fichiers de base.
NTPSec est disponible pour plusieurs distributions Linux. Actuellement, la dernière version stable est 1.1.8, pour Gentoo Linux — l'avant-dernière.
(1:696)$ sudo emerge -av ntpsec
Voici les paquets qui seraient installés, dans l'ordre :
Calcul des dépendances... terminé !
[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 Ko
Total : 1 paquet (1 réinstallation), Taille des téléchargements : 0 Ko
Souhaitez-vous fusionner ces paquets ? [ Oui / Non ]
Chrony
Une autre tentative a été faite pour remplacer l'ancien NTP par une alternative plus sécurisée. Chrony, contrairement à NTPSec, est écrit de zéro et conçu pour fonctionner de manière fiable dans une large gamme de conditions, y compris les connexions réseau instables, la disponibilité partielle ou la saturation du réseau et les variations de température. En outre, chrony présente d'autres avantages :
- chrony peut synchroniser les horloges système plus rapidement et avec une plus grande précision ;
- chrony consomme moins de mémoire et n'accède au processeur que lorsque cela est nécessaire. Pour économiser des ressources et de l'énergie, c'est un grand plus ;
- chrony prend en charge les horodatages au niveau matériel sous Linux, offrant ainsi une synchronisation extrêmement précise dans les réseaux locaux.
Cependant, chrony manque de certaines fonctionnalités de l'ancien NTP, comme le client/serveur en mode diffus et en mode multicast. De plus, le NTP classique prend en charge un plus grand nombre de systèmes d'exploitation et de plateformes.
Pour désactiver la fonctionnalité serveur et les requêtes NTP pour le processus chronyd, il suffit d'écrire port 0 dans le fichier chrony.conf. Cela se fait dans les cas où il n'est pas nécessaire de fournir l'heure pour les clients NTP ou les nœuds pair-à-pair. À partir de la version 2.0, le port du serveur NTP est ouvert uniquement si l'accès est autorisé par la directive allow ou par une commande correspondante, ou si un nœud pair-à-pair NTP est configuré, ou si la directive broadcast est utilisée.
Le programme se compose de deux modules.
- chronyd — un service fonctionnant en arrière-plan. Il obtient des informations sur la différence entre les horloges système et un serveur de temps externe et corrige l'heure locale. Il implémente également le protocole NTP et peut agir en tant que client ou serveur.
- chronyc — un outil en ligne de commande pour surveiller et contrôler le programme. Il est utilisé pour affiner divers paramètres du service, par exemple en permettant d'ajouter ou de supprimer des serveurs NTP pendant que chronyd continue de fonctionner.
À partir de la 7ème version de RedHat Linux chrony en tant que service de synchronisation de temps. Le paquet est également disponible pour d'autres distributions Linux. La dernière version stable 3.5, prépare la sortie de la version 4.0.
(1:712)$ sudo emerge -av chrony
Voici les paquets qui seraient fusionnés, dans cet ordre :
Calcul des dépendances... fait !
[binaire N ] net-misc/chrony-3.5-r2::gentoo USE="adns caps cmdmon ipv6 ntp phc readline refclock rtc seccomp (-html) -libedit -pps (-selinux)" 246 Ko
Total : 1 paquet (1 nouveau, 1 binaire), taille des téléchargements : 246 Ko
Souhaitez-vous fusionner ces paquets ? [Oui/Non]
Comment configurer votre propre serveur distant chrony sur Internet pour synchroniser l'heure dans un réseau de bureau. Voici un exemple de configuration sur un VPS.
Exemple de configuration de Chrony sur RHEL / CentOS sur VPS
Passons maintenant à la pratique et créons notre propre serveur NTP sur un VPS. C'est très simple, il suffit de choisir le bon tarif sur le site RuVDS, d'obtenir un serveur prêt à l'emploi et de taper une dizaine de commandes simples. Pour nos objectifs, cette option conviendra tout à fait.

Nous passons à la configuration du service et tout d'abord, installons le paquet chrony.
[root@server ~]$ yum install chronyRHEL 8 / CentOS 8 utilise un autre gestionnaire de paquets.
[root@server ~]$ dnf install chronyAprès l'installation de chrony, il faut démarrer et activer le service.
[root@server ~]$ systemctl enable chrony --nowSi désiré, vous pouvez modifier le fichier /etc/chrony.conf, en remplaçant les serveurs NPT par les plus proches pour réduire le temps de réponse.
# 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
Ensuite, configurons la synchronisation du serveur NTP avec les nœuds du pool spécifié.
[root@server ~]$ timedatectl set-ntp true
[root@server ~]$ systemctl restart chronyd.service
Il est également nécessaire d'ouvrir le port NTP, sinon le pare-feu bloquera les connexions entrantes des nœuds clients.
[root@server ~]$ firewall-cmd --add-service=ntp --permanent
[root@server ~]$ firewall-cmd --reload
Du côté client, il suffit de régler correctement le fuseau horaire.
[root@client ~]$ timedatectl set-timezone Europe/MoscowDans le fichier /etc/chrony.conf, spécifiez l'IP ou le nom d'hôte de notre serveur VPS sur lequel le serveur NTP chrony est en cours d'exécution.
server my.vps.serverEnfin, lancez la synchronisation de l'heure sur le client.
[root@client ~]$ systemctl enable --now chronyd
[root@client ~]$ timedatectl set-ntp true
La prochaine fois, je parlerai des options de synchronisation de l'heure sans Internet.
Source : habr.com
