# VM302 Netzwerk-Analyse & Optimierung — 2026-07-20 Vollständige Untersuchung der Latenz Deutschland ↔ Kansas City (VM302, A40-Workstation) sowie zweier kritischer Sicherheits-/Performance-Befunde. ## TL;DR - **Routing über Relays bringt NICHTS** — der direkte Pfad ist bereits physikalisch optimal (3 Beweise) - **Der echte Gewinn lag auf der Maschine:** RSC abschalten = −7 ms, mehr als jedes Gateway geboten hätte - **VM302 stand ungeschützt im Internet** (ComfyUI/Ollama ohne Auth) — geschlossen - **Tailscale lief über Relay statt direkt** — Port-Forward-Fix: 162 → 127 ms, Jitter 40 → 0,8 ms ## 1. Sicherheitslücke (kritisch) **Befund:** VM302s Windows-Firewall-Profil „Private" war **deaktiviert**, und die öffentliche NIC lag in genau diesem Profil. Folge: ComfyUI (:8188), Studio (:8502), Ollama (:11434), LiteLLM (:4000) waren **unauthentifiziert aus dem Internet erreichbar**. ComfyUI erlaubt Datei-Zugriff und via Custom-Nodes faktisch Code-Ausführung → A40 und System offen für jeden. **Fix — nur VM-Ebene filtern, Hosts offen lassen:** ``` /etc/pve/firewall/cluster.fw enable: 1, policy_in: ACCEPT # Subsystem an, Default offen /etc/pve/nodes//host.fw enable: 1 # erbt ACCEPT = ungefiltert /etc/pve/firewall/302.fw policy_in: DROP + Ausnahmen # NUR hier wird gefiltert qm set 302 --net1 ...,firewall=1 # nur die öffentliche NIC ``` Ausnahmen in 302.fw: 3389 (RDP), 47984-48010 (Moonlight), 41641 (Tailscale), ICMP. **net0 (intern/NAT) bleibt ungefiltert = Rettungsleine**, RDP über die NAT-IP bleibt immer erreichbar. ## 2. Tailscale: Relay statt Direktverbindung **Befund:** `tailscale status` zeigte `relay "ki1-us"` — jede Verbindung lief über Virginia, also DE→USA→DE. **Ursache:** VM302 sitzt hinter NAT auf gpu1. Forwards für RDP und Moonlight existierten, **für Tailscale UDP 41641 nicht.** **Fix — BEIDE Regeln nötig:** ```bash # eingehend iptables -t nat -A PREROUTING -i vmbr0 -p udp --dport 41641 -j DNAT --to-destination 10.10.10.102:41641 iptables -I FORWARD -p udp -d 10.10.10.102 --dport 41641 -j ACCEPT # ausgehend: Quellport ERHALTEN iptables -t nat -I POSTROUTING 1 -o vmbr0 -p udp -s 10.10.10.102 --sport 41641 \ -j SNAT --to-source 173.208.162.26:41641 netfilter-persistent save ``` **Nur DNAT reicht nicht** — MASQUERADE würfelt sonst den Quellport, STUN meldet einen anderen Port als den geforwardeten, und das Mapping passt nicht zusammen. **Ergebnis:** 162 ms / 40 ms Jitter (Relay) → **127 ms / 0,8 ms Jitter (direkt)**. ## 3. RSC — der eigentliche Latenz-Fresser **Befund:** nas2 → VM302 = 143,9 ms, nas2 → gpu1 = 134,8 ms. **9,1 ms Unterschied im selben Rechenzentrum.** **Ursache:** Recv Segment Coalescing (RSC) auf den virtio-NICs aktiv — bündelt eingehende Pakete, spart CPU, kostet Latenz und Jitter. ```powershell Disable-NetAdapterRsc -Name "Ethernet 2" Disable-NetAdapterRsc -Name "Ethernet" ``` **Ergebnis:** VM302 132,3 ms · Abstand zu blankem Blech **9,1 → 2,0 ms** · netto **~7 ms Gewinn**. RSS war bereits aktiv (16 Queues), Offloads korrekt. ## 4. Routing-Analyse — warum kein Relay hilft | Weg | Ergebnis | |---|---| | Direkt DE → VM302 | **121 ms**, ±2 ms Jitter, 0 % Verlust | | über Netcup DE (gw) | +15 ms | | über Netcup Virginia | +9 ms | | alle VM302-Ziele über gw | +15…20 ms | **Traceroute:** beide Wege über Arelion/Telia (62.115.x). Direkter Pfad **ohne Umweg**, Zielnetz ab Hop 13. **Geografie:** Virginia = Ostküste (94 ms), Kansas City = Landesinneres (121 ms) → über Virginia fährt man 27 ms extra. **Messfallen, die zu Fehlschlüssen führen:** - **TCP-Handshake über einen nginx-Stream-Proxy misst nichts** — nginx nimmt lokal an, bevor es das Backend kontaktiert (zeigte 3,5 ms statt der echten Strecke). Stattdessen echten Protokoll-Roundtrip messen (RDP X.224 CR→Confirm). - **Ping-Summen unterschätzen Relays systematisch** — Annahme/Pufferung/Neuversand tauchen darin nicht auf. Gemessene Realität bei gw: +15 ms, obwohl die Summe „gleichauf" vorhersagte. - `tailscale netcheck` nutzt einen **eigenen Socket** — der dort gemeldete Port ist NICHT tailscaleds 41641. **Fazit:** 7.000 km über ein Tier-1-Backbone sind ~121 ms. Kein Relay, Tunnel oder Peering-Trick geht darunter. Echte Hebel: Protokoll (Moonlight statt RDP), Maschine (RSC), Architektur (Ergebnisse nach DE pushen statt mehrfach queren). ## 5. Zwei eigene Fehler — zur Warnung **a) Proxmox-Cluster-Falle.** gpu1 und pm1 bilden `consoro-cluster`. `/etc/pve/` ist **geteiltes Cluster-Dateisystem** — `cluster.fw` mit `enable: 1` auf gpu1 schaltete die Firewall auch auf pm1 ein → dort SSH tot, Web-UI-Timeouts bei VM-Details (PVEFW-HOST-IN lässt SSH nur aus IPSET `management`, und das war leer). ➡️ **Vor jedem Proxmox-Firewall-Eingriff `pvecm status` prüfen.** **b) `policy_in` ist keine gültige `host.fw`-Option** (gehört in `cluster.fw`). Falsch gesetzt → Host-Policy fiel auf DROP zurück → **Selbst-Aussperrung per SSH**. Gerettet hat Tailscale, weil `ts-input` **vor** der PVE-Kette akzeptiert. ➡️ Bei Firewall-Arbeiten immer einen zweiten, ungefilterten Zugangsweg offen halten. **c) Unbelegte Behauptung.** Ich hatte gewarnt, der DERP auf dem Mailserver störe die Mailzustellung — **ohne zu messen**. Nachgemessen: 0,1 % CPU, 2 Verbindungen, 1 Logzeile/Stunde. Die Behauptung war falsch. ➡️ Erst messen, dann warnen. ## 6. Latenz-Matrix (Referenz) Gemessen von nas2 (Standort Bär, ohne WARP-Verfälschung): | nas2 → | ms | | Server → gpu1 | ms | |---|---|---|---|---| | DERP-DE (Mailserver) | 24,3 | | **Mailserver** | **111,4** (bestes Peering) | | DERP-US (Virginia) | 106,6 | | Hub | 120,5 | | gpu1 | 130–135 | | nas2 | 134,8 | | VM302 (nach Tuning) | 132,3 | | | | **Wichtig:** Bär nutzt Cloudflare WARP → Messungen an seinem Client sind verfälscht. **Immer von nas2 oder gpu1 aus messen.** --- # NACHTRAG — Thema abgeschlossen (Endstand 2026-07-20) ## Weitere Messungen nach dem ersten Bericht ### Cloudflare Tunnel — mein Messfehler und die Korrektur Erster Test zeigte scheinbar **90 ms Gewinn** durch einen Cloudflare Quick Tunnel. **Das war falsch.** Ursache: der Testserver war ein einthreadiger Python-`BaseHTTPRequestHandler`, der die *Direkt*messung ausbremste (274 ms bei 132 ms echter Netzlaufzeit). Neumessung mit `ThreadingHTTPServer` + `TCP_NODELAY` + keep-alive, gleiches Backend für beide Wege: | Weg | Median Dauerbetrieb | |---|---| | Direkt (http) | **130–144 ms** ← entspricht exakt dem Ping | | Cloudflare-Tunnel (https) | 166–227 ms | ➡️ **Cloudflare ist 35–80 ms LANGSAMER.** Kein Domain-Umzug nötig. ➡️ **Lehre: bei Latenzmessungen immer prüfen, ob der Testserver selbst der Flaschenhals ist.** ### Warum Cloudflares 1-ms-Nähe nicht hilft `gpu1 → 1.1.1.1 = 1,06 ms`, PoP-Kennung **`mci03`** (= Kansas City), 6 Hops, echtes Cloudflare (kein Provider-Hijack). Aber: Diese 1 ms decken nur den ersten Meter. Der Atlantik bleibt. **Ein Anycast-Ping misst, wo die nächste Edge steht — nicht, wie schnell das Backbone nach Europa trägt.** ### Alle Varianten im Endstand | Variante | Ergebnis | |---|---| | **Direkt** | ✅ 121 ms (RZ) · 130 ms (nas2) · 150 ms (Client) | | Cloudflare-Tunnel | +35…80 ms | | Netcup-DE-Relay | +15 ms | | Netcup-Virginia | +9 ms | | NordVPN Meshnet | ±0 (funktional = Tailscale) | | Multi-Routing-Broker | nicht bauen — Tailscale leistet das bereits | | **RSC-Tuning VM302** | ✅ **−7 ms** (einziger echter Gewinn) | **Bärs Anschluss ist Starlink** (SpaceX-IP, Berlin) → systembedingter Jitter, nicht wegoptimierbar. Sein Client misst 150 ms, sein NAS am selben Anschluss 130 ms → Verdacht WLAN/Client-seitig. ## Weitere Sicherheitsbefunde (alle geschlossen) ### Sunshine-Admin-Oberfläche stand offen Port 47990 öffentlich erreichbar, **ohne jede Zugangsdaten** (`credentials/` enthält nur TLS-Zertifikate, `sunshine.conf` hat kein `username`/`password`). Wer die URL aufrief, konnte sich als Admin einrichten, Geräte koppeln und **den Desktop streamen**. ➡️ 47990 aus der Proxmox-Regel entfernt **und** die DNAT-Weiterleitung auf gpu1 gelöscht. ### DNAT verschleierte alle RDP-Absender ``` DNAT tcp dpt:3389 → 10.10.10.102 destination 0.0.0.0/0 ← griff auch für .43 ``` Folge: **jede** RDP-Verbindung erschien als `10.10.10.1` — auch die Angriffe aus Ungarn (80.94.95.152) und Moskau (62.205.169.50). **EvlWatcher war blind** und hätte beim Sperren Bär selbst ausgesperrt. ➡️ DNAT auf `-d 173.208.162.26` eingegrenzt. `.43` läuft direkt mit echter Absender-IP, `.26` bleibt als Rettungsleine. **Merksatz:** DNAT-Regeln ohne Ziel-IP-Bindung hebeln VM-Firewalls aus, weil der Traffic am gefilterten Interface vorbei auf die interne Karte umgeleitet wird. ## Moonlight/Sunshine — Ursache **`sunshine_state.json`: 0 gekoppelte Geräte.** Ohne Kopplung kein Stream. Sunshine läuft als SYSTEM in Sitzung 1 (Konsole), virtueller Display-Adapter (SudoMaker) vorhanden, Aufnahme funktioniert (1600x1156 @ 66 Hz). Desktop-Duplication funktioniert in RDP-Sitzungen nicht — deshalb muss Sunshine auf der Konsole laufen. **Kopplung:** Client in Tailscale → Moonlight „+" → `100.104.5.57` → PIN unter `https://100.104.5.57:47990`. ## Fazit 7.000 km über ein Tier-1-Backbone sind ~121 ms. **Kein Relay, Tunnel, Mesh oder Broker geht darunter.** Für 5–10 €/Monat existiert keine Lösung, die das ändert. Einziger echter Hebel: **GPU-Maschine in Europa.** Praktisch nutzbar: Protokollwahl (Moonlight statt RDP) und **Ergebnisse nach DE pushen statt den Ozean mehrfach queren.**