Zeitzone und Zeitsynchronisation auf einem Linux-Server einrichten

Veröffentlicht am 16 Min. Lesezeit

Eine falsche Serveruhr meldet sich nie als Uhr, sondern als abgelehntes Zertifikat, als Paketquelle, die apt nicht annimmt, oder als Cronjob zur falschen Stunde. Wie Sie Zeitzone und Zeitdienst richtig setzen und nachweisen, dass die Synchronisation läuft.

Die Uhr eines Servers beachtet niemand, solange sie stimmt. Geht sie falsch, meldet sich nie die Uhr, sondern ein abgelehntes Zertifikat, eine Paketquelle, die apt nicht annimmt, ein Cronjob zur falschen Stunde und eine Protokolldatei, die sich mit keiner anderen mehr in Beziehung setzen lässt.

Dieser Beitrag vertieft Schritt 5 der Checkliste für einen neuen Rootserver. Wer dort die zwei Befehle abgearbeitet hat, hat die Pflicht erfüllt. Hier geht es um alles darüber hinaus: die Wahl des Zeitdienstes, die Hardware-Uhr, UTC gegen Ortszeit, den Nachweis der Synchronisation und die Fehlermeldungen dazu.

Alle Angaben beziehen sich auf Debian 13 (trixie), Debian 12 (bookworm), Ubuntu 24.04 LTS und Ubuntu 22.04 LTS. Die Befehle sind für den Betrieb als root geschrieben. Wenn Sie als normaler Benutzer arbeiten, stellen Sie jedem Befehl sudo voran.

Was eine falsche Uhr tatsächlich kaputt macht

Der gemeinsame Nenner: Keine dieser Meldungen spricht von der Uhr.

  • TLS-Zertifikate. Jedes Zertifikat hat ein Gültigkeitsfenster. Liegt die Systemzeit davor, meldet curl curl: (60) SSL certificate problem: certificate is not yet valid, liegt sie dahinter, certificate has expired. Betroffen ist jeder ausgehende Aufruf.
  • apt. Release-Dateien tragen ein Ausstellungs- und ein Ablaufdatum. Geht die Uhr nach, kommt Release file for ... is not valid yet, geht sie deutlich vor, entsprechend is expired. Der Server bekommt dann keine Sicherheitsaktualisierungen mehr, ohne dass ein Dienst ausfällt.
  • Protokolle. Zwei Maschinen mit fünf Minuten Abweichung lassen sich nicht mehr gegeneinander lesen, und genau dann braucht man es: bei einem Einbruch oder einem Ausfall.
  • Cronjobs und systemd-Timer. cron rechnet in der Systemzeitzone. Wer die Zone später umstellt, verschiebt jeden Job. Springt die Uhr, laufen Jobs doppelt oder gar nicht. Ausführlich in Cronjob einrichten.
  • Sicherungen. Fast jede Sicherung benennt ihre Ordner nach dem Datum und löscht nach Alter. Eine Uhr, die einen Tag zurückspringt, überschreibt die Sicherung von gestern.
  • Zeitbasierte Einmalpasswörter. TOTP rechnet in 30-Sekunden-Fenstern mit einer Toleranz von meist einem Fenster nach jeder Seite. Weicht die Serveruhr weiter ab, wird jeder korrekte Code abgelehnt. Das ist der einzige Punkt dieser Liste, der Sie tatsächlich aussperrt.

Bevor Sie etwas ändern: Rückweg und Bestandsaufnahme

Der Rückweg

Eine Änderung an der Zeitzone kappt keine laufende SSH-Sitzung, und die Synchronisation einzuschalten ist ebenfalls harmlos. Zwei Dinge in diesem Artikel sind es nicht: eine Uhr, die weit springt, und der Wechsel des Zeitdienstes. Ein großer Sprung nach hinten macht gültige Zertifikate vorübergehend ungültig und wirft TOTP-Anmeldungen aus dem Fenster. Der Wechsel des Zeitdienstes entfernt den alten, bevor der neue läuft: Bricht die Installation dazwischen ab, hat der Server gar keine Zeitsynchronisation mehr, und das fällt erst Tage später auf.

KVM-Rootserver und Dedicated Server von KernelHost haben kein IPMI und kein iDRAC. Der Zugang, der ohne Netzwerkdienste im Gastsystem funktioniert, ist die VNC-Konsole im Kundenbereich. Sie hängt an der Virtualisierungsschicht beziehungsweise am Anschluss selbst und ist von einer falschen Uhr im Gast nicht betroffen. Melden Sie sich dort einmal vorher an und prüfen Sie, ob Sie das root-Passwort kennen.

Der Ist-Zustand in vier Befehlen

Notieren Sie, was jetzt gilt. Ohne diese Notiz wissen Sie später nicht, ob eine Abweichung neu ist:

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

Von den sieben Zeilen aus timedatectl zählen drei. Time zone nennt die Zone samt Kürzel und Versatz, etwa Europe/Vienna (CEST, +0200). System clock synchronized sagt, ob die Uhr jemals abgeglichen wurde. NTP service kennt drei Zustände, die regelmäßig verwechselt werden:

ZeileBedeutungWas zu tun ist
NTP service: activeEin Zeitdienst ist installiert und läuft.Nichts, aber trotzdem gegenprüfen.
NTP service: inactiveEin Zeitdienst ist installiert, läuft aber nicht.Dienst starten, Ursache im Journal suchen.
NTP service: n/aEs ist überhaupt kein Zeitdienst installiert.timesyncd oder chrony nachinstallieren.

Im dritten Fall liefert timedatectl show -p CanNTP --value ein no, und jeder Versuch, die Synchronisation einzuschalten, endet mit Failed to set ntp: NTP not supported.

Zeitzone und Zeitsynchronisation sind zwei verschiedene Dinge

Der Kernel führt genau einen Zähler: Sekunden seit dem 1. Januar 1970, gerechnet in UTC. Dieser Zähler ist die Systemzeit, und er kennt keine Zeitzone, die ist nur eine Frage der Darstellung. Daraus folgen zwei Dinge: Die Zeitzone zu ändern verschiebt keinen einzigen Augenblick, date -u liefert davor und danach dieselbe Ausgabe. Und die Uhr zu synchronisieren ändert den Zähler, nicht die Darstellung, eine falsch gesetzte Zone bleibt also falsch. Zwei Aufgaben, zwei Prüfungen.

Schritt 1: Die Zeitzone setzen

Zonennamen stammen aus der IANA-Datenbank und lauten fast immer Kontinent/Stadt, in englischer Schreibweise. Suchen Sie den Namen, statt ihn zu raten:

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

Erfolgskontrolle:

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

Erwartet werden Europe/Vienna, der Pfad /usr/share/zoneinfo/Europe/Vienna und ein Kürzel, das zur Jahreszeit passt, im Sommer CEST und im Winter CET.

Drei Fallstricke

Die Datei /etc/timezone ist nicht maßgeblich. Debian 13 liefert sie nicht mehr aus, dort endet ein cat /etc/timezone mit No such file or directory, und auch tzdata bringt sie nicht zurück. Auf den anderen drei Systemen existiert sie noch, entscheidend ist aber überall allein der Symlink /etc/localtime.

Ohne tzdata gibt es keine Zonen. Auf schlanken Abbildern, besonders bei Ubuntu, fehlt die Zonendatenbank. Dann scheitert selbst ein korrekt geschriebener Name mit Failed to set time zone: Invalid or not installed time zone 'Europe/Vienna', und timedatectl list-timezones gibt nur eine Zeile aus. Nach der Abhilfe müssen es einige hundert sein:

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

Laufende Dienste merken sich die alte Zone. cron, Datenbanken und Anwendungsserver lesen die Zeitzone beim Start und protokollieren nach einer Umstellung weiter in der alten Zone, bis sie neu gestartet werden.

In Umgebungen ohne laufendes systemd gibt es timedatectl nicht. Der klassische Weg führt zum selben Ergebnis:

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

UTC oder Ortszeit: eine bewusste Entscheidung

Viele Betreiber lassen Server auf UTC laufen, und dafür gibt es gute Gründe. UTC kennt keine Sommerzeit, also auch keine Stunde, die zweimal vorkommt, und keine, die fehlt: In der Nacht der Umstellung existiert 02:30 Ortszeit im Herbst doppelt und im Frühjahr gar nicht, was jeden Job in diesem Fenster betrifft. Dagegen steht, dass Menschen die Protokolle lesen und ein Wartungsfenster "sonntags 03:00" die Ortszeit meint. Die brauchbare Regel: Wer mehrere Server oder Standorte betreibt, nimmt UTC, wer einen einzelnen Server nach der Bürouhr fährt, nimmt die Ortszeit. Falsch ist nur, es nicht zu wissen.

timedatectl set-timezone Etc/UTC

Für einen einzelnen Blick muss man die Systemzeitzone nicht anfassen, die Variable TZ genügt und wirkt nur auf diesen Aufruf:

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

Schritt 2: Den Zeitdienst wählen

Für Debian und Ubuntu stehen drei Kandidaten bereit, die dieselbe Aufgabe mit sehr unterschiedlichem Umfang lösen.

DienstWas er kannWann er passt
systemd-timesyncdReiner Client nach SNTP, fragt einen Server zur Zeit und wechselt bei AusfallDer Normalfall für einen einzelnen Server
chronyVollwertiger NTP-Client und -Server, kombiniert mehrere Quellen, bringt mit chronyc ein Diagnosewerkzeug mit, beherrscht NTSWenn Sie Genauigkeit nachweisen oder Fehler suchen wollen
ntpsecNachfolger der Referenzimplementierung ntpdBestandssysteme und Sonderfälle

Alle drei melden dem Paketsystem dieselbe Rolle: Provides: time-daemon und zugleich Conflicts: time-daemon. Wer zwei davon in einem Befehl anfordert, bekommt eine Absage:

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.

Wer chrony installiert, während timesyncd läuft, sollte die Zeile The following packages will be REMOVED: systemd-timesyncd nicht überlesen. Das ist gewollt, zwei Prozesse an derselben Uhr sind schlimmer als keiner. Prüfen Sie danach sofort, ob der neue Dienst läuft.

Zwei Paketnamen aus älteren Anleitungen sind erledigt: ntp und ntpdate. Auf Debian 12 und beiden Ubuntu-Versionen sind es nur noch Übergangspakete auf ntpsec, auf Debian 13 meldet apt-cache policy ntp schlicht Candidate: (none).

Variante A: systemd-timesyncd

Das Paket systemd empfiehlt auf allen vier Systemen systemd-timesyncd | time-daemon. Eine normale Installation bringt den Dienst also mit, ein Minimalabbild ohne Empfehlungen nicht.

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

Die mitgelieferte /etc/systemd/timesyncd.conf enthält ausschließlich auskommentierte Vorgaben. Eigene Werte gehören in eine Ergänzungsdatei, deren Verzeichnis ab Werk nicht existiert:

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

Unter NTP= stehen die Server, die gefragt werden. FallbackNTP= greift nur, wenn keiner davon antwortet, ab Werk steht dort auf Debian der Debian-Pool und auf Ubuntu ntp.ubuntu.com.

Erfolgskontrolle:

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

Der erste Befehl zeigt die zusammengesetzte Konfiguration, Ihre Ergänzungsdatei muss darin mit vollem Pfad auftauchen. Der dritte nennt den verwendeten Server, das Abfrageintervall und den zuletzt gemessenen Versatz. Antwortet er stattdessen mit Failed to query server: Connection timed out, läuft timesyncd nicht. Diese Meldung braucht 25 Sekunden.

Variante B: chrony

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

Die Unit heißt auf allen vier Distributionen chrony.service und trägt zusätzlich den Aliasnamen chronyd.service. Die mitgelieferte /etc/chrony/chrony.conf ist bereits brauchbar vorbelegt: Debian fragt pool 2.debian.pool.ntp.org iburst, Ubuntu fragt ntp.ubuntu.com plus drei Einträge aus dem Ubuntu-Pool. Ändern Sie diese Datei nicht. Sie bindet über confdir /etc/chrony/conf.d ein Verzeichnis ein, das Paketaktualisierungen unangetastet lassen:

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

Erfolgskontrolle mit chronyc tracking, so sieht es auf einem sauber laufenden Server aus:

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

Drei Zeilen genügen im Alltag. System time ist die aktuelle Abweichung, hier rund 136 Mikrosekunden. Leap status muss Normal lauten, bei Not synchronised hat chrony noch keine brauchbare Quelle. Stratum sagt, wie weit Sie von einer Referenzuhr entfernt sind, 2 bis 4 ist normal. Der zweite Blick gilt den Quellen selbst, mit 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

Die beiden Zeichen ganz links sind der eigentliche Befund. ^* markiert die Quelle, nach der die Uhr gestellt wird, ^+ eine, die mit einfließt, ^- eine, die nicht kombiniert wird, ^? eine unerreichbare und ^x eine widersprüchliche. In der Spalte Reach steht ein Oktalwert über die letzten acht Abfragen: 377 heißt, alle acht wurden beantwortet, 0 heißt, keine kam an.

Ab Version 4 beherrscht chrony Network Time Security, also authentifizierte Zeit über TLS. Das setzt zwei leicht übersehene Dinge voraus: das Paket ca-certificates und einen ausgehenden TCP-Port 4460. Fehlen die Wurzelzertifikate, scheitert der Abgleich mit 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

Die Hardware-Uhr

Neben der Systemzeit gibt es eine zweite Uhr: die Hardware-Uhr, kurz RTC. Sie liefert beim Start den ersten Zeitwert, lange bevor ein Zeitdienst läuft. Auf einem KVM-Rootserver ist das die von der Virtualisierungsschicht bereitgestellte Uhr, in timedatectl steht sie in der Zeile RTC time. Wichtig ist genau eine Einstellung, die letzte Zeile der Ausgabe:

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

Steht dort yes, wird die Hardware-Uhr als Ortszeit gelesen. Das ist ein Zugeständnis an Rechner, die parallel Windows starten, und auf einem Server sinnlos. Der Schaden zeigt sich zweimal im Jahr: Zur Zeitumstellung ist eine als Ortszeit geführte Hardware-Uhr für eine Stunde nicht eindeutig, und ein Neustart in diesem Fenster kann den Server mit einer um eine Stunde falschen Zeit hochfahren.

In die andere Richtung gilt: chrony schreibt die korrigierte Zeit über die Voreinstellung rtcsync regelmäßig in die Hardware-Uhr zurück, die Zeile steht in der mitgelieferten chrony.conf aller vier Distributionen. systemd-timesyncd kennt keine solche Option. Von Hand geht es mit hwclock --systohc. Der Befehl stammt auf Debian 12, Debian 13 und Ubuntu 24.04 aus dem Paket util-linux-extra; meldet die Shell hwclock: command not found, installieren Sie es nach. Auf Ubuntu 22.04 gehört er zu util-linux.

Schritt 3: Nachweisen, dass die Synchronisation läuft

Dass ein Befehl ohne Fehler durchlief, ist kein Nachweis. Diese fünf Prüfungen sind einer:

  1. Der Gesamtzustand. timedatectl zeigt System clock synchronized: yes und NTP service: active. Beide Zeilen zusammen, nicht eine davon.
  2. Der Dienst selbst. systemctl is-enabled chrony und systemctl is-active chrony antworten mit enabled und active, bei timesyncd entsprechend. enabled allein heißt nur, dass er beim nächsten Start liefe.
  3. Eine Quelle wird wirklich erreicht. Bei chrony muss in chronyc -n sources mindestens eine Zeile mit ^* stehen und die Spalte Reach von 0 weg sein. Bei timesyncd nennt timedatectl timesync-status einen konkreten Server.
  4. Der Versatz ist klein. chronyc tracking sollte bei System time Mikro- oder Millisekunden zeigen. Ganze Sekunden bedeuten, dass die Korrektur noch läuft oder etwas klemmt.
  5. Es übersteht einen Neustart. Server einmal neu starten, Prüfung 1 bis 4 wiederholen. Das ist die einzige Prüfung, die die Frage abschließend beantwortet.

Die Zeile, der Sie nicht allein trauen dürfen: System clock synchronized: yes spiegelt ein Kennzeichen im Kernel wider, das derjenige Prozess gesetzt hat, der die Uhr zuletzt gestellt hat. Es verschwindet nicht, wenn der Zeitdienst abstürzt. Ein Server kann diese Zeile also zeigen und trotzdem seit Stunden ohne Abgleich laufen.

Dienste, die beim Start zwingend eine richtige Uhr brauchen, ordnen Sie über After=time-sync.target ein. Damit dieses Ziel erst nach dem Abgleich erreicht wird, braucht es zusätzlich eine wartende Unit: systemd-time-wait-sync.service bei timesyncd, chrony-wait.service bei chrony. Letztere liefern Debian 12, Debian 13 und Ubuntu 24.04 mit, Ubuntu 22.04 nicht. Wie eine eigene Unit aufgebaut ist, steht in systemd-Service erstellen.

Firewall und Netz

NTP läuft über UDP-Port 123 nach außen, für NTS kommt TCP 4460 dazu. In der Voreinstellung von UFW ist ausgehender Verkehr erlaubt, es ist also nichts zu tun. Wer ufw default deny outgoing gesetzt hat, muss den Port freigeben, sonst bleibt die Uhr stehen, ohne dass ein Dienst eine Fehlermeldung schreibt:

ufw allow out 123/udp comment 'NTP'

Der Rest zur Firewall steht in UFW-Firewall einrichten. In der Gegenrichtung gilt: Ein Zeitdienst, der Anfragen aus dem Internet beantwortet, ist ein Verstärker für Reflexionsangriffe. chrony und systemd-timesyncd antworten ab Werk niemandem, erst eine allow-Zeile in der chrony-Konfiguration macht aus dem Client einen Server. Setzen Sie sie nur eingegrenzt auf Ihr eigenes Netz. Die vorgelagerte Filterung im Rechenzentrum maincubes in Frankfurt am Main fängt solchen Verkehr ab, der beste Verstärker bleibt aber der, den es gar nicht gibt.

Wenn die Uhr weit daneben liegt

Zeitdienste korrigieren im Normalfall nicht durch Springen, sondern durch minimales Beschleunigen oder Bremsen der Uhr. Deshalb verschwindet eine Abweichung von einer Minute nicht in einer Sekunde, und das ist richtig so: Ein Sprung nach hinten lässt Zeitstempel doppelt vorkommen.

Für frisch gestartete Systeme steht in der mitgelieferten chrony.conf aller vier Distributionen die Zeile makestep 1 3: Sie erlaubt einen echten Sprung bei einem Versatz über einer Sekunde, und das nur für die ersten drei Abgleiche. Genau dieser Fall tritt bei einer virtuellen Maschine ein, die aus einem Abbild geklont oder aus einem Schnappschuss zurückgeholt wurde. Reicht das nicht, erzwingen Sie den Sprung und warten auf das Ergebnis:

chronyc makestep
chronyc waitsync 10

Messen, ohne etwas zu verändern, geht mit dem Schalter -Q: Er fragt die konfigurierten Quellen ab, meldet die Abweichung und beendet sich, ohne die Uhr anzufassen. Die interessante Zeile lautet dann etwa System clock wrong by 0.000363 seconds (ignored):

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

Was Sie nicht tun sollten, ist die Uhr mit date -s von Hand zu stellen, während ein Zeitdienst läuft. timedatectl set-time verweigert das ausdrücklich mit Failed to set time: Automatic time synchronization is enabled, weil sonst zwei Instanzen gleichzeitig an derselben Uhr drehen würden.

Häufige Fehler und Lösungen

Failed to set time zone: Invalid or not installed time zone 'Europe/Wien': Der Zonenname existiert nicht. Die IANA-Datenbank führt englische Städtenamen, es heißt also Europe/Vienna, Europe/Zurich und Europe/Prague. Kommt dieselbe Meldung für einen richtig geschriebenen Namen, fehlt die Zonendatenbank: Gegenprobe ist timedatectl list-timezones | wc -l, bleibt eine einzige Zeile übrig, installieren Sie tzdata nach.

Failed to set ntp: NTP not supported: Es ist gar kein Zeitdienst installiert, timedatectl show -p CanNTP --value liefert dann no. Der Schalter set-ntp steuert nur Dienste, die sich unter /usr/lib/systemd/ntp-units.d/ eingetragen haben: timesyncd mit 80-systemd-timesync.list, chrony mit 50-chrony.list.

timedatectl set-ntp true läuft ohne Fehler durch, NTP service bleibt trotzdem inactive: Der Befehl meldet nur, dass er die Unit angewiesen hat, nicht, dass sie läuft. Die Ursache steht im Journal, etwa mit journalctl -u systemd-timesyncd -n 20.

506 Cannot talk to daemon: chronyc erreicht den Dienst nicht, weil chronyd nicht läuft. systemctl status chrony nennt den Grund. Die Meldung kommt bei jedem chronyc-Unterbefehl gleich.

chrony.service - chrony, an NTP client/server was skipped because of an unmet condition check (ConditionCapability=CAP_SYS_TIME).: Das System darf die Uhr gar nicht stellen. Bei VPS auf Container-Basis (LXC, OpenVZ) ist das der Normalfall, dort gibt das Wirtssystem die Zeit vor. Auf einem KVM-Rootserver darf der Gast seine Uhr selbst stellen, dort ist die Meldung ein echter Befund. Aus Sicht von timesyncd sieht derselbe Fall so aus: systemd-timesyncd.service - Network Time Synchronization was skipped because of an unmet condition check (ConditionVirtualization=!container).

Release file for ... is not valid yet bei apt update: Die Uhr geht nach. Zuerst die Zeit richten, danach apt update wiederholen. Umgekehrt weist is expired auf eine vorgehende Uhr hin, seltener auf eine veraltete Spiegelquelle.

Failed to query server: Connection timed out bei timedatectl timesync-status: timesyncd läuft nicht, oder chrony hat es ersetzt. Ist chrony der aktive Dienst, bleibt dieser Befehl dauerhaft ohne Antwort, und das ist kein Fehler. Das richtige Werkzeug heißt dann chronyc tracking.

Distributionsunterschiede auf einen Blick

PunktDebian 13Debian 12Ubuntu 24.04Ubuntu 22.04
chrony-Version4.6.14.34.54.2
Quelle in chrony.confDebian-PoolDebian-Poolntp.ubuntu.com plus Ubuntu-Poolntp.ubuntu.com plus Ubuntu-Pool
/etc/timezonenicht mehr vorhandenvorhandenvorhandenvorhanden
hwclock aus Paketutil-linux-extrautil-linux-extrautil-linux-extrautil-linux
chrony-wait.servicejajajanein
ntp und ntpdategibt es nicht mehrÜbergangspaketeÜbergangspaketeÜbergangspakete

Überall gleich ist dagegen: Die Zeitzone hängt allein am Symlink /etc/localtime, und ein Zeitdienst schließt jeden anderen aus.

Die Kurzfassung

Für einen frisch bereitgestellten Rootserver, der auf Ortszeit laufen soll und mit dem Standarddienst auskommt:

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

Erwartet werden am Ende Time zone: Europe/Vienna, System clock synchronized: yes, NTP service: active und RTC in local TZ: no. Stehen diese vier Zeilen auch nach einem Neustart so da, ist die Uhr dieses Servers erledigt.

Häufige Fragen

Was geht kaputt, wenn die Uhr eines Servers falsch geht?
Auffällig wird nie die Uhr, sondern eine Folge davon. Jedes TLS-Zertifikat hat ein Gültigkeitsfenster: Liegt die Systemzeit davor, meldet curl "curl: (60) SSL certificate problem: certificate is not yet valid", liegt sie dahinter, "certificate has expired". apt lehnt Release-Dateien mit "Release file for ... is not valid yet" ab, der Server bekommt dann keine Sicherheitsaktualisierungen mehr, ohne dass ein Dienst ausfällt. Dazu kommen Protokolle, die sich nicht mehr gegeneinander lesen lassen, Cronjobs zur falschen Stunde, Sicherungen, die nach dem Datum benannt sind und die von gestern überschreiben, sowie zeitbasierte Einmalpasswörter. TOTP rechnet in 30-Sekunden-Fenstern mit einer Toleranz von meist einem Fenster nach jeder Seite, eine weiter abweichende Serveruhr sperrt Sie also tatsächlich aus.
Ändert sich die Uhrzeit des Servers, wenn ich die Zeitzone umstelle?
Nein. Der Kernel führt genau einen Zähler, Sekunden seit dem 1. Januar 1970 in UTC, und die Zeitzone ist allein eine Frage der Darstellung. Der Befehl date -u liefert vor und nach der Umstellung dieselbe Ausgabe. Umgekehrt gilt: Eine Synchronisation ändert den Zähler, nicht die Darstellung, eine falsch gesetzte Zone bleibt also falsch. Es sind zwei Aufgaben mit zwei Prüfungen. Beachten Sie außerdem, dass cron, Datenbanken und Anwendungsserver die Zeitzone beim Start lesen und bis zu ihrem Neustart weiter in der alten Zone protokollieren.
Warum meldet timedatectl "Failed to set time zone: Invalid or not installed time zone"?
Dafür gibt es zwei Ursachen. Entweder existiert der Name nicht: Die IANA-Datenbank führt englische Städtenamen, es heißt also Europe/Vienna und nicht Europe/Wien, ebenso Europe/Zurich und Europe/Prague. Oder die Zonendatenbank fehlt, was auf schlanken Abbildern vorkommt, besonders bei Ubuntu. Die Gegenprobe ist timedatectl list-timezones | wc -l: Bleibt eine einzige Zeile übrig, installieren Sie tzdata nach, danach müssen es einige hundert sein. Maßgeblich für die Zone ist übrigens allein der Symlink /etc/localtime, nicht die Datei /etc/timezone, die Debian 13 gar nicht mehr ausliefert.
systemd-timesyncd oder chrony: welchen Zeitdienst soll ich nehmen?
systemd-timesyncd ist ein reiner Client nach SNTP, fragt einen Server zur Zeit und wechselt bei dessen Ausfall. Das ist der Normalfall für einen einzelnen Server. chrony ist ein vollwertiger NTP-Client und -Server, kombiniert mehrere Quellen, bringt mit chronyc ein Diagnosewerkzeug mit und beherrscht Network Time Security, also authentifizierte Zeit über TLS. Nehmen Sie chrony, wenn Sie Genauigkeit nachweisen oder Fehler suchen wollen. Beide zusammen geht nicht: Jeder Zeitdienst meldet dem Paketsystem "Provides: time-daemon" und zugleich "Conflicts: time-daemon". Die Installation von chrony entfernt deshalb systemd-timesyncd, sichtbar an der Zeile "The following packages will be REMOVED: systemd-timesyncd". Prüfen Sie danach sofort, ob der neue Dienst läuft.
timedatectl set-ntp scheitert mit "Failed to set ntp: NTP not supported". Was fehlt?
Es ist überhaupt kein Zeitdienst installiert. In der Ausgabe von timedatectl steht dann in der Zeile NTP service der Wert n/a, und timedatectl show -p CanNTP --value liefert no. Der Schalter set-ntp steuert nur Dienste, die sich unter /usr/lib/systemd/ntp-units.d/ eingetragen haben: timesyncd mit 80-systemd-timesync.list, chrony mit 50-chrony.list. Installieren Sie einen der beiden nach. Davon zu unterscheiden ist NTP service: inactive, dort ist ein Dienst vorhanden, läuft aber nicht, und die Ursache steht im Journal.
chrony startet auf meinem VPS nicht und meldet eine nicht erfüllte Bedingung. Ist das ein Fehler?
Im Journal steht dann "was skipped because of an unmet condition check (ConditionCapability=CAP_SYS_TIME)", das System darf die Uhr also gar nicht stellen. Bei VPS auf Container-Basis (LXC, OpenVZ) ist das der Normalfall, dort gibt das Wirtssystem die Zeit vor. Auf einem KVM-Rootserver darf der Gast seine Uhr selbst stellen, dort ist die Meldung ein echter Befund. Aus Sicht von timesyncd sieht derselbe Fall mit der Bedingung ConditionVirtualization=!container aus.
Wie weise ich nach, dass die Zeitsynchronisation wirklich läuft?
Die Zeile System clock synchronized: yes genügt allein nicht. Sie spiegelt ein Kennzeichen im Kernel wider, das derjenige Prozess gesetzt hat, der die Uhr zuletzt gestellt hat, und es verschwindet nicht, wenn der Zeitdienst abstürzt. Prüfen Sie deshalb fünf Dinge: dass daneben NTP service: active steht, dass systemctl is-enabled und is-active für den Dienst enabled und active melden, dass eine Quelle wirklich erreicht wird (bei chrony eine Zeile mit ^* in chronyc -n sources und eine Spalte Reach ungleich 0, bei timesyncd ein konkreter Server in timedatectl timesync-status), dass chronyc tracking bei System time Mikro- oder Millisekunden zeigt, und dass alles einen Neustart übersteht. Nur die letzte Prüfung beantwortet die Frage abschließend.
Soll der Server auf UTC oder auf Ortszeit laufen?
Wer mehrere Server oder Standorte betreibt, nimmt UTC, wer einen einzelnen Server nach der Bürouhr fährt, nimmt die Ortszeit. Für UTC spricht, dass es keine Sommerzeit kennt: In der Umstellungsnacht gibt es 02:30 Ortszeit im Herbst zweimal und im Frühjahr gar nicht, was jeden Job in diesem Fenster betrifft. Dagegen steht, dass Menschen die Protokolle lesen und ein Wartungsfenster sonntags 03:00 die Ortszeit meint. Falsch ist nur, es nicht zu wissen. Für einen einzelnen Blick müssen Sie die Systemzeitzone nicht anfassen, TZ=Europe/Vienna date wirkt nur auf diesen Aufruf. Unabhängig von dieser Entscheidung gehört die Hardware-Uhr auf UTC: timedatectl set-local-rtc 0, in der Ausgabe muss RTC in local TZ: no stehen.

Zeitzone NTP timedatectl chrony systemd-timesyncd Linux Debian Ubuntu