Probleme mit OpenVPN auf einem vServer

… und die passende Lösung dazu.

Aber mal ganz von Anfang an. Ich habe auf einem vServer bei Hetzner ein VPN mit OpenVPN eingerichtet. Dazu habe ich hauptsächlich die Anleitung dazu aus dem Debian Wiki und die Anleitung für IPv6 aus dem OpenVPN Wiki verwendet.

Über das VPN bekommen die verbundenen Clients dann private IPv4- und IPv6-Adressen. Neulich bin ich dann von einem älteren Modell auf einen der aktuellen CX-Server umgestiegen und damit kommen wir dann auch langsam zum Problem. Dort funktioniert zwar erstmal das VPN wie gewohnt. Die Clients bekommen ihre IPv4- und IPv6-Adresse und können damit auch übers VPN ins Internet. Um das zu verifizieren habe ich jeweils einen ping und einen mtr, je über IPv4 und IPv6, getestet um festzustellen, dass ein mtr über IPv6 nicht klappt, ich komme bis zum ersten HOP (meinem vServer), aber nicht weiter.

Ein tcpdump auf dem Client, während ein ‚mtr -6 google.de‘ läuft, sieht dann auszugsweise folgendermaßen aus:

# tcpdump -n -v -i tun0 icmp6
tcpdump: listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes

18:13:04.343693 IP6 (flowlabel 0xb626a, hlim 3, next-header ICMPv6 (58) payload length: 64) fd00:dead:beef:cafe::1000 > 2a00:1450:4001:81c::2003: [icmp6 sum ok] ICMP6, echo request, seq 60032
18:13:04.387088 IP6 (flowlabel 0x8e224, hlim 62, next-header ICMPv6 (58) payload length: 112) 2a01:4f8:0:e171::113e > fd00:dead:beef:cafe::1000: [bad icmp6 cksum 0x66d2 -> 0x68d2!] ICMP6, time exceeded in-transit for 2a00:1450:4001:81c::2003

fd00:dead:beef:cafe::1000 ist hierbei die IPv6-Adresse meines Clients, die Pakete gehen also korrekt raus, kommen aber mit einer ungültigen Checksumme zurück.

Ich habe mir tagelang über das Problem den Kopf zerbrochen und alles mögliche ausprobiert. Die Lösung fanden wir dann gestern gemeinsam auf dem Chaostreff nach weiterem stundenlangem Debugging.

Die Lösung

Nach dem erwähnten stundenlanden Debugging kam mir dann irgendwann der helfende Gedanke. Und zwar kann man bei den CX-Servern bei Hetzner die Art der Virtualisierung der Netzwerkkarte auswählen. Standardmäßig ist hier ‚VirtIO‘ ausgewählt, welches die beste Performance bieten soll. Als ich hier auf eine der anderen beiden Auswahlmöglichkeiten umgestellt hatte kamen die Pakete auf einmal mit einer korrekten Checksumme an! 🙂 Yeah! Endlich!

robot_cx_settings

Stesie’s Vermutung dazu ist, dass der VirtIO-Treiber hier davon ausgeht, dass er keine Checksummenberechnung machen muss, da es ja nur ein virtualisiertes Netzwerkinterface ist und die Netzwerkkarte des Hostsystems ja schon die Checksummen berechnen sollte. Im Zusammenspiel mit OpenVPN klappt das wohl nicht ganz wie erwartet. Diese Pakete gehen dann in diesem Fall also ohne korrekte Checksumme übers VPN zum Client, welcher hier dann die Checksumme prüft und merkt, dass dort keine gültige eingetragen ist. Ich weiß nicht, ob diese Vermutung zutrifft, klingt für mich aber plausibel so wie er sie erzählt hat (ich hoffe ich habe es hier auch halbwegs korrekt wiedergegeben).

TL;DR

Wenn du auf einem CX-Server bei Hetzner ein VPN betreiben möchtest, dann stell das ‚NIC-Modell‘ von VirtIO auf eine der anderen Auswahlmöglichkeiten.

Vielen Dank nochmal an alle, die beim Chaostreff anwesend waren und mir bei der Problemlösung geholfen haben 😉 Ich hoffe falls jemand das selbe Problem hat findet er diesen Blogeintrag 🙂