lordgurke
Goto Top

Geschwindigkeitsunterschiede Verschlüsselung OpenVPN vs. HTTPS

Moin-Moin!

Ich habe hier ein Phänomen, für das es vermutlich ein simple Erklärung gibt, die ich aber einfach nicht sehe.

Gegeben ist ein OpenVPN-Client, der auf einem Linux auf einer zugegebenermaßen relativ alten Hardware (Intel Atom 1.8 GHz, kein AES-NI) läuft.
Dieser arbeitet mit AES-128-GCM + SHA256 über UDP. Die inner-Tunnel MTU steht auf 1440 Bytes, so dass nicht fragmentiert werden muss.
Fragmentierung und Kompression sind auch ohnehin auf Client und Server ausgeschaltet.
Der OpenVPN-Server steht im gleichen Netzwerk und hängt am gleichen Switch, hat aber eine moderne CPU mit AES-NI zur Verfügung.

Jetzt baue ich also den Tunnel zum Server auf und stelle fest, dass der Client maximal 70-80 Mbps Datendurchsatz schafft. Die CPU-Last auf dem Client liegt derweil bei knapp 60% auf einem Kern - da wäre also theoretisch noch Luft. Der Server hat gerade einmal maximal 10% CPU-Last.


Ich frage mich also: Warum ist hier OpenVPN so furchtbar langsam?
Mein erster Gedanke war, dass die CPU nicht schnell genug ver- oder entschlüsseln kann.
Lade ich nun aber vom gleichen Server - nur ohne den Tunnel - per HTTPS eine Datei herunter, erreiche ich ca. 900 Mbps.
Der Cipher ist dabei ebenfalls AES-128-GCM und SHA256.

Mein zweiter Gedanke war, dass das mit dem Transport über UDP zu tun hat und da vielleicht anders Ver-/Entschlüsselt wird. So habe ich also testweise den Tunnel via TCP aufgebaut - wenig Überraschend ohne Verbesserung.

Und dann habe ich mal einen anderen Client verwendet: Ein Notebook mit Core i7, erste Generation, 1.6 GHz, ebenfalls ohne AES-NI.
Dieser Client kommt per OpenVPN auf immerhin deutlich über 300 Mbps, dann schlägt ein CPU-Kern auf 100% Last an.
Allerdings kann auch dieser Client mit Quasi-Gigabit per HTTPS problemlos herunterladen.

Und jetzt stehe ich hier und überlege, warum der gleiche Cipher mit gleichem HMAC bei HTTPS schnell genug ist, um das Gigabit-Netzwerk auszulasten - aber bei OpenVPN kaum über 300 Mbps herauskommen.

Bleibt also nur OpenVPN als Schuldiger, wo ich nun einfach vermute, dass ich zu doof bin, das Teil auf Performance zu optimieren.
Oder ich habe einen schlimmen Denkfehler, was die Vergleichbarkeit der Ciphers angeht face-wink

Hat hier eventuell jemand einen Tipp, was ihr Server- oder Clientseitig bei OpenVPN so üblicherweise konfiguriert, wenn ihr mehr als die müden 70 Mbps Durchsatz haben wollt?


Danke!

Content-ID: 645158

Url: https://administrator.de/contentid/645158

Printed on: October 9, 2024 at 17:10 o'clock

tagol01
tagol01 Jan 28, 2021 updated at 07:21:19 (UTC)
Goto Top
hallo

wie testet du den VPN speed?

denke den link kennst du - https://community.openvpn.net/openvpn/wiki/Gigabit_Networks_Linux

wie sieht deine config aus?
speziel folgende werte:
sndbuf +rcvbuf
fredmy
fredmy Jan 28, 2021 at 08:33:03 (UTC)
Goto Top
Hallo,
manchmal hat Umstellen auf das langsamere TCP geholfen, das Ganze schneller zu machen.
Ich habe aber nie genauer nachgeforscht, was die Provider da machen (Routing?)

Es gab auch auf manchen "Strecken" massive Verbinungsabbruchprobleme bei UDP - TCP hat geholfen und war eben auch schneller.
Nur so ein Suchgedanke ...

Fred
aqui
Solution aqui Jan 28, 2021 updated at 09:00:33 (UTC)
Goto Top
Nur so ein Suchgedanke ...
Das sind aber typische (MTU) Fragmentierungsprobleme die dann oft planlos versucht wird mit TCP zu "reparieren". Allein wegen des erheblich größeren Paket Overheads bei TCP kann man solche Spekulationen getrost in das Reich der IT Märchen verbannen. Mit "Provider Router" hat sowas auch nicht das Geringste zu tun. Ein Router arbeitet rein auch Layer 3 und was da über ihm im Layer 4 (UDP/TCP usw.) transportiert wird ist ihm vollkommen Wumpe. Eine IP Forwarding Entscheidung hat mit sowas logischerweise nicht das Geringste zu tun. Weis jeder Netzwerker auch selber.
Abgesehen davon hat Kollege @LordGurke eine Fragmentierungs Thematik ja sicher ausgeschlossen.
Warum die Unterschiede oben so gravierend sind ist wirklich fraglich. Das Performance Dokument oben hat ja auch keine wirklich schlüssige Antwort.
Spannend wäre mal den Durchsatz des OVPN Tunnels ganz ohne Verschlüsselung zu messen wie es das Dokument macht um mal den genauen Unterschied zu sehen was rein nur durchs Tunneling verloren geht ?!
Hier ist dann sicher die Frage wieviel Performance das reine Enkapsulieren und Dekapsulieren der Frames in den UDP Tunnel ganz ohne Verschlüsselung fordert. Vermutlich treten da schon die gravierensten Verluste auf und die Verschlüsselung an sich ist nur marginal.
Das ist aber jetzt auch erstmal nur geraten, wäre aber für eine weitere Beurteilung mal ganz spannend....
Lochkartenstanzer
Lochkartenstanzer Jan 28, 2021 at 09:17:56 (UTC)
Goto Top
Zitat von @aqui:

Nur so ein Suchgedanke ...
Das sind aber typische (MTU) Fragmentierungsprobleme die dann oft planlos versucht wird mit TCP zu "reparieren". Allein wegen des erheblich größeren Paket Overheads bei TCP kann man solche Spekulationen getrost in das Reich der IT Märchen verbannen.

Das wäre auch mein erster Verdacht. Über TCP tunneln ist eher kontraproduktiv. Man soltle eher schauen, wie aqui es vorgeschlagen hat, ob es auch ohne encryption, so schlecht läuft. Wenn ja, dann mit MTU-Anpassungen schauen, ob das besser wird.

Die Umstellung auf TCP wirkt nur auf den ersten Blick geschwindigkeitsfördernd. Na gut, manche (Ärzte) ohne Ahnung doktern ja auch lieber an den Symptomen einer "Krankheit" als an den Ursachen herum. face-smile

lks
heilgecht
heilgecht Jan 28, 2021 at 09:47:49 (UTC)
Goto Top
Hallo,

das liegt an der Enkapsulierung.
Die Daten werden in OpenVPN Paket reingesteckt und OpenVPN Paket selbst muss ja dann in den durch MTU vorgegebene Paketgröße in UDP Frame reinpassen. Folglich hat man ein eine gewisse Unterschied zwischen Brutto und Netto Durchsatz wenn man VPN Tunnel Benutzt.

MfG Heilgecht.
Lochkartenstanzer
Lochkartenstanzer Jan 28, 2021 at 09:50:38 (UTC)
Goto Top
Zitat von @heilgecht:

Hallo,

das liegt an der Enkapsulierung.
Die Daten werden in OpenVPN Paket reingesteckt und OpenVPN Paket selbst muss ja dann in den durch MTU vorgegebene Paketgröße in UDP Frame reinpassen. Folglich hat man ein eine gewisse Unterschied zwischen Brutto und Netto Durchsatz wenn man VPN Tunnel Benutzt.

Deswegen muß man die MTU anpassen, damit das nicht passiert..

lks
heilgecht
heilgecht Jan 28, 2021 at 09:59:15 (UTC)
Goto Top
Hallo,

ein Tunnel kostet immer Durchsatz weil payload Anteil im Frame kleiner wird.
MTU Anpassung hilft, muss aber auf allen Geräten geändert werden: auf Client, Server, Router und Switche dazwischen sonst hat man wieder Fragmentierung und das verringert Durchsatz.

MfG
LordGurke
LordGurke Jan 28, 2021 at 10:03:50 (UTC)
Goto Top
Habe gerade mal ohne Verschlüsselung und HMAC getestet: Das isr tatsächlich zwar ein bisschen schneller, aber ich bleibe unter 100 Mbps. OK...

Bei rcvbuf habe ich bisher "0" eingetragen, weil das laut Doku dazu führt dass die Systemwerte genommen werden. Ich werde jetzt mal an den Buffers nochmal justieren und wenigstens 120 MB vergeben, damit das rechnerisch für Gigabit reicht und nochmal testen.
aqui
aqui Jan 28, 2021 updated at 10:07:11 (UTC)
Goto Top
Fragmentierungs Probleme hat Kollege @LordGurke aber ja oben explizit ausgeschlossen. Das ist also nicht der Punkt hier !!
Bleibt die spannende Frage nach der reinen En- und Dekapsulierungs Performance in das Tunnelframe Protokoll ohne Verschlüsselung und wie da der Durchsatz aussieht im Vergleich zur Verschlüsselung ?! OK, LG war schneller...
Gut 100Mbps ist ja nun auch nicht der Brüller zeigt aber m.E. dann deutlich das der Großteil der Performance dann in der En- und Dekapsulierung verbraten wird und die reine Verschlüsselung an sich marginal ist.
117471
117471 Jan 28, 2021 at 15:48:35 (UTC)
Goto Top
Hallo,

ich beobachte Ähnliches, wenn ich z.B. einen reversen Proxy über HTTPS anspreche und der die Daten dann (ebenfalls über HTTPS) von einem internen Webserver zieht.

In dem Zusammenhang wurde mir an allen Ecken und Enden geraten, auf die Verschlüsselung zwischen dem Proxy und dem lokalen Server zu verzichten - was die Performance nahezu verdoppelt hat.

Es hieß immer: "Doppelte Verschlüsselung ist zu vermeiden". Vielleicht ist das hier ebenfalls der Fall?

Gruß,
Jörg
aqui
aqui Jan 28, 2021 at 16:15:24 (UTC)
Goto Top
Bei OpenVPN generell und auch im obigen Aufbau beim Lord gibts ja aber gar keine doppelte Verschlüsselung !
117471
117471 Jan 28, 2021 at 17:00:49 (UTC)
Goto Top
Hallo,

ich hatte das so verstanden dass er HTTPS Seiten durch einen verschlüsselten Tunnel zieht.

Gruß,
Jörg
NetzwerkDude
Solution NetzwerkDude Jan 28, 2021 updated at 21:38:16 (UTC)
Goto Top
Da es ein Linuxsystem ist, kann man ja mal schön debuggen face-smile

perf ich ein schönes tool, mit dem man mal anfangen kann, wobei perf selbst natürlich performance nimmt und dadurch alles langsamer ist
(alles mit root rechnten ausführen) mit:
perf top -g
bekommst du einen high level overview welche lib + function am meisten cpu benötigt, so kann man schonmal sehen ob z.B. eher die crypto oder der netzwerkstack am meisten benötigen bzw. wie das verhältnis ist.
Mit Enter kannst du tiefer in den prozess eintauchen und schauen welche komponenten was wieviel brauchen.

Wenn du am Buffer experementierst hilft sicher ein echtzeitblick auf die UDP buffers, zu finden unter:
cat /proc/net/udp

Wenn der Filetransfer eine weile geht, könnte man mit dem recht trivialen einzeiler eine art udp buffer task-manager basteln:
while :; do cat /proc/net/udp | awk '{print $5 " " $6}';sleep 1; clear; done  
(sehr doof, aber should get the job done)

MFG
N-Dude
aqui
aqui Jan 29, 2021 at 11:38:08 (UTC)
Goto Top
Der Output wäre in der Tat einmal sehr spannend ! 👍
LordGurke
LordGurke Jan 31, 2021 updated at 16:14:04 (UTC)
Goto Top
@NetzwerkDude: Großen Dank für die Tipps! Mit perf habe ich bisher noch nie wirklich herumhantiert!

Ich habe jetzt endlich Zeit gehabt, tiefergehend mit perf zu debuggen und basierend auf den Daten glaube ich nun, dass OpenVPN einfach eine unheilige Kombination aus vielen Syscalls im User-Space und vermutlich auch nicht exakt geschwindigkeitsoptimierter Code ist.
Vorweg zu den Ergebnissen: Weil ich das bereits im Verdacht hatte, habe ich im Kernel per Bootoption die Spectre- und Meltdown-Mitigations ausgeschaltet. Das hat an der Geschwindigkeit allerdings nichts verändert. Die Atom-CPUs sind allerdings ohnehin nicht betroffen, aber der Vollständigkeit halber, habe ich es ausgeschaltet face-wink


Mit "perf top -g" habe ich dann mal angesehen, was OpenVPN und wget so machen:

OpenVPN:
perf-top-ovpn

wget:
perf-top-wget

Die "qozap"-Prozesse sind von einer ISDN-Karte, die dort verbaut sind (resp. von deren Treiber), die haben aber keinen Einfluss auf die Geschwindigkeit, wenn ich sie entlade.
Interessant ist aber, dass im Fall von OpenVPN viel mehr Rechenzeit auf libcrypto abfällt. Bei wget tauchte dies erst irgendwo auf Platz 28 auf.
Allerdings dürfte mit knapp 9% Anteil an der Rechenzeit auch da nicht der Flaschenhals sein.


Die UDP-Buffers habe ich mir ebenfalls angesehen, die laufen aber nur dann voll, wenn ich sie *wirklich* niedrig stelle und dann bricht auch die Geschwindigkeit sichtbar ein. Auch das würde ich dann jetzt nicht als den Flaschenhals betrachten.
Außerdem sind die Buffers exakt identisch konfiguriert wie auf dem Test-Notebook, mit dem ich volle Geschwindigkeit (wenn auch auf einem Core i7M) erreicht habe.


Meine Vermutung war, dass das Syscall-Handling für UDP-Pakete und/oder TUN-Devices irgendwie langsamer ist.

Mit strace kann ich sehen, dass für jedes Paket im wesentlichen jeweils vier Syscalls gemacht werden:
1612099820.362778 poll([{fd=3, events=POLLIN|POLLPRI}, ...], 2, 2099) = 2 ([{fd=3, revents=POLLIN}, ...])
1612099820.362972 time(NULL)            = 1612099820
1612099820.363144 recvfrom(3, "K"..., 48196, 0, {sa_family=AF_INET, sin_port=htons(1194), sin_addr=inet_addr("xxxxxxx")}, [16]) = 1422  
1612099820.363557 write(5, "E"..., 1398) = 1398  

Die zugehörigen File-Descriptors:
# ls -la /proc/8725/fd
insgesamt 0
dr-x------ 2 root root  0 Jan 31 14:29 .
dr-xr-xr-x 8 root root  0 Jan 30 00:50 ..
lrwx------ 1 root root 64 Jan 31 14:29 0 -> /dev/null
lrwx------ 1 root root 64 Jan 31 14:29 1 -> /dev/null
lrwx------ 1 root root 64 Jan 31 14:29 2 -> /dev/null
lrwx------ 1 root root 64 Jan 31 14:29 3 -> socket:[64684635]
lrwx------ 1 root root 64 Jan 31 14:29 4 -> socket:[64426488]
lrwx------ 1 root root 64 Jan 31 14:29 5 -> /dev/net/tun

Es wird also auf dem UDP-Socket mit "poll" auf ein neues Paket auf dem Socket gewartet, dieses dann mit "recvfrom" gelesen, dann (in strace natürlich nicht sichtbar) intern entschlüsselt/geprüft u.s.w. und dann mit "write" auf das TUN-Device geschrieben.
Und dann muss das Paket natürlich noch durch die interne Routingtabelle und iptables u.s.w.

Dass ein großer Anteil der Zeit auf Syscalls und Kontext-Wechsel abfällt, kann man mit "perf stat -a -d -p $(pidof openvpn)" ganz gut sehen:

perf-ovpn
perf-ovpn-detail

Der ohnehin nicht besonders tolle L1- und L2-Cache der Atom-CPU tut bei den vielen Kontextwechseln sein übriges, um hier Verzögerungen einzubringen.

Natürlich macht die Messung mit strace den Prozess spürbar langsamer, aber wir können aus perf relativ gut sehen, wie viele Syscalls möglich wären (denn mit perf gab es keinen Einbruch der Geschwindigkeit).
Da gab es ~28.000 Syscalls pro Sekunde, was dann bei je vier Syscalls pro Paket theoretisch 7.000 Pakete pro Sekunde ermöglicht.
Bei vollem Payload (in meinem Fall 1.400 Bytes) wären das maximal 9,8 Mbyte/s - was der Geschwindigkeit von ca. 60-70 Mbps, die ich ja auch erhalten habe, sehr nahe kommt. Zumal wir ja nur die reine Anzahl möglicher Syscalls betrachten, nicht die Rechenzeit, die noch für Entschlüsselung oben drauf kommt.


wget, um auch das mal als Vergleich angesehen zu haben, arbeitet zwar ebenfalls mit je vier Syscalls, nutzt aber "select" anstelle von "poll", was aber vermutlich auch der Tatsache geschuldet ist, dass wir hier mit TCP statt UDP arbeiten.
Außerdem muss wget nur nach /dev/null schreiben, hat also keine eventuellen Wartezeiten auf dem TUN-Gerät.

1612100391.160165 select(5, [4], NULL, NULL, {0, 950000}) = 1 (in [4], left {0, 949994})
1612100391.160346 read(4, "\0"..., 8192) = 8192  
1612100391.160595 write(3, "\0"..., 4096) = 4096  
1612100391.160744 write(3, "\0"..., 4096) = 4096  

# ls -la /proc/27366/fd
lrwx------ 1 root root 64 Jan 31 14:42 0 -> /dev/pts/2
lrwx------ 1 root root 64 Jan 31 14:42 1 -> /dev/pts/2
lrwx------ 1 root root 64 Jan 31 14:42 2 -> /dev/pts/2
l-wx------ 1 root root 64 Jan 31 14:42 3 -> /dev/null
lrwx------ 1 root root 64 Jan 31 14:42 4 -> socket:[64747111]


perf-wget
perf-wget-detail

Erklären lässt sich der Geschwindigkeitsunterschied aus diesen Daten m.M.n. nur durch die Tatsache, dass wget intern die Daten Buffern und in jeweils viel größeren Blöcken schreiben kann, als OpenVPN es tut und dadurch Syscalls gespart werden können. wget muss die Daten ja nicht in möglichst Echtzeit irgendwohin schreiben.
Auch bei der Entschlüsselung und Verifizierung der Daten kann man immer schön einen großen Block verwenden und muss nicht jedes Paket einzeln verarbeiten, was dann ebenfalls CPU-Zeit spart.
Würde OpenVPN blockweise verarbeiten, hätte man ja wahnsinnige Latenzzeiten auf einer Tunnelverbindung und würde doch eher stakkatohaft darüber telefonieren oder RDP nutzen face-wink
LordGurke
LordGurke Jan 31, 2021 at 14:16:01 (UTC)
Goto Top
Oh, einige Fragen habe ich irgendwie überlesen, aber weil es interessante Hintergrundinfos liefert, schicke ich die Antwort, auch wenn das eigentlich schon gelöst ist face-wink

Zitat von @tagol01:
wie testet du den VPN speed?

Ich lade eine Datei per HTTP von einem Server herunter, der sich hinter dem Remote-VPN-Router befindet.
wget -O /dev/null http://interner.server.hinter.dem.vpnrouter/testdatei.1gb
Innerhalb des Remote-Netzwerks ist damit auch problemlos Gigabit möglich.

Habe ich schon durchgespielt - allerdings bringen die dort erwähnten Performance-Optimierungen abseits der eingesetzten Ciphers in meinem Szenario nichts, weil ich trotz massiv aufgedrehter MTU natürlich weiterhin keine Pakete bekomme, die mehr als 1500 Bytes Payload haben, weil sie ja von einem anderen Gerät kommen.
Würde ich direkt von einem Server laden, auf dem auch der OpenVPN-Prozess läuft, wäre das wohl tatsächlich anders, das kann ich allerdings nicht testen.


Zitat von @fredmy:
manchmal hat Umstellen auf das langsamere TCP geholfen, das Ganze schneller zu machen.

Habe ich schon getestet, wenn auch aus anderen Grünen.

Ich habe aber nie genauer nachgeforscht, was die Provider da machen (Routing?)

Ich habe derartige Phänomene bisher nur in wenigen Fällen bei wenigen Providern gesehen.
Die Idee dahinter kann ich nachvollziehen, allerdings ändert es nichts daran, dass das häufig technisch schlecht umgesetzt ist:
Wenn ein Kunde per DDoS attackiert wird, wird häufig, weil es so schön billig ist, per UDP einfach Traffic auf ihn geworfen.
Die ganzen DDoS-Techniken wie DNS-, LDAP-, SNMP-, TFTP-Amplification u.s.w. basieren einfach auf den Eigenheiten von UDP und sind mit TCP zumindest in der Form nicht abbildbar.
Damit ein attackierter Kunde nicht einen kompletten DSLAM oder DOCSIS-Knoten offline nimmt, wird bereits vorher auf den dicken Routern ein Rate-Limit auf UDP-Pakete ausgeführt. Das verhindert, dass große Mengen UDP-Traffic an eine IP gerichtet hereinkommen, verhindert aber auch legitime Verwendungszwecke dafür.
Meistens werden diese Rate-Limits auch nicht nachjustiert um den steigenden Kapazitäten der Kunden-Anschlüsse zu entsprechen. Da werden teilweise noch Limits auf 50 Mbps gefahren...
In der Vergangenheit hat in dem Fall geholfen, andere Ports (443 oder 4500) zu verwenden, da hier die Provider meistens Ausnahmeregeln haben. Speziell bei 443/UDP, welches von Google Chrome genutzt wird, würden sich die Kunden dann über ruckelnde Youtube-Videos beschweren face-wink

Allerdings ist das ohnehin in meinem Testszenario ausgeschlossen, denn ich teste in meinem eigenen Netzwerk und Client und Server sind am exakt selben Switch angeschlossen.
NetzwerkDude
NetzwerkDude Feb 01, 2021 updated at 13:20:22 (UTC)
Goto Top
Oh, das ist ein schöner Ansatz, die Syscalls auf Paketpayload umzurechnen, nice face-smile
aqui
aqui Mar 07, 2021 updated at 18:01:24 (UTC)
Goto Top
Hast du spaßeshalber einmal Wireguard getestet als Alternative zu OpenVPN ?? Habs hier gerade mal auf 2 RasPis im Vergleich zu OpenVPN laufen und mit iPerf3 gemessen und der Durchsatz ist deutlich hoher als OpenVPN.
wg