Configurer le fuseau horaire et la synchronisation de l'heure sur un serveur Linux

Publié le 18 min de lecture

Une horloge de serveur fausse ne se signale jamais comme horloge, mais comme certificat refusé, comme source de paquets qu'apt n'accepte pas ou comme tâche cron partie à la mauvaise heure. Comment régler correctement le fuseau horaire et le service de temps, et prouver que la synchronisation fonctionne.

Personne ne prête attention à l'horloge d'un serveur tant qu'elle est juste. Quand elle dérive, ce n'est jamais l'horloge qui se manifeste, mais un certificat refusé, une source de paquets qu'apt n'accepte pas, une tâche cron qui part à la mauvaise heure et un fichier journal qu'on ne peut plus mettre en relation avec aucun autre.

Cet article approfondit l'étape 5 de la checklist pour un nouveau serveur root. Si vous y avez exécuté les deux commandes, vous avez fait le strict nécessaire. Il est question ici de tout ce qui va au-delà : le choix du service de temps, l'horloge matérielle, UTC face à l'heure locale, la preuve que la synchronisation fonctionne et les messages d'erreur qui vont avec.

Toutes les indications se rapportent à Debian 13 (trixie), Debian 12 (bookworm), Ubuntu 24.04 LTS et Ubuntu 22.04 LTS. Les commandes sont écrites pour une exécution en tant que root. Si vous travaillez avec un utilisateur normal, faites précéder chaque commande d'un sudo.

Ce qu'une horloge fausse casse réellement

Le dénominateur commun : aucun de ces messages ne parle de l'horloge.

  • Les certificats TLS. Chaque certificat possède une fenêtre de validité. Si l'heure système se situe avant, curl signale curl: (60) SSL certificate problem: certificate is not yet valid, si elle se situe après, certificate has expired. Chaque appel sortant est concerné.
  • apt. Les fichiers Release portent une date d'émission et une date d'expiration. Si l'horloge retarde, vous obtenez Release file for ... is not valid yet, si elle avance nettement, c'est is expired. Le serveur ne reçoit alors plus aucune mise à jour de sécurité, sans qu'aucun service ne tombe en panne.
  • Les journaux. Deux machines qui divergent de cinq minutes ne se lisent plus l'une avec l'autre, et c'est précisément là qu'on en a besoin : lors d'une intrusion ou d'une panne.
  • Les tâches cron et les timers systemd. cron calcule dans le fuseau horaire du système. Si vous changez ce fuseau plus tard, vous décalez chaque tâche. Si l'horloge saute, les tâches s'exécutent deux fois ou pas du tout. Le détail se trouve dans Configurer une tâche cron sous Linux.
  • Les sauvegardes. Presque toutes les sauvegardes nomment leurs dossiers d'après la date et suppriment selon l'ancienneté. Une horloge qui recule d'un jour écrase la sauvegarde de la veille.
  • Les mots de passe à usage unique basés sur le temps. TOTP travaille par fenêtres de 30 secondes, avec une tolérance limitée le plus souvent à une fenêtre de chaque côté. Si l'horloge du serveur s'écarte davantage, tout code pourtant correct est refusé. C'est le seul point de cette liste qui vous met réellement à la porte.

Avant toute modification : voie de retour et état des lieux

La voie de retour

Changer de fuseau horaire ne coupe aucune session SSH en cours, et activer la synchronisation est tout aussi inoffensif. Deux opérations de cet article ne le sont pas : une horloge qui fait un grand saut et le changement de service de temps. Un saut important vers l'arrière rend temporairement invalides des certificats pourtant valides et fait échouer les connexions par TOTP. Le changement de service de temps supprime l'ancien avant que le nouveau ne tourne : si l'installation s'interrompt entre les deux, le serveur n'a plus aucune synchronisation de l'heure, et cela ne se remarque que plusieurs jours plus tard.

Les serveurs root KVM et les serveurs dédiés de KernelHost n'ont ni IPMI ni iDRAC. L'accès qui fonctionne sans aucun service réseau dans le système invité, c'est la console VNC dans l'espace client. Elle est rattachée à la couche de virtualisation ou au raccordement lui-même, et une horloge fausse dans l'invité ne l'affecte pas. Connectez-vous-y une fois au préalable et vérifiez que vous connaissez bien le mot de passe root.

L'état actuel en quatre commandes

Notez ce qui est en vigueur aujourd'hui. Sans cette note, vous ne saurez pas plus tard si un écart est nouveau :

timedatectl
readlink -f /etc/localtime
date -u
systemctl is-active systemd-timesyncd chrony

Sur les sept lignes que produit timedatectl, trois comptent vraiment. Time zone donne le fuseau avec son abréviation et son décalage, par exemple Europe/Vienna (CEST, +0200). System clock synchronized indique si l'horloge a déjà été alignée une fois. NTP service connaît trois états, régulièrement confondus :

LigneSignificationCe qu'il faut faire
NTP service: activeUn service de temps est installé et tourne.Rien, mais vérifiez tout de même.
NTP service: inactiveUn service de temps est installé, mais il ne tourne pas.Démarrez le service, cherchez la cause dans le journal.
NTP service: n/aAucun service de temps n'est installé.Installez timesyncd ou chrony.

Dans le troisième cas, timedatectl show -p CanNTP --value renvoie no, et toute tentative d'activer la synchronisation se termine par Failed to set ntp: NTP not supported.

Fuseau horaire et synchronisation de l'heure sont deux choses distinctes

Le noyau ne tient qu'un seul compteur : les secondes écoulées depuis le 1er janvier 1970, comptées en UTC. Ce compteur est l'heure système, et il ne connaît aucun fuseau horaire, celui-ci n'étant qu'une question d'affichage. Deux conséquences en découlent. Changer de fuseau horaire ne déplace pas le moindre instant, date -u donne la même sortie avant et après. Et synchroniser l'horloge modifie le compteur, pas l'affichage : un fuseau mal réglé reste donc faux. Deux tâches, deux vérifications.

Étape 1 : définir le fuseau horaire

Les noms de fuseaux proviennent de la base IANA et se présentent presque toujours sous la forme Continent/Ville, en orthographe anglaise. Cherchez le nom plutôt que de le deviner :

timedatectl list-timezones | grep -i vienna
timedatectl set-timezone Europe/Vienna

Contrôle du résultat :

timedatectl show -p Timezone --value
readlink -f /etc/localtime
date +%Z

Vous attendez Europe/Vienna, le chemin /usr/share/zoneinfo/Europe/Vienna et une abréviation qui correspond à la saison, CEST en été et CET en hiver.

Trois pièges

Le fichier /etc/timezone ne fait pas foi. Debian 13 ne le livre plus, un cat /etc/timezone s'y termine par No such file or directory, et tzdata ne le ramène pas non plus. Sur les trois autres systèmes, il existe encore, mais partout, seul le lien symbolique /etc/localtime est déterminant.

Sans tzdata, il n'y a aucun fuseau. Sur les images allégées, en particulier chez Ubuntu, la base des fuseaux manque. Même un nom correctement orthographié échoue alors avec Failed to set time zone: Invalid or not installed time zone 'Europe/Vienna', et timedatectl list-timezones ne renvoie qu'une seule ligne. Une fois le paquet installé, il doit y en avoir plusieurs centaines :

DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata
timedatectl list-timezones | wc -l

Les services déjà lancés gardent l'ancien fuseau en mémoire. cron, les bases de données et les serveurs d'applications lisent le fuseau horaire au démarrage et continuent, après un changement, à journaliser dans l'ancien fuseau jusqu'à leur redémarrage.

Dans les environnements où systemd ne tourne pas, timedatectl n'existe pas. La méthode classique aboutit au même résultat :

ln -sf /usr/share/zoneinfo/Europe/Vienna /etc/localtime
dpkg-reconfigure -f noninteractive tzdata
readlink -f /etc/localtime

UTC ou heure locale : un choix délibéré

Beaucoup d'exploitants font tourner leurs serveurs en UTC, et ce n'est pas sans raison. UTC ignore l'heure d'été, donc aussi bien l'heure qui revient deux fois que celle qui manque : la nuit du changement, 02:30 en heure locale existe deux fois à l'automne et pas du tout au printemps, ce qui concerne chaque tâche planifiée dans cette fenêtre. À l'inverse, ce sont des humains qui lisent les journaux, et une fenêtre de maintenance « le dimanche à 03:00 » désigne bien l'heure locale. La règle utilisable : qui exploite plusieurs serveurs ou plusieurs sites prend UTC, qui pilote un serveur unique à l'heure du bureau prend l'heure locale. La seule erreur, c'est de ne pas savoir laquelle des deux s'applique.

timedatectl set-timezone Etc/UTC

Pour un simple coup d'œil, inutile de toucher au fuseau horaire du système : la variable TZ suffit et n'agit que sur cet appel :

TZ=Europe/Vienna date
TZ=Europe/Vienna journalctl -u nginx --since "today"

Étape 2 : choisir le service de temps

Pour Debian et Ubuntu, trois candidats sont disponibles, qui remplissent la même mission avec une ampleur très différente.

ServiceCe qu'il sait faireQuand il convient
systemd-timesyncdClient SNTP pur, interroge un serveur à la fois et bascule en cas de panneLe cas normal pour un serveur unique
chronyClient et serveur NTP complet, combine plusieurs sources, fournit avec chronyc un outil de diagnostic, gère NTSQuand vous voulez prouver la précision ou chercher une panne
ntpsecSuccesseur de l'implémentation de référence ntpdSystèmes existants et cas particuliers

Tous les trois annoncent le même rôle au système de paquets : Provides: time-daemon et en même temps Conflicts: time-daemon. Si vous en demandez deux dans une seule commande, vous essuyez un refus :

The following packages have unmet dependencies:
 chrony : Conflicts: time-daemon
 systemd-timesyncd : Conflicts: time-daemon
E: Unable to correct problems, you have held broken packages.

Si vous installez chrony alors que timesyncd tourne, ne passez pas à côté de la ligne The following packages will be REMOVED: systemd-timesyncd. C'est voulu : deux processus sur la même horloge sont pires qu'aucun. Vérifiez immédiatement après que le nouveau service tourne bien.

Deux noms de paquets issus de guides plus anciens ont fait leur temps : ntp et ntpdate. Sur Debian 12 et sur les deux versions d'Ubuntu, ce ne sont plus que des paquets de transition vers ntpsec, et sur Debian 13, apt-cache policy ntp répond simplement Candidate: (none).

Variante A : systemd-timesyncd

Sur les quatre systèmes, le paquet systemd recommande systemd-timesyncd | time-daemon. Une installation normale apporte donc le service, une image minimale sans paquets recommandés, non.

DEBIAN_FRONTEND=noninteractive apt-get install -y systemd-timesyncd
systemctl enable --now systemd-timesyncd

Le fichier /etc/systemd/timesyncd.conf livré avec le paquet ne contient que des valeurs par défaut mises en commentaire. Vos propres valeurs vont dans un fichier complémentaire, dont le répertoire n'existe pas d'origine :

mkdir -p /etc/systemd/timesyncd.conf.d
cat > /etc/systemd/timesyncd.conf.d/10-kernelhost.conf <<'EOF'
[Time]
NTP=0.at.pool.ntp.org 1.at.pool.ntp.org 2.at.pool.ntp.org
FallbackNTP=0.pool.ntp.org 1.pool.ntp.org
EOF
systemctl restart systemd-timesyncd

Sous NTP= figurent les serveurs qui sont interrogés. FallbackNTP= ne prend le relais que si aucun d'eux ne répond ; d'origine, on y trouve le pool Debian sur Debian et ntp.ubuntu.com sur Ubuntu.

Contrôle du résultat :

systemd-analyze cat-config systemd/timesyncd.conf
systemctl is-active systemd-timesyncd
timedatectl timesync-status

La première commande affiche la configuration assemblée : votre fichier complémentaire doit y apparaître avec son chemin complet. La troisième nomme le serveur utilisé, l'intervalle d'interrogation et le dernier décalage mesuré. Si elle répond plutôt Failed to query server: Connection timed out, c'est que timesyncd ne tourne pas. Ce message met 25 secondes à arriver.

Variante B : chrony

apt-get install -y chrony
systemctl enable --now chrony

Sur les quatre distributions, l'unit s'appelle chrony.service et porte en plus l'alias chronyd.service. Le fichier /etc/chrony/chrony.conf livré est déjà prérempli de façon utilisable : Debian interroge pool 2.debian.pool.ntp.org iburst, Ubuntu interroge ntp.ubuntu.com plus trois entrées du pool Ubuntu. Ne modifiez pas ce fichier. Il inclut, via confdir /etc/chrony/conf.d, un répertoire auquel les mises à jour de paquets ne touchent pas :

cat > /etc/chrony/conf.d/10-kernelhost.conf <<'EOF'
pool 0.at.pool.ntp.org iburst
EOF
systemctl restart chrony

Contrôle du résultat avec chronyc tracking, voici ce que cela donne sur un serveur qui tourne correctement :

Reference ID    : A29FC801 (time.cloudflare.com)
Stratum         : 4
Ref time (UTC)  : Thu Sep 03 17:53:29 2026
System time     : 0.000135970 seconds fast of NTP time
Last offset     : +0.000042723 seconds
RMS offset      : 0.000086483 seconds
Frequency       : 13.967 ppm fast
Residual freq   : +0.002 ppm
Skew            : 0.073 ppm
Root delay      : 0.008282715 seconds
Root dispersion : 0.000613841 seconds
Update interval : 1038.4 seconds
Leap status     : Normal

Au quotidien, trois lignes suffisent. System time est l'écart actuel, ici environ 136 microsecondes. Leap status doit indiquer Normal ; avec Not synchronised, chrony n'a pas encore de source utilisable. Stratum dit à quelle distance vous êtes d'une horloge de référence, 2 à 4 est normal. Le deuxième coup d'œil va aux sources elles-mêmes, avec chronyc -n sources :

MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^- 217.175.198.239               3  10   377   748   +114us[ +153us] +/-   19ms
^- 46.102.157.67                 2  10   377   558   +151us[ +192us] +/-   28ms
^* 162.159.200.1                 3  10   377   335   -251us[ -208us] +/- 4463us
^+ 152.53.132.244                2   9   377   231   +335us[ +335us] +/- 5626us

Les deux caractères tout à gauche constituent le véritable diagnostic. ^* marque la source sur laquelle l'horloge est réglée, ^+ une source qui entre dans le calcul, ^- une source qui n'est pas combinée, ^? une source injoignable et ^x une source contradictoire. La colonne Reach contient une valeur octale portant sur les huit dernières interrogations : 377 signifie que les huit ont reçu une réponse, 0 qu'aucune n'est arrivée.

À partir de la version 4, chrony gère Network Time Security, c'est-à-dire une heure authentifiée par TLS. Cela suppose deux choses que l'on oublie facilement : le paquet ca-certificates et un port TCP 4460 ouvert en sortie. Si les certificats racines manquent, l'alignement échoue avec Error in the certificate verification. The certificate is NOT trusted. The certificate issuer is unknown.

apt-get install -y ca-certificates
cat > /etc/chrony/conf.d/20-nts.conf <<'EOF'
server time.cloudflare.com iburst nts
EOF
systemctl restart chrony
chronyc authdata

L'horloge matérielle

À côté de l'heure système existe une deuxième horloge : l'horloge matérielle, en abrégé RTC. C'est elle qui fournit la première valeur au démarrage, bien avant qu'un service de temps ne tourne. Sur un serveur root KVM, il s'agit de l'horloge mise à disposition par la couche de virtualisation ; dans timedatectl, elle apparaît sur la ligne RTC time. Un seul réglage compte vraiment, celui de la dernière ligne de la sortie :

timedatectl set-local-rtc 0
timedatectl | grep "RTC in local TZ"

Si vous y lisez yes, l'horloge matérielle est interprétée comme de l'heure locale. C'est une concession aux machines qui démarrent aussi sous Windows, et cela n'a aucun sens sur un serveur. Le dégât se manifeste deux fois par an : lors du changement d'heure, une horloge matérielle tenue en heure locale reste ambiguë pendant une heure, et un redémarrage dans cette fenêtre peut faire démarrer le serveur avec une heure fausse d'exactement une heure.

Dans l'autre sens : grâce au réglage par défaut rtcsync, chrony réécrit régulièrement l'heure corrigée dans l'horloge matérielle, et cette ligne figure dans le chrony.conf livré par les quatre distributions. systemd-timesyncd ne connaît pas d'option équivalente. À la main, cela se fait avec hwclock --systohc. Sur Debian 12, Debian 13 et Ubuntu 24.04, la commande provient du paquet util-linux-extra ; si le shell répond hwclock: command not found, installez ce paquet. Sur Ubuntu 22.04, elle fait partie de util-linux.

Étape 3 : prouver que la synchronisation fonctionne

Qu'une commande se soit exécutée sans erreur ne prouve rien. Ces cinq vérifications, elles, prouvent quelque chose :

  1. L'état d'ensemble. timedatectl affiche System clock synchronized: yes et NTP service: active. Les deux lignes ensemble, pas l'une des deux.
  2. Le service lui-même. systemctl is-enabled chrony et systemctl is-active chrony répondent enabled et active, et de même pour timesyncd. enabled seul signifie uniquement qu'il démarrerait au prochain démarrage.
  3. Une source est réellement jointe. Avec chrony, chronyc -n sources doit contenir au moins une ligne marquée ^*, et la colonne Reach doit avoir quitté 0. Avec timesyncd, timedatectl timesync-status nomme un serveur précis.
  4. L'écart est faible. Sur la ligne System time, chronyc tracking devrait afficher des microsecondes ou des millisecondes. Des secondes entières signifient que la correction est encore en cours ou que quelque chose coince.
  5. Cela survit à un redémarrage. Redémarrez le serveur une fois, puis répétez les vérifications 1 à 4. C'est la seule vérification qui tranche définitivement la question.

La ligne à laquelle vous ne devez pas vous fier seule : System clock synchronized: yes reflète un indicateur du noyau, positionné par le processus qui a réglé l'horloge en dernier. Il ne disparaît pas quand le service de temps plante. Un serveur peut donc afficher cette ligne tout en tournant depuis des heures sans le moindre alignement.

Les services qui exigent impérativement une horloge juste au démarrage se placent avec After=time-sync.target. Pour que cette cible ne soit atteinte qu'après l'alignement, il faut en plus une unit d'attente : systemd-time-wait-sync.service avec timesyncd, chrony-wait.service avec chrony. Cette dernière est livrée par Debian 12, Debian 13 et Ubuntu 24.04, mais pas par Ubuntu 22.04. La structure d'une unit maison est décrite dans Créer un service systemd.

Pare-feu et réseau

NTP sort par le port UDP 123, et NTS y ajoute le port TCP 4460. Dans la configuration par défaut d'UFW, le trafic sortant est autorisé, il n'y a donc rien à faire. Si vous avez posé ufw default deny outgoing, vous devez ouvrir le port, faute de quoi l'horloge cesse d'être corrigée sans qu'aucun service n'écrive de message d'erreur :

ufw allow out 123/udp comment 'NTP'

Le reste au sujet du pare-feu se trouve dans Configurer le pare-feu UFW. Dans l'autre sens : un service de temps qui répond aux requêtes venues d'Internet est un amplificateur pour les attaques par réflexion. chrony et systemd-timesyncd ne répondent d'origine à personne, seule une ligne allow dans la configuration de chrony transforme le client en serveur. Ne la posez que restreinte à votre propre réseau. Le filtrage en amont, dans le centre de données maincubes à Francfort-sur-le-Main, intercepte ce genre de trafic, mais le meilleur amplificateur reste celui qui n'existe pas.

Quand l'horloge est très décalée

En temps normal, les services de temps ne corrigent pas par sauts, mais en accélérant ou en ralentissant très légèrement l'horloge. C'est pourquoi un écart d'une minute ne disparaît pas en une seconde, et c'est très bien ainsi : un saut vers l'arrière ferait apparaître deux fois les mêmes horodatages.

Pour les systèmes qui viennent de démarrer, le chrony.conf livré par les quatre distributions contient la ligne makestep 1 3 : elle autorise un vrai saut lorsque l'écart dépasse une seconde, et cela uniquement pour les trois premiers alignements. C'est exactement le cas d'une machine virtuelle clonée depuis une image ou restaurée depuis un snapshot. Si cela ne suffit pas, forcez le saut et attendez le résultat :

chronyc makestep
chronyc waitsync 10

Pour mesurer sans rien modifier, il y a l'option -Q : elle interroge les sources configurées, indique l'écart et se termine sans toucher à l'horloge. La ligne intéressante ressemble alors à System clock wrong by 0.000363 seconds (ignored) :

chronyd -Q -f /etc/chrony/chrony.conf

Ce qu'il ne faut pas faire, c'est régler l'horloge à la main avec date -s pendant qu'un service de temps tourne. timedatectl set-time le refuse d'ailleurs explicitement avec Failed to set time: Automatic time synchronization is enabled, car deux instances agiraient sinon en même temps sur la même horloge.

Erreurs fréquentes et solutions

Failed to set time zone: Invalid or not installed time zone 'Europe/Wien' : le nom de fuseau n'existe pas. La base IANA retient les noms de villes en anglais, on écrit donc Europe/Vienna, Europe/Zurich et Europe/Prague. Si le même message apparaît pour un nom correctement orthographié, c'est la base des fuseaux qui manque : la contre-épreuve est timedatectl list-timezones | wc -l, et s'il ne reste qu'une seule ligne, installez tzdata.

Failed to set ntp: NTP not supported : aucun service de temps n'est installé, et timedatectl show -p CanNTP --value renvoie alors no. L'option set-ntp ne pilote que les services inscrits sous /usr/lib/systemd/ntp-units.d/ : timesyncd avec 80-systemd-timesync.list, chrony avec 50-chrony.list.

timedatectl set-ntp true s'exécute sans erreur, et pourtant NTP service reste inactive : la commande signale seulement qu'elle a donné l'ordre à l'unit, pas que celle-ci tourne. La cause se lit dans le journal, par exemple avec journalctl -u systemd-timesyncd -n 20.

506 Cannot talk to daemon : chronyc n'atteint pas le service parce que chronyd ne tourne pas. systemctl status chrony en donne la raison. Le message est identique pour n'importe quelle sous-commande de chronyc.

chrony.service - chrony, an NTP client/server was skipped because of an unmet condition check (ConditionCapability=CAP_SYS_TIME). : le système n'a tout simplement pas le droit de régler l'horloge. Sur les VPS à base de conteneurs (LXC, OpenVZ), c'est le cas normal, l'heure y est imposée par le système hôte. Sur un serveur root KVM, l'invité a le droit de régler lui-même son horloge, et le message y constitue un véritable symptôme. Vu depuis timesyncd, le même cas se présente ainsi : systemd-timesyncd.service - Network Time Synchronization was skipped because of an unmet condition check (ConditionVirtualization=!container).

Release file for ... is not valid yet lors d'un apt update : l'horloge retarde. Corrigez d'abord l'heure, puis relancez apt update. À l'inverse, is expired indique une horloge qui avance, plus rarement un miroir périmé.

Failed to query server: Connection timed out lors d'un timedatectl timesync-status : timesyncd ne tourne pas, ou bien chrony l'a remplacé. Si chrony est le service actif, cette commande restera durablement sans réponse, et ce n'est pas une erreur. Le bon outil s'appelle alors chronyc tracking.

Les différences entre distributions en un coup d'œil

PointDebian 13Debian 12Ubuntu 24.04Ubuntu 22.04
Version de chrony4.6.14.34.54.2
Source dans chrony.confpool Debianpool Debianntp.ubuntu.com plus pool Ubuntuntp.ubuntu.com plus pool Ubuntu
/etc/timezonen'existe plusprésentprésentprésent
hwclock issu du paquetutil-linux-extrautil-linux-extrautil-linux-extrautil-linux
chrony-wait.serviceouiouiouinon
ntp et ntpdaten'existent pluspaquets de transitionpaquets de transitionpaquets de transition

Ce qui est identique partout, en revanche : le fuseau horaire ne dépend que du lien symbolique /etc/localtime, et un service de temps exclut tous les autres.

La version courte

Pour un serveur root fraîchement mis à disposition, qui doit tourner à l'heure locale et se contente du service par défaut :

DEBIAN_FRONTEND=noninteractive apt-get install -y systemd-timesyncd tzdata
timedatectl set-timezone Europe/Vienna
timedatectl set-local-rtc 0
systemctl enable --now systemd-timesyncd
timedatectl

À la fin, vous attendez Time zone: Europe/Vienna, System clock synchronized: yes, NTP service: active et RTC in local TZ: no. Si ces quatre lignes sont encore là après un redémarrage, l'horloge de ce serveur est réglée pour de bon.

Questions fréquentes

Qu'est-ce qui casse quand l'horloge d'un serveur est fausse ?
Ce n'est jamais l'horloge qui attire l'attention, mais l'une de ses conséquences. Chaque certificat TLS possède une fenêtre de validité : si l'heure système se situe avant, curl signale « curl: (60) SSL certificate problem: certificate is not yet valid », si elle se situe après, « certificate has expired ». apt rejette les fichiers Release avec « Release file for ... is not valid yet », et le serveur ne reçoit alors plus aucune mise à jour de sécurité, sans qu'aucun service ne tombe en panne. S'y ajoutent des journaux qu'on ne peut plus lire les uns avec les autres, des tâches cron qui partent à la mauvaise heure, des sauvegardes nommées d'après la date qui écrasent celle de la veille, ainsi que les mots de passe à usage unique basés sur le temps. TOTP travaille par fenêtres de 30 secondes, avec une tolérance limitée le plus souvent à une fenêtre de chaque côté : une horloge de serveur qui s'écarte davantage vous met donc réellement à la porte.
L'heure du serveur change-t-elle si je modifie le fuseau horaire ?
Non. Le noyau ne tient qu'un seul compteur, les secondes écoulées depuis le 1er janvier 1970 en UTC, et le fuseau horaire n'est qu'une question d'affichage. La commande date -u donne la même sortie avant et après le changement. À l'inverse, une synchronisation modifie le compteur et non l'affichage : un fuseau mal réglé reste donc faux. Ce sont deux tâches, avec deux vérifications. Notez en outre que cron, les bases de données et les serveurs d'applications lisent le fuseau horaire au démarrage et continuent à journaliser dans l'ancien fuseau jusqu'à leur redémarrage.
Pourquoi timedatectl signale-t-il « Failed to set time zone: Invalid or not installed time zone » ?
Il y a deux causes possibles. Soit le nom n'existe pas : la base IANA retient les noms de villes en anglais, on écrit donc Europe/Vienna et non Europe/Wien, de même Europe/Zurich et Europe/Prague. Soit la base des fuseaux manque, ce qui arrive sur les images allégées, en particulier chez Ubuntu. La contre-épreuve est timedatectl list-timezones | wc -l : s'il ne reste qu'une seule ligne, installez tzdata, après quoi il doit y en avoir plusieurs centaines. Pour le fuseau, seul compte d'ailleurs le lien symbolique /etc/localtime, et non le fichier /etc/timezone, que Debian 13 ne livre même plus.
systemd-timesyncd ou chrony : quel service de temps choisir ?
systemd-timesyncd est un client SNTP pur : il interroge un serveur à la fois et bascule si celui-ci tombe. C'est le cas normal pour un serveur unique. chrony est un client et serveur NTP complet, il combine plusieurs sources, fournit avec chronyc un outil de diagnostic et gère Network Time Security, c'est-à-dire une heure authentifiée par TLS. Prenez chrony si vous voulez prouver la précision ou chercher une panne. Les deux ensemble, ce n'est pas possible : chaque service de temps annonce au système de paquets « Provides: time-daemon » et en même temps « Conflicts: time-daemon ». L'installation de chrony supprime donc systemd-timesyncd, ce que montre la ligne « The following packages will be REMOVED: systemd-timesyncd ». Vérifiez immédiatement après que le nouveau service tourne bien.
timedatectl set-ntp échoue avec « Failed to set ntp: NTP not supported ». Qu'est-ce qui manque ?
Aucun service de temps n'est installé. Dans la sortie de timedatectl, la ligne NTP service affiche alors la valeur n/a, et timedatectl show -p CanNTP --value renvoie no. L'option set-ntp ne pilote que les services inscrits sous /usr/lib/systemd/ntp-units.d/ : timesyncd avec 80-systemd-timesync.list, chrony avec 50-chrony.list. Installez l'un des deux. À distinguer de NTP service: inactive, où un service est bien présent mais ne tourne pas, la cause se lisant alors dans le journal.
chrony ne démarre pas sur mon VPS et signale une condition non remplie. Est-ce une panne ?
Le journal contient alors « was skipped because of an unmet condition check (ConditionCapability=CAP_SYS_TIME) », donc le système n'a tout simplement pas le droit de régler l'horloge. Sur les VPS à base de conteneurs (LXC, OpenVZ), c'est le cas normal, l'heure y est imposée par le système hôte. Sur un serveur root KVM, l'invité a le droit de régler lui-même son horloge, et le message y constitue un véritable symptôme. Vu depuis timesyncd, le même cas se présente avec la condition ConditionVirtualization=!container.
Comment prouver que la synchronisation de l'heure fonctionne vraiment ?
La ligne System clock synchronized: yes ne suffit pas à elle seule. Elle reflète un indicateur du noyau positionné par le processus qui a réglé l'horloge en dernier, et il ne disparaît pas quand le service de temps plante. Vérifiez donc cinq choses : que NTP service: active figure à côté, que systemctl is-enabled et is-active répondent enabled et active pour le service, qu'une source est réellement jointe (avec chrony une ligne marquée ^* dans chronyc -n sources et une colonne Reach différente de 0, avec timesyncd un serveur précis dans timedatectl timesync-status), que chronyc tracking affiche des microsecondes ou des millisecondes sur la ligne System time, et que tout cela survit à un redémarrage. Seule la dernière vérification tranche définitivement la question.
Le serveur doit-il tourner en UTC ou à l'heure locale ?
Qui exploite plusieurs serveurs ou plusieurs sites prend UTC, qui pilote un serveur unique à l'heure du bureau prend l'heure locale. En faveur d'UTC : il ignore l'heure d'été, alors que la nuit du changement, 02:30 en heure locale existe deux fois à l'automne et pas du tout au printemps, ce qui concerne chaque tâche planifiée dans cette fenêtre. Contre lui : ce sont des humains qui lisent les journaux, et une fenêtre de maintenance le dimanche à 03:00 désigne bien l'heure locale. La seule erreur, c'est de ne pas savoir laquelle des deux s'applique. Pour un simple coup d'œil, inutile de toucher au fuseau horaire du système, TZ=Europe/Vienna date n'agit que sur cet appel. Indépendamment de ce choix, l'horloge matérielle doit être en UTC : timedatectl set-local-rtc 0, et la sortie doit indiquer RTC in local TZ: no.

Fuseau horaire NTP timedatectl chrony systemd-timesyncd Linux Debian Ubuntu