Mal wieder Freitag? Könnte man meinen, aber nein erst Dienstag. Das Monitoring meldet ntp wäre nicht synchron. Die Uhrzeit geht aber richtig. Komisch. Also Zeit der Sache mit der Zeit auf den Grund zu gehen.

Aber egal, hier kommt es gar nicht drauf an ob die Uhrzeit jetzt richtig geht oder nicht: Der Sache sollte man auf den Grund gehen. Hier ein einfacher Leitfaden mit dem man sich auf die Suche nach der Ursache machen kann. Zunächst meldet man sich zum Beispiel via ssh an der Konsole des betroffenen Rechners an.

1. Uhrzeitquellen ermitteln

Das geht an der Konsole rasch und fix wie folgt:

root@ghm ~ # ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 0.ubuntu.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
 1.ubuntu.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
 2.ubuntu.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
 3.ubuntu.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
 de.pool.ntp.org .POOL.          16 p    -   64    0    0.000    0.000   0.000
 ntp.ubuntu.com  .POOL.          16 p    -   64    0    0.000    0.000   0.000
-nbg00.furzone.n 237.17.204.95    2 u   13   64  377    2.696   -0.107   0.226
#ns1.customer-re 192.53.103.108   2 u   12   64  377   10.811    1.154   0.385
+mail.sebi.org   237.17.204.95    2 u   10   64  377    2.753    0.522   0.404
-47.ip-51-75-67. 207.197.87.124   4 u    6   64  377    6.170   -0.790   0.284
-dxb.vaxxi.net   176.96.138.245   3 u    7   64  377    5.246    0.209   0.269
-2a01:4f8:202:14 36.224.68.195    2 u   73  128  377    0.344   -0.302   0.330
*193.24.227.196  .PZF.            1 u    9   64  377    7.340    0.393   0.419
-mc1.root.projec 35.73.197.144    2 u   76  128  377    6.191   -0.331   0.393
-vmd55813.contab 192.53.103.103   2 u    9   64  377   14.178    0.867   0.411
-shout.ovh       131.188.3.220    2 u   68  128  377    2.701    0.441   0.532
+2a03:4000:28:36 85.25.213.41     3 u    2   64  377    2.740   -0.096   0.242

Das -p steht für peers. Mit -pn hätte man die numerische Ansicht, also keine DNS-Namen in der ersten Spalte. In diesem Beispiel habe ich mal eine etwas längere Liste genommen. Interessant ist das Zeichen vor der ersten Spalte. Die wichtigsten hierbei sind:

+ Dieser Server könnte verwendet werden
* Dieser Server wird verwendet
- Dieser Server wurde aussortiert
Leerzeichen: Dieser Server ist nicht erreichbar.

Weitere Details gefällig? Die finden sich zum Beispiel hier: http://doc.ntp.org/4.1.0/ntpq.htm.

Für uns wichtig: Es sollte eine Zeitquelle mit dem * geben. Wenn ja, dann ist alles wunderbar.

Nur ist es leider so, dass man das so nicht immer antrifft. In internen Netzen hinter Firewalls erlebe ich oft genug, dass es nur einen NTP-Server als Zeitquelle gibt. Und wenn dieser nach der Initialisierungsphase immer noch mit Leerzeichen angezeigt wird, wird es Zeit der Sache genauer auf den Grund zu gehen. Das könnte dann wie folgt aussehen:

ntpq> peers
     remote           refid      st t when poll reach   delay   offset jitter
==============================================================================
 2.time.domain   192.53.103.104   2 u  268 1024  377    0.222    0.046   0.485
ntpq>

Zu diesem Aufruf: Ich habe lediglich ntpq an der Konsole eingegeben und an der folgenden Befehlseingabe das Schlüsselwort peers. Das hätte ich auch schneller haben können wie bereits oben gezeigt: ntpq -p.

Aber was sieht man? Nur eine Zeitquelle und die hat trotz einem guten Stratum von 2 (die st Spalte) nur ein Leerzeichen davor.

Details zum Begriff Stratum gefällig? Eine kurze Einführung gibt es hier: https://de.wikipedia.org/wiki/Network_Time_Protocol#Grundlagen. Mehr Details gefällig? Die gibt es hier: http://www.ntp.org/ntpfaq/NTP-s-algo.htm.

2. Analyse

ntpq habe ich bereits gezeigt. Dieses Tool ist Mittel der Wahl zur Fehlersuche. Also rasch nochmals gestartet und folgende beiden Kommandos ausgeführt: as für associations. In dieser Übersicht erhält man die für weitere Recherchen notwendige assid. Du hast nachgelesen was +, -, * und so weiter in der Liste der peers bedeutet? Dann wirst Du alte Bekannte in der Spalte condition wieder erkennen. Das sieht dann zum Beispiel so aus:

ntpq> as
ind assid status  conf reach auth condition  last_event cnt
===========================================================
  1 26914  901a   yes   yes  none    reject    sys_peer  1
ntpq>

In diesem Beispiel gehe ich wieder der Annahme, dass bereits ntpq gestartet wurde. Interessant ist die assid 26914. Unter condition steht reject. Aber das wussten wir ja bereits.

Mit rv bzw. readvars kann man sich nun weiter Details zur ermittelten assid anzeigen lassen:

rv 26914
associd=26914 status=901a conf, reach, sel_reject, 1 event, sys_peer,
srcadr=<snip>, srcport=123, dstadr=<snip>, dstport=123,
leap=00, stratum=2, precision=-23, rootdelay=18.784, rootdisp=25.986,
refid=192.53.103.104,
reftime=e2d36804.31d83086  Tue, Aug  4 2020  6:52:20.194,
rec=e2d36ab6.efc51cfc  Tue, Aug  4 2020  7:03:50.936, reach=377,
unreach=0, hmode=3, pmode=4, hpoll=10, ppoll=10, headway=0,
flash=400 peer_dist, keyid=0, offset=0.046, delay=0.222,
dispersion=19.105, jitter=0.485, xleave=0.019,
filtdelay=     0.22    0.22    0.24    0.26    0.28    0.27    0.29    0.27,
filtoffset=   -0.08    0.05    0.17    0.35    0.51    0.65    0.78    0.68,
filtdisp=      0.00   15.81   31.26   46.74   62.76   79.05   95.06  110.49

Für die Bedeutung sämtlicher Variablen sei im Moment auf die ntp Dokumentation verwiesen. Interessant ist in unserem Fall das was bei flash steht: 400 peer_dist. Zusammengefasst bedeutet dies, dass die maximale Zeit erreicht wurde die der gegenüberliegende Server brauchen darf für seine Antwort. Die Gründe hierfür können die Serverlast zum einen, die Netzwerklast zum anderen sein.

Details zum flash status finden sich hier: http://doc.ntp.org/4.2.6p5/decode.html. Weitere Infos zu maxdist mit dem man die maximale Wartezeit beeinflussen kann finden sich hier: http://doc.ntp.org/current-stable/miscopt.html.

Noch eine kurze Anmerkung zum rv: Wenn man die assid weglässt oder auf 0 setzt werden die eigenen Variablen ausgegeben.

3. Ursache und Lösung

Da der Rest im Netzwerk zu dem Zeitpunkt sauber läuft liegt die Ursache vermutlich wo anders. Also zum Zeitpunkt mal auf dem Ziel-NTP-Server umgeschaut. Und siehe da, da reichte ein einfacher top um die Ursache zu finden: Das Backup lastete die Prozessoren aus. Kaum war das Backup vorbei lief NTP wieder sauber.

Was kann man dagegen machen? Zum einen könnte man das Backup entsprechend ändern, dass es weniger CPU-Ressourcen verbraucht. Das geht aber normalerweise zu Kosten der Laufzeit und ist sicherlich nicht überall umsetzbar. Die pragmatischste Lösung wäre ein weiterer NTP-Server. Solange die zu unterschiedlichen Zeiten ihr Backup am laufen haben ist immer mindestens ein Server uneingeschränkt erreichbar. Und das hilft sogar außerhalb vom Backup bei so Begriffen wie „Wartungsarbeiten“ oder dem weniger schönen „Ausfall“…

Und gleich nochmals

Ok, einer geht noch. Ein Fall der in meinem Umfeld viel öfters vorkommt als der oben beschriebene. Werfen wir einen Blick auf folgende Ausgabe der peers:

ntpq> peers
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 1xx.xx.xxx.x    .INIT.          16 u    - 1024    0    0.000    0.000   0.000
+ftp.xxx.xxx     192.53.103.104   2 u  730 1024  377    0.254   -0.046   0.226
+ptbtime1.ptb.de .PTB.            1 u  139 1024  377   18.605   -0.019   0.106
*ptbtime2.ptb.de .PTB.            1 u  556 1024  377   18.704   -0.029   0.104
+ptbtime3.ptb.de .PTB.            1 u  455 1024  377   18.567   -0.029   1.859
+ns.xxx.xxx      192.53.103.108   2 u   97 1024  377    0.272    0.103   0.138

Eigentlich ein Traum: Von einem mal abgesehen könnten alle Server als Uhrzeitquelle verwendet werden. Und ein * ist mittendrin. Alles wunderbar. Trotzdem schauen wir nochmals genauer die erste Zeile an: Ein Leerzeichen und die refid bleibt auf .INIT. stehen. Da das hier nur einer ist wäre das nicht so wild. Wenn es bei allen Servern so aussieht, dann wäre das weniger gut.

Und wie geht es weiter? Genauso wie oben. Also mit as die assid ermittelt und via rv die Variablen anzeigen lassen:

ntpq> as

ind assid status  conf reach auth condition  last_event cnt
===========================================================
  1  9501  8011   yes    no  none    reject    mobilize  1
  2  9502  941a   yes   yes  none candidate    sys_peer  1
  3  9503  94fa   yes   yes  none candidate    sys_peer 15
  4  9504  96fa   yes   yes  none  sys.peer    sys_peer 15
  5  9505  94fa   yes   yes  none candidate    sys_peer 15
  6  9506  9414   yes   yes  none candidate   reachable  1
ntpq> rv 9501
associd=9501 status=8011 conf, sel_reject, 1 event, mobilize,
srcadr=1xx.xx.xxx.x, srcport=123, dstadr=xxx.xxx.xxx.xxx, dstport=123,
leap=11, stratum=16, precision=-24, rootdelay=0.000, rootdisp=0.000,
refid=INIT, reftime=00000000.00000000  Thu, Feb  7 2036  7:28:16.000,
rec=00000000.00000000  Thu, Feb  7 2036  7:28:16.000, reach=000,
unreach=43552, hmode=3, pmode=0, hpoll=10, ppoll=10, headway=0,
flash=1600 peer_stratum, peer_dist, peer_unreach, keyid=0, offset=0.000,
delay=0.000, dispersion=15937.500, jitter=0.000, xleave=0.010,
filtdelay=     0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00,
filtoffset=    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00,
filtdisp=   16000.0 16000.0 16000.0 16000.0 16000.0 16000.0 16000.0 16000.0
ntpq>

Bei flash steht dieses mal deutlich mehr drin: peer_stratum, peer_dist und peer_unreach. Der Code 1600 ist die Summe der einzelnen Codes 200, 400 und 1000. Diese Werte finden sich unter anderem im bereits weiter oben genannten Link http://doc.ntp.org/4.2.6p5/decode.html wieder.

peer_dist und peer_stratum sind jetzt eher als Folgefehler zu betrachten. peer_unreach ist da schon viel eindeutiger. Und in der Tat hat hier die Firewall ein Streich gespielt. Es ist schon einige Mal vorgekommen, dass die Kollegen von der Firewall vergessen haben, dass NTP Anfragen zwar auf Port 123/udp gehen, jedoch auch von Port 123 kommen.

Fazit

Egal was für ein Problem man mit NTP hat: Mehr Hinweise erhält man wenn man die Synchronisierungsserver anzeigen lässt, zu den Problemfällen die Verknüpfungsids ermittelt und zu diesen die Variablen ausliest (peers, as und rv). Der Rest ist dann Stückwerk und Auswertung der Fakten. Die Vorarbeit ist bereits erfolgreich erledigt.