NTP Server abfragen und Netzwerk prüfen
NTP nutzt UDP Port 123. Ein normaler TCP-Portcheck ist daher nicht ausreichend. Wenn bestimmte NTP-Server per IP-Adresse getestet werden sollen, muss eine echte NTP-Anfrage an diese IP gesendet werden.
Keine Zusatzpakete notwendig
Der folgende Test benötigt keine zusätzlichen NTP-Tools wie ntpdig, sntp oder ntpdate. Er verwendet nur python3, falls es auf dem System vorhanden ist.
Auf normalen Debian-Systemen ist python3 häufig vorhanden. Auf sehr minimalen Systemen ist das aber nicht garantiert. Ohne python3 oder ein NTP-Tool ist ein sauberer direkter NTP-Test gegen beliebige IP-Adressen nicht sinnvoll möglich.
1. Einzelne NTP-IP testen
Beispiel-IP anpassen:
python3 - 192.168.10.10 <<'PY'
import datetime
import ipaddress
import socket
import struct
import sys
if len(sys.argv) != 2:
print("FEHLER: Bitte genau eine IP-Adresse angeben.")
sys.exit(2)
host = sys.argv[1].strip()
try:
ipaddress.ip_address(host)
except ValueError:
print(f"FEHLER {host}: Keine gültige IP-Adresse.")
sys.exit(2)
packet = bytearray(48)
packet[0] = 0x23
try:
infos = socket.getaddrinfo(host, 123, type=socket.SOCK_DGRAM)
family, socktype, proto, _, sockaddr = infos[0]
with socket.socket(family, socktype, proto) as sock:
sock.settimeout(3)
sock.sendto(packet, sockaddr)
data, addr = sock.recvfrom(512)
if len(data) < 48:
print(f"FEHLER {host}: Antwort zu kurz, keine gültige NTP-Antwort.")
sys.exit(1)
stratum = data[1]
tx_seconds, tx_fraction = struct.unpack("!II", data[40:48])
unix_time = tx_seconds - 2208988800 + tx_fraction / 2**32
server_time = datetime.datetime.fromtimestamp(unix_time, datetime.timezone.utc)
if stratum == 0:
print(f"WARNUNG {host}: Antwort erhalten, aber Stratum 0. Server lehnt die Anfrage möglicherweise ab.")
else:
print(f"OK {host}: NTP-Antwort erhalten, Stratum {stratum}, Serverzeit {server_time.isoformat()}")
except socket.timeout:
print(f"FEHLER {host}: Timeout. Keine NTP-Antwort über UDP Port 123.")
sys.exit(1)
except OSError as e:
print(f"FEHLER {host}: Netzwerkfehler: {e}")
sys.exit(1)
PY
2. Mehrere NTP-IPs testen
Die IP-Adressen in der ersten Zeile anpassen:
for ip in 192.168.10.10 192.168.10.11 192.168.10.12; do
python3 - "$ip" <<'PY'
import datetime
import ipaddress
import socket
import struct
import sys
host = sys.argv[1].strip()
try:
ipaddress.ip_address(host)
except ValueError:
print(f"FEHLER {host}: Keine gültige IP-Adresse.")
sys.exit(2)
packet = bytearray(48)
packet[0] = 0x23
try:
infos = socket.getaddrinfo(host, 123, type=socket.SOCK_DGRAM)
family, socktype, proto, _, sockaddr = infos[0]
with socket.socket(family, socktype, proto) as sock:
sock.settimeout(3)
sock.sendto(packet, sockaddr)
data, addr = sock.recvfrom(512)
if len(data) < 48:
print(f"FEHLER {host}: Antwort zu kurz, keine gültige NTP-Antwort.")
sys.exit(1)
stratum = data[1]
tx_seconds, tx_fraction = struct.unpack("!II", data[40:48])
unix_time = tx_seconds - 2208988800 + tx_fraction / 2**32
server_time = datetime.datetime.fromtimestamp(unix_time, datetime.timezone.utc)
if stratum == 0:
print(f"WARNUNG {host}: Antwort erhalten, aber Stratum 0. Server lehnt die Anfrage möglicherweise ab.")
else:
print(f"OK {host}: NTP-Antwort erhalten, Stratum {stratum}, Serverzeit {server_time.isoformat()}")
except socket.timeout:
print(f"FEHLER {host}: Timeout. Keine NTP-Antwort über UDP Port 123.")
except OSError as e:
print(f"FEHLER {host}: Netzwerkfehler: {e}")
PY
done
3. Prüfen, ob Python vorhanden ist
python3 --version
Wenn eine Versionsnummer angezeigt wird, kann der Test verwendet werden. Wenn python3: command not found erscheint, ist Python auf diesem System nicht installiert.
Warum nicht curl oder wget?
curl und wget können keine echte NTP-Abfrage machen. NTP läuft über UDP Port 123, nicht über HTTP oder HTTPS.
Mit curl oder wget kann man nur prüfen, ob HTTP/HTTPS funktioniert:
curl -I https://www.debian.org
wget --spider https://www.debian.org
Das sagt aber nichts Sicheres darüber aus, ob NTP über UDP Port 123 erlaubt ist. Denn natürlich kann Netzwerkdiagnose nicht einfach mal logisch sein.
Warum nicht nur Bash mit /dev/udp?
Bash kann zwar Daten an /dev/udp/IP/PORT senden, aber UDP hat keinen Verbindungsaufbau wie TCP. Nur weil ein UDP-Paket gesendet wurde, weiß man noch nicht, ob ein NTP-Server geantwortet hat.
Für einen brauchbaren Test muss eine echte NTP-Anfrage gesendet und die Antwort ausgewertet werden. Genau das macht der Python-Test oben.
Ergebnis bewerten
| Ergebnis | Bedeutung |
|---|---|
OK ... NTP-Antwort erhalten |
Die IP-Adresse antwortet auf NTP über UDP Port 123. |
WARNUNG ... Stratum 0 |
Der Server hat geantwortet, lehnt die Anfrage aber möglicherweise ab oder liefert keine nutzbare Zeit. |
Timeout |
Keine Antwort erhalten. UDP Port 123 wird möglicherweise blockiert oder der Server antwortet nicht. |
Netzwerkfehler |
Es gibt ein lokales Netzwerkproblem, Routingproblem oder ein Problem mit der Adresse. |
Keine gültige IP-Adresse |
Der angegebene Wert ist keine gültige IPv4- oder IPv6-Adresse. |
Kurzfazit
Wenn bestimmte IP-Adressen getestet werden sollen, reicht timedatectl nicht aus. Für einen direkten Test braucht man entweder ein NTP-Tool wie ntpdig oder einen kleinen UDP-NTP-Test wie oben mit python3.
Ohne python3, ntpdig, sntp oder ntpdate ist ein sauberer direkter NTP-Test gegen beliebige IP-Adressen nicht realistisch möglich.
No Comments