Das Problem: Der Server weiß nicht wie spät es ist
Es fing harmlos an. Mein Netcup VPS zeigte timedatectl status:
System clock synchronized: no
NTP service: activeDer NTP-Service lief – aber die Uhr war nicht synchronisiert. Ein Blick ins Journal:
systemd-timesyncd: Timed out waiting for reply from 192.53.103.108:123
systemd-timesyncd: Timed out waiting for reply from 192.53.103.104:123Timeout nach Timeout. Dabei ließen sich die NTP-Server per nc -uzv problemlos erreichen. Was war hier los?
Die Diagnose: Stateless vs. Stateful Firewalls
Um das Problem zu verstehen, muss man den Unterschied zwischen zwei grundlegenden Firewall-Konzepten kennen.
Stateful Firewall (Connection Tracking)
Eine Stateful Firewall führt eine interne Verbindungstabelle – den sogenannten Connection Tracking Table. Sie merkt sich: „Von diesem Host wurde eine Anfrage nach draußen geschickt. Die Antwort darf rein.“
Genau das macht iptables/nftables auf Linux mit der RELATED,ESTABLISHED-Regel:
-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPTEingehende Pakete die zu einer bestehenden Verbindung gehören, werden automatisch akzeptiert – ohne explizite Regel.
Stateless Firewall (Paketfilter)
Eine Stateless Firewall betrachtet dagegen jedes Paket isoliert. Sie kennt keinen Kontext, kein Gedächtnis. Für sie ist eine eingehende Antwort von einem NTP-Server genauso unbekannt wie ein Angriffsversuch.
Die Netcup SCP-Firewall arbeitet nach diesem Prinzip.
Warum NTP und DNS betroffen waren
NTP über UDP funktioniert so:
VPS (Port 54321) ──UDP──▶ NTP-Server (Port 123)
VPS (Port 54321) ◀──UDP── NTP-Server (Port 123)Der VPS schickt ein NTP-Request von einem zufälligen ephemeren Quellport (z.B. 54321) an Zielport 123. Die Antwort kommt zurück mit Quellport 123 auf denselben ephemeren Port.
Die Netcup-Firewall sah:
| Richtung | Quellport | Zielport | Ergebnis |
|---|---|---|---|
| Ausgehend | 54321 | 123 | ✅ Outbound offen |
| Eingehend | 123 | 54321 | ❌ Keine Regel → DROP |
Da sie stateless ist, erkannte sie den Zusammenhang zwischen Anfrage und Antwort nicht. Das Ergebnis: alle NTP-Requests verschwanden ins Nichts.
Das gleiche Problem traf DNS over TLS (DoT): systemd-resolved versuchte DoT auf Port 853 – die Antworten kamen nie an, und der Resolver fiel auf unverschlüsseltes UDP zurück:
systemd-resolved: Using degraded feature set UDP+EDNS0 instead of TLS+EDNS0Die Diagnose im Detail
conntrack als Beweis
Das Entscheidende war der Blick in die conntrack-Tabelle:
sudo conntrack -L | grep 123udp 17 28 src=123.456.789.000 dst=212.132.97.26 sport=60698 dport=123 [UNREPLIED] ...
udp 17 18 src=123.456.789.000 dst=185.252.140.126 sport=54607 dport=123 [UNREPLIED] ...[UNREPLIED] – conntrack trackte die Verbindungen korrekt, aber die Antwortpakete kamen nie an. Nicht geblockt von iptables, nicht gefiltert von UFW – sie kamen schlicht nicht am eth0 an.
tcpdump als finaler Beweis
sudo tcpdump -n -i eth0 udp port 123Ausschließlich ausgehende Pakete. Keine einzige Antwort. Die Pakete wurden vor dem VPS geblockt – auf Hypervisor-Ebene durch die Netcup SCP-Firewall.
Die Lösung
Fix 1: Netcup SCP-Firewall korrigieren
Die korrekte Regel für NTP-Antworten in der SCP-Firewall anlegen und zuweisen:
| Feld | Falsch | Richtig |
|---|---|---|
| Typ | EINGEHEND | EINGEHEND |
| Protokoll | UDP | UDP |
| Source Port | – | 123 |
| Destination Port | 123 | * (Any) |
Die Antwortpakete kommen von Quellport 123 zurück auf einen ephemeren Zielport. Das muss explizit erlaubt werden.
Analog für DNS over TLS: Eingehend, UDP+TCP, Source Port 853.
Fix 2: Von systemd-timesyncd auf chrony wechseln
Da systemd-timesyncd weiterhin Probleme machte, wechselte ich auf chrony mit NTS (Network Time Security):
sudo systemctl disable --now systemd-timesyncd
sudo apt install chrony# /etc/chrony/chrony.conf
server time.cloudflare.com iburst nts
server ptbtime1.ptb.de iburst nts
server ptbtime2.ptb.de iburst nts
makestep 1.0 3
rtcsync
driftfile /var/lib/chrony/driftNTS nutzt TCP/4460 für den initialen Key-Exchange (TLS-gesichert) und ist damit deutlich robuster als reines UDP/123. Nach der Netcup-Firewall-Korrektur synchronisierte chrony sofort:
^* ptbtime2.ptb.de 1 6 77 7 -155us[ +122us] +/- 5586usStratum 1, direkt an einer Atomuhr – und nur 0,15ms Offset.
Fix 3: DNS over TLS mit Quad9
systemd-resolved wurde auf öffentliche DoT-fähige Resolver umgestellt:
# /etc/systemd/resolved.conf
[Resolve]
DNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net
FallbackDNS=1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com
DNSOverTLS=yes
DNSSEC=yesDie #hostname-Syntax ist dabei entscheidend: Ohne den Hostnamen kann systemd-resolved das TLS-Zertifikat des Resolvers nicht validieren und fällt auf UDP zurück.
Das technische Fazit
Das Problem lässt sich in einem Satz zusammenfassen: Eine stateless Firewall versteht keine Verbindungen – sie kennt nur Pakete.
Wer einen VPS hinter einer stateless Firewall betreibt und UDP-basierte Dienste wie NTP oder DNS nutzt, muss Return Traffic explizit erlauben – also eingehende Pakete vom jeweiligen Quellport des Servers, nicht vom Zielport des eigenen Requests.
Für TCP-Verbindungen ist das normalerweise kein Problem, da der Three-Way-Handshake leichter zu erkennen ist. UDP hingegen ist verbindungslos – hier braucht eine stateless Firewall immer explizite Regeln für beide Richtungen.
Checkliste für Netcup VPS mit SCP-Firewall
Folgende eingehende Regeln werden für typische Serverdienste benötigt:
| Dienst | Protokoll | Source Port | Destination Port |
|---|---|---|---|
| NTP-Sync | UDP | 123 | * |
| DNS (UDP) | UDP | 53 | * |
| DNS over TLS | TCP | 853 | * |
| HTTP/S | TCP | * | 80/443 |
| SSH | TCP | * | 22 (oder custom) |
HTTPS und SSH funktionieren in der Regel ohne diese Regeln weil die meisten Firewalls TCP-Established-Traffic durchlassen – aber bei UDP immer beide Richtungen prüfen.


