Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English

Chrony et NTP : synchroniser l'heure d'un serveur

Par mis à jour le

Améliorer cette page

Chrony est le client et serveur NTP des distributions Linux actuelles : il cale l'horloge sur des serveurs de temps, avec une précision de l'ordre de la milliseconde sur Internet, et sait chiffrer l'échange avec NTS. Une horloge juste conditionne la corrélation des logs, la validité des certificats TLS et tout système distribué. Ce guide installe chrony, montre où vit sa configuration selon la distribution, apprend à lire chronyc tracking et chronyc sources, active NTS, puis ouvre le service à un réseau local. Public visé : administrateurs Linux. Chaque sortie a été relevée le 30 septembre 2026, avec chrony 4.6.1 (Debian 13), 4.5 (Ubuntu 24.04) et 4.8 (AlmaLinux 10).

  • Installer chrony et vérifier qu'il remplace bien le service de temps déjà présent.
  • Localiser le fichier de configuration, qui n'est pas au même endroit selon la famille.
  • Interpréter l'état de synchronisation avec chronyc tracking et chronyc sources.
  • Chiffrer l'échange de temps avec NTS et contrôler qu'il fonctionne.
  • Servir l'heure à un réseau local sans ouvrir le service à tous.
  • Un serveur Debian 13, Ubuntu 24.04 ou RHEL 10 (ou AlmaLinux, Rocky), avec les droits sudo.
  • Une sortie vers Internet sur le port UDP 123 (NTP), et TCP 4460 pour NTS.
  • Savoir démarrer un service et lire son état avec systemctl.

Une horloge qui dérive ne fait pas tomber un serveur : elle fausse tout ce qui compare des dates. Deux journaux décalés de trente secondes rendent un incident impossible à reconstituer, un certificat TLS paraît « pas encore valide » ou « expiré », un jeton d'authentification limité dans le temps est refusé. Toute horloge matérielle dérive, et celle d'une machine virtuelle dépend en plus de l'hôte qui la fait tourner.

Le protocole NTP (Network Time Protocol), conçu par David L. Mills et déployé dès 1985, corrige cette dérive en interrogeant des serveurs de temps. Chrony en est l'implémentation moderne : lancé en 1997 par Richard Curnow et maintenu par Miroslav Lichvar, il se cale plus vite que l'ancien ntpd au démarrage, supporte mieux les coupures réseau, et c'est lui que les distributions de référence proposent aujourd'hui.

Cinq notions suffisent pour lire tout ce que chrony affiche. Elles reviennent dans chaque sortie de chronyc, et les confondre mène à de mauvais diagnostics.

Le stratum mesure la distance à l'horloge de référence. Le stratum 0 est l'horloge physique elle-même (atomique, GPS), qui ne parle pas NTP. Un serveur relié directement à elle est de stratum 1, un serveur calé sur un stratum 1 est de stratum 2, et ainsi de suite. Votre serveur affiche donc le stratum de sa source plus un.

Une source est un serveur interrogé. La directive server en déclare un, la directive pool déclare un nom DNS derrière lequel se cachent plusieurs serveurs : chrony en retient jusqu'à quatre par défaut. Les distributions livrent un pool (2.debian.pool.ntp.org, 2.almalinux.pool.ntp.org), ce qui donne plusieurs sources sans rien écrire.

La dérive (drift) est l'écart de rythme entre l'horloge locale et l'heure réelle. Chrony la mesure en continu et l'enregistre dans le driftfile (/var/lib/chrony/chrony.drift sur Debian, /var/lib/chrony/drift sur AlmaLinux) : au redémarrage, il repart avec une correction déjà connue au lieu de la réapprendre.

Par défaut, chrony corrige en douceur (slew) : il accélère ou ralentit l'horloge jusqu'à rattraper l'écart, sans jamais revenir en arrière, ce qui préserve l'ordre des journaux et des transactions. La directive makestep 1 3, présente dans les trois configurations par défaut, autorise un saut immédiat si l'écart dépasse 1 seconde, et seulement lors des 3 premières mises à jour : c'est le cas d'une machine restée longtemps éteinte.

L'option iburst, derrière server ou pool, envoie une rafale de requêtes au démarrage au lieu d'attendre l'intervalle normal. Le premier calage prend ainsi quelques secondes au lieu de plusieurs minutes. Elle figure sur toutes les sources des configurations par défaut.

Sur Debian et Ubuntu, installer chrony désinstalle systemd-timesyncd, le client de temps minimal livré par défaut sur Ubuntu. Les deux paquets fournissent le même service virtuel, time-daemon, et s'excluent : le relevé d'APT sur Ubuntu 24.04 l'annonce en clair. Sur RHEL et ses dérivées, chrony est le service de temps standard.

Fenêtre de terminal
sudo apt update
sudo apt install chrony
The following packages will be REMOVED:
systemd-timesyncd

Le service démarre dès l'installation. Il s'appelle chrony.service, avec un alias chronyd.service : les deux noms fonctionnent avec systemctl.

Vérifiez ensuite que le service tourne et que l'horloge est synchronisée, deux choses différentes :

Fenêtre de terminal
systemctl status chronyd
chronyc tracking

Le fichier de configuration n'a pas le même chemin selon la famille, et c'est la première source d'erreur. Relevé sur les trois distributions de référence :

FamilleConfigurationClésRépertoires d'ajout
Debian 13, Ubuntu 24.04/etc/chrony/chrony.conf/etc/chrony/chrony.keys/etc/chrony/sources.d/, /etc/chrony/conf.d/
RHEL 10, AlmaLinux 10/etc/chrony.confaucune par défautaucun par défaut

Modifier /etc/chrony.conf sur une Debian, c'est écrire un fichier que chronyd ne lira jamais : la configuration semble posée, et rien ne change. Dans le doute, demandez à systemd quel démon tourne et avec quelles options :

Fenêtre de terminal
systemctl cat chronyd

Voici la configuration livrée par Debian 13, commentaires retirés. Celle d'AlmaLinux 10 contient les mêmes directives essentielles, avec le pool 2.almalinux.pool.ntp.org.

pool 2.debian.pool.ntp.org iburst
sourcedir /run/chrony-dhcp
sourcedir /etc/chrony/sources.d
keyfile /etc/chrony/chrony.keys
driftfile /var/lib/chrony/chrony.drift
ntsdumpdir /var/lib/chrony
logdir /var/log/chrony
maxupdateskew 100.0
rtcsync
makestep 1 3
leapseclist /usr/share/zoneinfo/leap-seconds.list
confdir /etc/chrony/conf.d

Les directives à connaître : pool (les sources), sourcedir (des sources ajoutées par fichier, ou fournies par DHCP dans /run/chrony-dhcp), driftfile (la dérive mémorisée), ntsdumpdir (le cache des clés NTS, qui évite de renégocier à chaque redémarrage), rtcsync (le noyau recopie régulièrement l'heure système dans l'horloge matérielle) et makestep.

Sur Debian et Ubuntu, la méthode propre consiste à ajouter un fichier dans /etc/chrony/sources.d/ plutôt que de modifier le fichier principal : il survit aux mises à jour du paquet. Le fichier doit se terminer par .sources et ne contenir que des lignes server, pool ou peer, et un simple reload suffit, sans redémarrer le service :

Fenêtre de terminal
echo 'server ntp.interne.lan iburst' | sudo tee /etc/chrony/sources.d/interne.sources
sudo chronyc reload sources

Sur RHEL et AlmaLinux, qui n'ont pas ce répertoire, ajoutez la ligne server dans /etc/chrony.conf, puis redémarrez :

Fenêtre de terminal
sudo systemctl restart chronyd

Déclarez au moins trois sources. Avec deux sources en désaccord, chrony ne peut pas savoir laquelle ment ; à partir de trois, il écarte celle qui s'éloigne des autres.

Un service chronyd actif ne prouve pas que l'heure est juste. Il peut tourner sans qu'aucune source ne réponde, par exemple si le port UDP 123 est filtré, et l'horloge dérive alors sans le moindre message d'erreur. Deux commandes font la preuve.

chronyc tracking dit à quelle source le système est calé et quel écart il mesure. Sortie relevée sur AlmaLinux 10, quelques secondes après le démarrage :

Reference ID : A29FC801 (time.cloudflare.com)
Stratum : 4
Ref time (UTC) : Wed Sep 30 14:44:15 2026
System time : 0.000812048 seconds slow of NTP time
Last offset : -0.000666413 seconds
RMS offset : 0.000666413 seconds
Frequency : 0.000 ppm slow
Residual freq : -196.961 ppm
Skew : 1000000.000 ppm
Root delay : 0.026948174 seconds
Root dispersion : 31.631998062 seconds
Update interval : 2.0 seconds
Leap status : Normal

Les lignes qui comptent au diagnostic :

  • Reference ID : la source retenue. Une valeur 00000000 signifie aucune source.
  • Stratum : celui de la source plus un. Un stratum 10 signale en général un serveur retombé sur son horloge locale (local stratum 10) faute de source joignable.
  • System time : l'écart courant, ici 0,8 milliseconde de retard.
  • Skew et Root dispersion : l'incertitude. Les valeurs énormes de cette sortie sont normales juste après le démarrage, elles fondent en quelques minutes.
  • Leap status : Normal quand tout va bien, Not synchronised quand l'horloge n'est calée sur rien.

chronyc sources liste les sources et dit laquelle est retenue. Avec l'option -v, chrony imprime sa propre légende au-dessus du tableau :

.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .- Source state '*' = current best, '+' = combined, '-' = not combined,
| / 'x' = may be in error, '~' = too variable, '?' = unusable.
|| .- xxxx [ yyyy ] +/- zzzz
|| Reachability register (octal) -. | xxxx = adjusted offset,
|| Log2(Polling interval) --. | | yyyy = measured offset,
|| \ | | zzzz = estimated error.
|| | | \
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^+ time.cloudflare.com 3 6 17 22 +1316us[+1806us] +/- 16ms
^* gbg2-ts.nts.netnod.se 1 6 17 22 -1400us[ -911us] +/- 22ms
^? ptbtime1.ptb.de 1 7 21 14 +1912us[+1912us] +/- 18ms

Le premier caractère donne le mode (^ pour un serveur), le second l'état, et c'est lui qu'on regarde :

SymboleSignification
*la meilleure source, celle qui règle actuellement l'horloge
+source combinée avec la meilleure pour affiner le calcul
-source sélectionnable mais non combinée, rien d'anormal
xsource que chronyd juge fausse (falseticker)
~source dont le temps est trop variable pour être exploité
?source inutilisable : injoignable, ou pas encore assez évaluée

La colonne Reach est un registre octal des huit dernières requêtes : 377 signifie huit réponses sur huit, 17 quatre réponses après un démarrage récent, 0 aucune. Poll est le logarithme en base 2 de l'intervalle : 6 vaut 64 secondes. Une horloge saine affiche au moins une ligne ^* et un Reach qui monte vers 377.

NTS (Network Time Security, RFC 8915) authentifie les réponses NTP : un attaquant placé sur le réseau ne peut plus fournir une fausse heure sans être détecté. Le NTP classique n'a aucune protection, et décaler l'horloge d'un serveur suffit à lui faire accepter un certificat expiré. Chrony gère NTS depuis sa version 4.0, et les trois versions relevées ici l'embarquent.

L'activation tient en une option, nts, sur des serveurs qui la proposent. Le manuel de chrony.conf recommande, dès qu'on authentifie, de retirer les sources non authentifiées : en mode mix par défaut, chrony ne les utilise que si elles concordent avec les sources NTS. Remplacez donc le pool par au moins trois serveurs NTS :

server time.cloudflare.com iburst nts
server nts.netnod.se iburst nts
server ptbtime1.ptb.de iburst nts

Sur Debian et Ubuntu, placez ces lignes dans un fichier .sources de /etc/chrony/sources.d/ et commentez la ligne pool du fichier principal ; sur AlmaLinux, remplacez la ligne pool de /etc/chrony.conf. Redémarrez ensuite le service.

chronyc authdata prouve que NTS fonctionne. Relevé avec les trois serveurs ci-dessus :

Name/IP address Mode KeyID Type KLen Last Atmp NAK Cook CLen
=========================================================================
time.cloudflare.com NTS 1 30 128 27 0 0 8 64
gbg2-ts.nts.netnod.se NTS 1 15 256 27 0 0 8 100
ptbtime1.ptb.de NTS 1 15 256 27 0 0 8 100

La colonne Cook compte les cookies reçus lors de l'établissement de la session : 8 signifie que la négociation a réussi. Un 0 avec un Atmp (tentatives) qui grimpe signale un échec de l'établissement, que le journal de chronyd explique.

Un seul serveur interne calé sur Internet, et toutes les machines du réseau calées sur lui : c'est l'architecture la plus courante. Par défaut, chrony ne sert l'heure à personne : il faut l'autoriser explicitement avec allow, sur le serveur interne.

allow 192.168.10.0/24

Si vous voulez que le serveur continue à répondre quand Internet est coupé, ajoutez local stratum 10 : il sert alors sa propre horloge, avec un stratum élevé qui avertit les clients de sa faible qualité. Ouvrez enfin le port UDP 123 dans le pare-feu, pour ce seul réseau, et déclarez le serveur côté clients avec une ligne server.

Chrony ouvre deux canaux distincts, et la plupart des erreurs de sécurité viennent de leur confusion. Le service NTP (UDP 123) distribue l'heure ; le canal de commande (UDP 323 et une socket Unix) permet à chronyc de piloter le démon.

DirectiveCanalEffet
allow / denyservice NTPqui peut recevoir l'heure
cmdallow / cmddenycommandesqui peut piloter chronyd à distance
bindcmdaddresscommandesl'adresse d'écoute des commandes

Par défaut, le canal de commande n'écoute que sur 127.0.0.1 et ::1, ce qui est le bon réglage : ne l'ouvrez pas au réseau avec cmdallow, sous peine d'exposer l'administration du démon en croyant ouvrir l'heure. Une ligne bindcmdaddress 127.0.0.1 ne fait que rendre ce défaut explicite.

Clés symétriques entre serveur et clients internes

Section intitulée « Clés symétriques entre serveur et clients internes »

Pour authentifier un serveur interne qui ne propose pas NTS, chrony accepte des clés symétriques, partagées entre le serveur et ses clients. Générez-les avec chronyc keygen, qui produit une clé SHA256 aléatoire, jamais une clé tapée à la main :

Fenêtre de terminal
chronyc keygen 1 SHA256 256
1 SHA256 HEX:1866637433DF91090E2D5F7E346120C2B803FB091A12BD7464B528194A66CC22

Copiez cette ligne dans le fichier de clés des deux côtés (/etc/chrony/chrony.keys sur Debian, un fichier déclaré par keyfile sur AlmaLinux), puis ajoutez key 1 à la ligne server du client. Le fichier de clés garde les droits livrés par Debian : propriétaire root, groupe du service (_chrony), mode 640. Chronyd abandonne les droits root après le démarrage : relevé sur Debian 13, un fichier en root:root 600 est bien chargé au lancement, mais le journal affiche Missing read access, et un chronyc rekey échoue ensuite sur Could not open keyfile. Un mode 644, à l'inverse, expose les clés à tous les comptes locaux.

SymptômeCause probableSolution
chronyc sources n'affiche que des ^? et un Reach à 0Port UDP 123 bloqué en sortie, ou DNS injoignableTester avec chronyc -n sources, ouvrir UDP 123 vers les serveurs
Reference ID : 00000000 et Leap status : Not synchronisedAucune source exploitableVérifier les sources, puis le pare-feu
Stratum : 10 sur un serveur interneRetombé sur local stratum 10, Internet injoignableRétablir l'accès aux sources externes
La configuration modifiée n'a aucun effetMauvais fichier (/etc/chrony.conf sur Debian)systemctl cat chronyd, puis modifier le bon fichier
Source NTS avec Cook 0 dans chronyc authdataca-certificates absent, ou TCP 4460 bloquéInstaller ca-certificates, ouvrir TCP 4460 en sortie
Les clients internes ne reçoivent aucune heurePas de allow, ou deny all écrit après allowUn seul allow <réseau>, sans deny all
Une directive copiée d'un vieux tutoriel reste sans effetDirective retirée, comme commandkey, ignorée avec un simple avertissementLire journalctl -u chronyd, supprimer la ligne signalée

Le journal du service, journalctl -u chronyd, donne la cause exacte d'une directive ignorée, d'un fichier de clés illisible ou d'un échec NTS.

Rien ne remplace la manipulation : ce lab vous fait configurer chrony, contrôler la synchronisation avec chronyc tracking et régler le fuseau horaire, le tout de façon persistante sur une VM.

  1. Un chronyd actif ne prouve rien : seuls chronyc tracking et une ligne ^* dans chronyc sources prouvent la synchronisation.
  2. La configuration vit dans /etc/chrony/chrony.conf sur Debian et Ubuntu, dans /etc/chrony.conf sur RHEL : modifier le mauvais fichier ne change rien.
  3. Installer chrony sur Debian ou Ubuntu retire systemd-timesyncd : un seul service de temps par machine.
  4. NTS authentifie l'heure avec l'option nts ; il exige ca-certificates et le port TCP 4460, et se vérifie avec chronyc authdata.
  5. Chrony ne sert l'heure à personne par défaut : un allow <réseau> suffit, et un deny all écrit après lui ferme tout.

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

La documentation du projet fait référence pour chaque directive, et le site de NTP retrace l'histoire du protocole.

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn