Bardzo niska przepustowość TCP OpenVPN (port 100 Mb, niskie wykorzystanie procesora)

27

Mam bardzo niskie prędkości transferu OpenVPN między dwoma serwerami. W przypadku tego pytania zadzwonię do serwerów A i Server B.

Zarówno na serwerze A, jak i na serwerze B działa CentOS 6.6. Oba znajdują się w centrach danych z linią 100 Mb, a transfery danych między dwoma serwerami poza OpenVPN przebiegają z prędkością około ~ 88 Mb / s.

Jednak gdy próbuję przesłać jakiekolwiek pliki przez połączenie OpenVPN, które ustanowiłem między serwerem A i serwerem B, uzyskuję przepustowość około 6,5 Mb / s.

Wyniki testu z iperf:

[  4] local 10.0.0.1 port 5001 connected with 10.0.0.2 port 49184
[  4]  0.0-10.0 sec  7.38 MBytes  6.19 Mbits/sec
[  4]  0.0-10.5 sec  7.75 MBytes  6.21 Mbits/sec
[  5] local 10.0.0.1 port 5001 connected with 10.0.0.2 port 49185
[  5]  0.0-10.0 sec  7.40 MBytes  6.21 Mbits/sec
[  5]  0.0-10.4 sec  7.75 MBytes  6.26 Mbits/sec

Oprócz tych testów iperf OpenVPN, oba serwery są praktycznie całkowicie bezczynne przy zerowym obciążeniu.

Serwerowi A przypisano adres IP 10.0.0.1 i jest to serwer OpenVPN. Serwer B ma przypisany adres IP 10.0.0.2 i jest to klient OpenVPN.

Konfiguracja OpenVPN dla serwera A wygląda następująco:

port 1194
proto tcp-server
dev tun0
ifconfig 10.0.0.1 10.0.0.2
secret static.key
comp-lzo
verb 3

Konfiguracja OpenVPN dla serwera B wygląda następująco:

port 1194
proto tcp-client
dev tun0
remote 204.11.60.69
ifconfig 10.0.0.2 10.0.0.1
secret static.key
comp-lzo
verb 3

Co zauważyłem:

1. Moją pierwszą myślą było to, że wąskie gardło procesora na serwerze. OpenVPN jest jednowątkowy i na obu tych serwerach działają procesory Intel Xeon L5520, które nie są najszybsze. Jednak uruchomiłem toppolecenie podczas jednego z testów iperf i nacisnąłem, 1aby zobaczyć wykorzystanie procesora według rdzenia i stwierdziłem, że obciążenie procesora było bardzo niskie na każdym rdzeniu:

top - 14:32:51 up 13:56,  2 users,  load average: 0.22, 0.08, 0.06
Tasks: 257 total,   1 running, 256 sleeping,   0 stopped,   0 zombie
Cpu0  :  2.4%us,  1.4%sy,  0.0%ni, 94.8%id,  0.3%wa,  0.0%hi,  1.0%si,  0.0%st
Cpu1  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu2  :  0.0%us,  0.0%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.3%st
Cpu3  :  0.3%us,  0.0%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu4  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu5  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu6  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu7  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu8  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu9  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu10 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu11 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu12 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu13 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu14 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu15 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:    946768k total,   633640k used,   313128k free,    68168k buffers
Swap:  4192188k total,        0k used,  4192188k free,   361572k cached

2. Czasy pingowania znacznie się zwiększają w tunelu OpenVPN podczas działania iperf. Gdy iperf nie działa, czasy pingowania w tunelu wynoszą stale 60 ms (normalnie). Ale gdy iperf działa i pcha duży ruch, czasy pingów stają się zmienne. Poniżej możesz zobaczyć, jak czasy pingowania są stabilne do czwartego pingowania, kiedy rozpocząłem test iperf:

PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=60.1 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=60.1 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=60.2 ms
** iperf test begins **
64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=146 ms
64 bytes from 10.0.0.2: icmp_seq=5 ttl=64 time=114 ms
64 bytes from 10.0.0.2: icmp_seq=6 ttl=64 time=85.6 ms
64 bytes from 10.0.0.2: icmp_seq=7 ttl=64 time=176 ms
64 bytes from 10.0.0.2: icmp_seq=8 ttl=64 time=204 ms
64 bytes from 10.0.0.2: icmp_seq=9 ttl=64 time=231 ms
64 bytes from 10.0.0.2: icmp_seq=10 ttl=64 time=197 ms
64 bytes from 10.0.0.2: icmp_seq=11 ttl=64 time=233 ms
64 bytes from 10.0.0.2: icmp_seq=12 ttl=64 time=152 ms
64 bytes from 10.0.0.2: icmp_seq=13 ttl=64 time=216 ms

3. Jak wspomniano powyżej, uruchomiłem iperf poza tunelem OpenVPN, a przepływność była normalna - ~ 88 Mb / s konsekwentnie.

Co próbowałem:

1. Pomyślałem, że kompresja może powodować problemy, więc wyłączyłem kompresję, usuwając comp-lzoobie konfiguracje i ponownie uruchamiając OpenVPN. Brak postępu.

2. Mimo że wcześniej stwierdziłem, że wykorzystanie procesora było niskie, pomyślałem, że domyślny szyfr może być zbyt intensywny, aby system mógł go nadążyć. Dodałem więc cipher RC2-40-CBCdo obu konfiguracji (bardzo lekki szyfr) i zrestartowałem OpenVPN. Brak postępu.

3. Czytałem na różnych forach o tym, jak ulepszenie fragmentu, mssfix i mtu-tun może pomóc w wydajności. Grałem z kilku wariantów opisanych w tym artykule , ale znowu, nie ma poprawy.

Wszelkie pomysły na to, co może powodować tak niską wydajność OpenVPN?

Elliot B.
źródło
Czy jakieś linki, komentarze stąd pomagają? forums.openvpn.net/topic10593.html
Matt
Większość sugestii to rzeczy, które już wypróbowałem: 1. sprawdź wąskie gardło procesora, 2. sprawdź prędkości transferu bez VPN, 3. przełącz kompresję, 4. wybierz szybszy szyfr itp. Nie ma szczęścia z żadnym z nich jeszcze: - / To dziwne. Oprócz niskiej prędkości i wysokich / niestabilnych czasów pingowania, nie widzę innych oznak tego, gdzie może być wąskie gardło.
Elliot B.
Czy obie maszyny znajdują się w tym samym centrum danych? 60 ms w tym samym centrum danych jest dość wysokie. Kusi mnie, by spróbować, cipher nonechoć wątpię, by to pomogło.
Zoredache
@Zoredache Przepraszam - nie miałem jasności co do lokalizacji serwerów - serwer A znajduje się w Dallas, a serwer B - w Seattle.
Elliot B.
Czy sprawdziłeś MTU? Esp: parametry tun-mtu, fragment i mssfix? Dokumentacja
Lenniey

Odpowiedzi:

26

Po wielu poprawkach w Google i plikach konfiguracyjnych znalazłem rozwiązanie. Dostaję teraz stałe prędkości 60 Mb / s i tryby do 80 Mb / s. Jest nieco wolniejszy niż prędkości transferu, które otrzymuję poza VPN, ale myślę, że jest to tak dobre, jak to możliwe.

Pierwszym krokiem było ustawienie sndbuf 0i rcvbuf 0skonfigurowanie OpenVPN zarówno dla serwera, jak i klienta.

Dokonałem tej zmiany po tym, jak zobaczyłem sugestię, aby zrobić to na postu na forum publicznym (czyli angielskim tłumaczeniu rosyjskiego oryginalnego postu ), który przytoczę tutaj:

Jest lipiec 2004 r. Zwykła prędkość Internetu w domu w krajach rozwiniętych wynosi 256-1024 Kbit / s, w krajach słabiej rozwiniętych 56 Kbit / s. Linux 2.6.7 został wydany niedawno, a wersja 2.6.8, w której skalowanie rozmiaru TCP Windows byłoby domyślnie włączone, jest wydawana dopiero za miesiąc. OpenVPN jest w fazie rozwoju od 3 lat, wersja 2.0 jest już prawie wydana. Jeden z deweloperów decyduje się na dodanie kodu do bufora gniazd, myślę, że ujednolicę rozmiary buforów między systemami operacyjnymi. W systemie Windows coś idzie nie tak z jednostką MTU adaptera, jeśli ustawione są niestandardowe rozmiary buforów, więc w końcu przekształca się w następujący kod:

#ifndef WIN32
o->rcvbuf = 65536;
o->sndbuf = 65536;
#endif

Jeśli korzystałeś z OpenVPN, powinieneś wiedzieć, że może on działać przez TCP i UDP. Jeśli ustawisz niestandardową wartość bufora gniazda TCP na 64 KB, algorytm skalowania rozmiaru okna TCP nie będzie mógł ustawić rozmiaru okna na więcej niż 64 KB. Co to znaczy? Oznacza to, że jeśli łączysz się z inną witryną VPN za pomocą długiego łącza, tj. USA do Rosji z pingiem około 100 ms, nie możesz uzyskać prędkości większej niż 5,12 Mbit / s przy domyślnych ustawieniach bufora OpenVPN. Potrzebujesz co najmniej 640 KB bufora, aby uzyskać 50 Mbit / s przez to łącze. UDP będzie działać szybciej, ponieważ nie ma rozmiaru okna, ale również nie będzie działać bardzo szybko.

Jak już można się domyślić, najnowsza wersja OpenVPN nadal używa rozmiaru bufora gniazda 64 KB. Jak powinniśmy rozwiązać ten problem? Najlepszym sposobem jest zabronienie OpenVPN ustawiania niestandardowych rozmiarów buforów. Należy dodać następujący kod do plików konfiguracyjnych serwera i klienta:

sndbuf 0
rcvbuf 0

Autor opisuje, jak przesuwać korekty wielkości bufora do klienta, jeśli sam nie kontrolujesz konfiguracji klienta.

Po wprowadzeniu tych zmian moja przepustowość wzrosła do 20 Mb / s. Potem zobaczyłem, że wykorzystanie procesora było trochę wysokie na jednym rdzeniu, więc usunąłemcomp-lzo (kompresję) z konfiguracji zarówno na kliencie, jak i serwerze. Eureka! Prędkości transferu wzrosły do ​​60 Mb / s przy przedłużeniu i 80 Mb / s w trybie seryjnym.

Mam nadzieję, że pomoże to komuś innemu rozwiązać ich problemy z powolnością OpenVPN!

Elliot B.
źródło
4

Po kilku próbach znalazłem dobre rozwiązanie. W moim przypadku odpowiedź @ Elliota nie pomogła. Googling więcej, znalazłem ten fragment, aby dodać w konfiguracji serwera, który wykonał zadanie

sndbuf 393216
rcvbuf 393216
push "sndbuf 393216"
push "rcvbuf 393216"

Mam mały serwer OpenVPN działający na Raspberry PI3, a teraz dostaję łącze w dół 71 Mb / s i łącze w górę 16 Mb / s . Pobieranie jest ograniczone, ponieważ moc procesora. Obecnie moja konfiguracja jest następująca:

client-to-client
duplicate-cn
keepalive 10 120
cipher AES-128-CBC
#cipher AES-256-CBC <<<---- lowers the speed to around 50Mbps, still not bad
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
tun-mtu 9000

OpenVPN 2.4.0 arm-unknown-linux-gnueabihf z OpenSSL 1.0.2l

Wydaje się to tak dziwne, że nadal istnieje taki problem dotyczący domyślnej konfiguracji bufora.

[EDYCJA] Mój plik client.ovpn ma następującą strukturę:

client
dev tun
proto tcp
remote SERVER.IP.ADDRESS.HERE
resolv-retry infinite
nobind
persist-key
persist-tun
mute-replay-warnings
ns-cert-type server
tun-mtu 9000
key-direction 1
cipher AES-128-CBC
comp-lzo
verb 1
mute 20
<ca>
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN RSA PRIVATE KEY-----
[...]
-----END RSA PRIVATE KEY-----
</key>
<tls-auth>
-----BEGIN OpenVPN Static key V1-----
[...]
-----END OpenVPN Static key V1-----
</tls-auth>
Jądro
źródło
Ustawienie rozmiarów buforów pomogło mi.
Rolf
co umieściłeś w pliku .ovpn klienta?
Patoshi
@Patoshi パ ト シ Skomentowałem sndbuf i recbuf, umieściłem odpowiedni szyfr i kompresję i pozostawiłem parametry domyślne.
Kernel
@ Kernel czy możesz mi pokazać, co masz w swoim kliencie? Robię połączenie OpenVPN z Hongkongu do Nowego Jorku i jest losowo wolne, a czasem rozłącza się. Nie jestem pewien dlaczego.
Patoshi
@Patoshi パ ト シ Zredagowałem swoją odpowiedź, sprawdź ją ponownie. Niemniej jednak sugeruję, abyś zamiast tego spróbował użyć UDP, ponieważ może to pomóc w rozwiązaniu problemu niestabilnego łącza z serwerem. Rzeczywiście, to tylko założenie, że nigdy nie próbowałem porównywać tego rozwiązania w tej sytuacji.
Kernel
1

Według Config używasz TCP jako transportu do tunelu. Rozważ użycie UDP zamiast TCP, ponieważ stosy połączeń TCP w stosie tworzą problemy w przypadku utraty pakietów.

Jako odniesienie zobacz Dlaczego TCP przez TCP jest złym pomysłem

Lairsdragon
źródło
Niestety UDP nie jest dla nas opcją. Musimy upewnić się, że przesyłane pakiety danych dotrą zgodnie z oczekiwaniami. Niemniej jednak wcześniej eksperymentowaliśmy z UDP, a słabe prędkości przesyłania nadal stanowiły problem.
Elliot B.
6
We need to ensure that the data packets we transmit arrive as expected.i czy nie jest to obsługiwane przez tunelowany protokół? Jak myślisz, dlaczego tunel musi być tym, co to wymusza?
Zoredache
Prawdopodobnie tak jest, ale używamy OpenVPN do asynchronicznej implementacji DRBD na duże odległości (tj. Replikacji systemu plików). Integralność danych jest naprawdę ważna, więc chociaż DRBD prawdopodobnie ma wewnętrzne mechanizmy weryfikacji integralności transferu, wolałbym zachować to na TCP. Tak czy inaczej, kiedy mieliśmy go na UDP, nadal mieliśmy niską przepustowość.
Elliot B.
3
@ElliotB. Ponieważ sam DRBD używa TCP do replikacji, przesyła ponownie w przypadku utraty pakietu OpenVPN UDP. Właściwie używając TCP w tym przypadku zrobisz dwa retransfery zamiast jednego ... z których jeden zostanie wyrzucony. Możliwe, że tworzysz dość długie okno bez ruchu DRBD (nawet z powodu zepsutej replikacji). Gdy na trasie pojawi się utrata pakietów, zobaczysz, jak źle to myśli.
Fox
@ Fox Dziękujemy za wyjaśnienie! Rzeczywiście DRBD korzysta z TCP (drbd.linbit.com/users-guide/s-prepare-network.html). Wcześniejsza sugestia Lairsdragon, aby przejść na UDP, nie była wówczas istotna, ponieważ UDP również doświadczał bardzo niskich prędkości transferu, ale od czasu wdrożenia rozwiązania, które zamieściłem powyżej, przeszliśmy na UDP i doświadczyliśmy kolejnego wzrostu wydajności o kilka Mbps.
Elliot B.
1

Mamy dwa serwery międzykontynentalne, które łączą się ze sobą, a prędkości między nimi wahają się wokół 220 Mbit / s.

Wewnątrz tunelu OpenVPN (UDP) prędkości byłyby jednak przeciętne przy 21 Mbit / s - około 10 razy wolniej.

(Między serwerami występuje znaczne opóźnienie: około 130 ms, a transfery zostały zmierzone przy użyciu Iperf3 w trybie TCP).

Wypróbowałem wszystkie sugestie dotyczące odpowiedzi tutaj w tym piśmie i nic nie pomogło.

Jedyną rzeczą, która w końcu pomogła, było to:

--txqueuelen 4000

Zgodnie z podręcznikiem OpenVPN:

–txqueuelen n 
(Linux only) Set the TX queue length on the TUN/TAP interface. Currently defaults to 100.

Po ustawieniu tego parametru na serwerze i kliencie mogłem osiągnąć te same prędkości „bezpośredniego łącza” (~ 250 Mb / s) również pod tunelem OpenVPN.

Już korzystałem rcvbuf 0i sndbuf 0, ale przynajmniej sam , w ogóle nie pomogły.

Te rekomendacje znalazłem na obu: tej stronie na forach OpenVPN , a także na tej stronie w wiki UDPspeeder .

Inna uwaga: byłem w stanie osiągnąć wyższe prędkości przy użyciu transferów UDP w iperf, ale spowodowałoby to również dość dużą utratę pakietów.

Jeśli przez przypadek potrzebujesz użyć VPN do tunelowania dwóch miejsc ze stratnymi linkami, radzę rozważyć użycie jakiegoś tunelu Forward-Error-Correction (FEC) pod samą siecią VPN. Dwa, z którymi udało mi się znaleźć i z którymi pracuję to:

Oba mogą bardzo pomóc w utracie pakietów (przede wszystkim przez zwiększenie przepustowości), a ostatecznie nawet w zwiększeniu przepustowości danych, nawet z dodatkowym narzutem, co jest naprawdę fajne, jeśli mnie zapytasz.

(Jest tak, ponieważ utrata pakietów może naprawdę zepsuć sieć , szczególnie TCP . Patrz strona 6.)

Wolałbym używać OpenVPN na UDP ze wszystkich zwykłych powodów, ale trudno mi poradzić sobie z UDPspeeder, gdy masz zarówno opóźnienie ponad 100 ms, jak i prędkości> 10 Mbit / s.

kcptun jednak działał świetnie z bardzo mało skomplikowany, a właściwie bardzo wzrosły nasze serwery przepustowość ze sobą. =)

Na dłuższy uwaga, tutaj można znaleźć bardziej szczegółowe wyjaśnienia dotyczące szczypanie niektóre części wydajności OpenVPN.

Vinícius M.
źródło
0

Dla mnie miałem serwer VPS z konfiguracją serwera openvpn w Japonii, a moje połączenie klienta korzystało z DDWRT w trybie klienta OpenVPN w Nowym Jorku. Dostawałem tylko 1-2 Mb / s przy połączeniu 100 Mb. Najlepsze, na co mogłem go zoptymalizować, to 5 Mb / s, co wystarczało na to, czego potrzebowałem, i jest tak zoptymalizowane, jak to tylko możliwe.

Moje ustawienia serwera OpenVPN:

tun-mtu 9000
sndbuf 393216
rcvbuf 393216
push "sndbuf 393216"
push "rcvbuf 393216"
comp-lzo
txqueuelen 4000
######
port 10111
proto udp
dev tun
user nobody
group nobody
persist-key
persist-tun
keepalive 10 120
topology subnet
server x.x.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "dhcp-option DNS 1.0.0.1"
push "dhcp-option DNS 1.1.1.1"
push "redirect-gateway def1 bypass-dhcp"
dh none
ecdh-curve prime256v1
#tls-crypt tls-crypt.key 0
crl-verify crl.pem
ca ca.crt
cert server_IzA1QdFzHLRFfEoQ.crt
key server_IzA1QdFzHLRFfEoQ.key
auth SHA256
#cipher AES-128-GCM
#cipher AES-128-CBC
#ncp-ciphers AES-128-GCM
#ncp-ciphers AES-128-CBC
#tls-server
#tls-version-min 1.2
#tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
#tls-cipher TLS-DHE-RSA-WITH-AES-128-CBC-SHA
status /var/log/openvpn/status.log
verb 3

Moje ustawienia klienta DDWRT OpenVPN są również widoczne na moim zrzucie ekranu:

tun-mtu 9000
comp-lzo
##########
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verify-x509-name server_IzA1QdFzHLRFfEoQ name
auth SHA256
auth-nocache
setenv opt block-outside-dns # Prevent Windows 10 DNS leak
verb 3

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

Patoshi パ ト シ
źródło