Очень низкая пропускная способность TCP OpenVPN (порт 100 Мбит, низкая загрузка ЦП)

27

Я испытываю чрезвычайно медленную скорость передачи OpenVPN между двумя серверами. На этот вопрос я позвоню на серверы Сервер А и Сервер Б.

Сервер A и сервер B работают под управлением CentOS 6.6. Оба расположены в центрах обработки данных с линией 100 Мбит, и передача данных между двумя серверами за пределами OpenVPN выполняется на скорости около 88 Мбит / с.

Однако, когда я пытаюсь передать любые файлы через соединение OpenVPN, которое я установил между Сервером A и Сервером B, я получаю пропускную способность около 6,5 Мбит / с.

Результаты теста от 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

Помимо этих тестов OpenVPN iperf, оба сервера практически полностью простаивают с нулевой нагрузкой.

Серверу А присвоен IP 10.0.0.1, и он является сервером OpenVPN. Серверу B присвоен IP 10.0.0.2, и он является клиентом OpenVPN.

Конфигурация OpenVPN для Сервера A выглядит следующим образом:

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

Конфигурация OpenVPN для Сервера B выглядит следующим образом:

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

Что я заметил:

1. Моей первой мыслью было узкое место на процессоре сервера. OpenVPN является однопоточным, и оба этих сервера работают на процессорах Intel Xeon L5520, которые не являются самыми быстрыми. Тем не менее, я topвыполнил команду во время одного из тестов iperf и нажал, 1чтобы посмотреть загрузку ЦП ядром, и обнаружил, что загрузка ЦП была очень низкой для каждого ядра:

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. Время пинга значительно увеличивается по туннелю OpenVPN во время работы iperf. Когда iperf не работает, время пинга по туннелю постоянно составляет 60 мс (нормально). Но когда iperf работает и интенсивно загружается, время пинга становится нестабильным. Ниже вы можете увидеть, насколько стабильно время пинга до 4-го пинга, когда я начал тестирование 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. Как упоминалось выше, я запускал iperf за пределами туннеля OpenVPN, и пропускная способность была нормальной - ~ 88 Мбит / с.

Что я пробовал:

1. Я подумал, что сжатие может привести к загрязнению, поэтому я отключил сжатие, удалив comp-lzoоба конфига и перезапустив OpenVPN. Без улучшения.

2. Несмотря на то, что ранее я обнаружил, что загрузка ЦП была низкой, я думал, что шифр по умолчанию может быть слишком интенсивным, чтобы система не отставала от него. Поэтому я добавил cipher RC2-40-CBCоба конфига (очень легкий шифр) и перезапустил OpenVPN. Без улучшения.

3. Я читал на различных форумах о том, как настройка фрагмента, mssfix и mtu-tun может помочь с производительностью. Я играл с несколькими вариантами, как описано в этой статье , но, опять же, без улучшений.

Любые идеи о том, что может быть причиной такой низкой производительности OpenVPN?

Эллиот Б.
источник
Помогают ли здесь какие-либо ссылки, комментарии? forums.openvpn.net/topic10593.html
Мэтт,
Большинство предложений здесь есть вещи, которые я уже попробовал: 1. проверить узкое место ЦП, 2. проверить скорость передачи без VPN, 3. переключить сжатие, 4. выбрать более быстрый шифр и т. Д. Не повезло ни с одним из них пока: - / Это странно. Помимо медленной скорости и высокого / нестабильного времени пинга, я не вижу других указаний на то, где может быть узкое место.
Эллиот Б.
Обе машины находятся в одном центре обработки данных? 60 мс в одном и том же дата-центре довольно высоки. Я мог бы попробовать, cipher noneхотя я сомневаюсь, что это поможет.
Зоредаче
@Zoredache Извините - я не знал, где расположены серверы - сервер A находится в Далласе, а сервер B - в Сиэтле.
Эллиот Б.
Вы проверили MTU? Esp: параметры tun-mtu, фрагмента и mssfix? Документация
Lenniey

Ответы:

26

После большого количества настроек Google и настроек я нашел решение. Сейчас у меня стабильная скорость 60 Мбит / с и скорость до 80 Мбит / с. Это немного медленнее, чем скорость передачи, которую я получаю за пределами VPN, но я думаю, что это так же хорошо, как и получится.

Первым шагом была настройка sndbuf 0и rcvbuf 0в конфигурации OpenVPN как для сервера, так и для клиента.

Я внес это изменение, увидев предложение сделать это в общедоступном посте на форуме (который является переводом на русский язык оригинального поста на русском языке ), который я процитирую здесь:

Это июль 2004 года. Обычная скорость домашнего интернета в развитых странах составляет 256-1024 Кбит / с, в менее развитых странах - 56 Кбит / с. Linux 2.6.7 был выпущен не так давно, а 2.6.8, где TCP Windows Size Scaling будет включен по умолчанию, выпущен только через месяц. OpenVPN находится в активной разработке уже 3 года, версия 2.0 практически выпущена. Один из разработчиков решает добавить код для буфера сокетов, я думаю, чтобы унифицировать размеры буферов между операционными системами. В Windows что-то не так с MTU адаптеров, если установлены нестандартные размеры буферов, поэтому, в конце концов, он преобразуется в следующий код:

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

Если вы использовали OpenVPN, вы должны знать, что он может работать через TCP и UDP. Если для настраиваемого значения буфера TCP-сокета установлено значение 64 КБ, алгоритм масштабирования размера окна TCP не может изменить размер окна более чем на 64 КБ. Что это значит? Это означает, что если вы подключаетесь к другому VPN-сайту по длинному толстому каналу, например, из США в Россию с пингом около 100 мс, вы не сможете получить скорость более 5,12 Мбит / с со стандартными настройками буфера OpenVPN. Вам нужно как минимум 640 КБ буфера, чтобы получить 50 Мбит / с по этой ссылке. UDP будет работать быстрее, потому что у него нет размера окна, но он также не будет работать очень быстро.

Как вы уже, наверное, догадались, последний выпуск OpenVPN по-прежнему использует размер буфера сокета 64 КБ. Как мы должны исправить эту проблему? Лучший способ - запретить OpenVPN устанавливать собственные размеры буфера. Вы должны добавить следующий код в конфигурационные файлы сервера и клиента:

sndbuf 0
rcvbuf 0

Далее автор описывает, как передать клиенту настройки размера буфера, если вы сами не управляете конфигурацией клиента.

После того, как я внес эти изменения, моя пропускная способность возросла до 20 Мбит / с. Затем я увидел, что загрузка ЦП на одном ядре была немного высокой, поэтому я удалил comp-lzo(сжатие) из конфигурации как на клиенте, так и на сервере. Эврика! Скорость передачи данных выросла до 60 Мбит / с, а скорость 80 Мбит / с.

Я надеюсь, что это поможет кому-то решить свои проблемы с медлительностью OpenVPN!

Эллиот Б.
источник
4

После нескольких попыток я нашел хорошее решение. В моем случае ответ @ Elliot не помог. Погуглив больше, я обнаружил этот фрагмент, чтобы добавить в конфигурацию сервера, который сделал работу

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

У меня есть небольшой сервер OpenVPN, работающий на Raspberry PI3, и теперь я получаю нисходящую линию связи 71 Мбит / с и восходящую линию связи 16 Мбит / с . Загрузка ограничена, так как мощность процессора. Прямо сейчас моя конфигурация следующая:

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 с OpenSSL 1.0.2l

Это настолько странно, что такая проблема с настройкой буфера по умолчанию все еще существует.

[РЕДАКТИРОВАТЬ] Мой файл client.ovpn имеет следующую структуру:

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>
ядро
источник
Установка размеров буфера мне помогла.
Рольф
что вы положили в клиентский файл .ovpn?
Патоши シ ト シ
@Patoshi パ ト シ Я закомментировал sndbuf и recbuf, поставил соответствующий шифр и сжатие и оставил параметры по умолчанию.
Ядро
@ Кернел, можешь показать мне, что у тебя есть в клиенте? Я делаю соединение OpenVPN из Гонконга в Нью-Йорк, и оно случайно медленно, а иногда и отключается. Я не уверен почему.
Патоши シ ト シ
@Patoshi パ ト シ Я отредактировал свой ответ, проверь его снова. Тем не менее, я бы посоветовал вам попробовать использовать UDP вместо этого, так как это может помочь вам решить проблему нестабильной связи с вашим сервером. На самом деле, это всего лишь предположение, я никогда не пытался сравнить это решение в этой ситуации.
Ядро
1

В соответствии с конфигурацией вы используете TCP в качестве транспорта для туннеля. Подумайте об использовании UDP вместо TCP, так как стекированные соединения TCP-палатки создают проблемы в ситуациях потери пакетов.

В качестве ссылки смотрите, почему TCP через TCP - плохая идея

Lairsdragon
источник
К сожалению, UDP не подходит для нас. Мы должны гарантировать, что пакеты данных, которые мы передаем, прибывают как ожидалось. Тем не менее, мы поэкспериментировали с UDP раньше, и низкая скорость передачи данных оставалась проблемой.
Эллиот Б.
6
We need to ensure that the data packets we transmit arrive as expected.и разве это не обрабатывается протоколом, который туннелируется? Как вы думаете, почему ваш туннель должен обеспечивать это?
Зоредаче
Вероятно, это так, но мы используем OpenVPN для реализации асинхронного DRBD на большом расстоянии (т. Е. Репликации файловой системы). Целостность данных действительно важна, поэтому, хотя DRBD, вероятно, имеет внутренние механизмы для проверки целостности передачи, я бы предпочел оставить ее на TCP. В любом случае, когда у нас было это по UDP, у нас все еще была низкая пропускная способность.
Эллиот Б.
3
@ElliotB. Поскольку DRBD сам использует TCP для репликации, он выполнит повторную передачу в случае потери UDP-пакета OpenVPN. На самом деле, используя TCP в этом случае, вы сделаете два ретранслятора вместо одного ... один из которых будет отброшен. Возможно, вы создаете довольно длинное окно без трафика DRBD (даже из-за этого нарушается репликация). Как только вы получите потерю пакетов на маршруте, вы увидите, насколько это плохо.
Фокс
@Fox Спасибо за разъяснения! Действительно, DRBD использует TCP (drbd.linbit.com/users-guide/s-prepare-network.html). Ранее предложение Lairsdragon о переходе на UDP не имело значения в то время, потому что UDP также испытывал чрезвычайно низкие скорости передачи, но с тех пор, как мы внедрили решение, которое я разместил выше, мы переключились на UDP и испытали еще один прирост производительности на несколько Мбит / с.
Эллиот Б.
1

У нас есть два межконтинентальных сервера, которые связаны друг с другом, скорость между ними колеблется около 220 Мбит / с.

Однако в туннеле (UDP) OpenVPN скорость будет в среднем 21 Мбит / с - примерно в 10 раз медленнее.

(Между серверами существует значительная задержка: около 130 мс, и передачи измерялись с помощью Iperf3 в режиме TCP.)

Перепробовал все предложения по ответам здесь на момент написания статьи, и ничего не помогло.

Единственное, что в итоге помогло, это немного:

--txqueuelen 4000

Согласно справочному руководству OpenVPN:

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

После установки этого параметра на сервере и клиенте я смог достичь тех же скоростей прямого соединения (~ 250 Мбит / с) также в туннеле OpenVPN.

Я уже использовал rcvbuf 0и sndbuf 0, но, по крайней мере, один , они не помогли вообще.

Я нашел эти рекомендации как на этой странице на форумах OpenVPN , так и на этой странице в вики UDPspeeder .

С другой стороны: мне удалось достичь более высоких скоростей, используя UDP-передачу в iperf, но это также повлекло бы за собой достаточно высокую потерю пакетов.

Если по какой-то причине вам понадобится использовать VPN для туннелирования в двух местах с потерями, я бы посоветовал рассмотреть возможность использования своего рода туннеля прямого исправления ошибок (FEC) под самой VPN. Два из них мне удалось найти и работать с:

  • Вышеупомянутый UDPspeeder , который туннелирует соединения UDP;
  • kcptun , который туннелирует TCP-соединения;

И то, и другое может сильно помочь с потерей пакетов (прежде всего, потратив больше пропускной способности) и, в конечном итоге, даже привести к более высокой пропускной способности данных, даже с дополнительными издержками, что очень удобно, если вы спросите меня.

(Это потому, что потеря пакетов может действительно испортить сеть , особенно TCP . См. Стр. 6.)

Я бы предпочел использовать OpenVPN в UDP по всем обычным причинам, но мне было трудно иметь дело с UDPspeeder, когда у вас есть задержка более 100 мс и скорость> 10 Мбит / с.

kcptun однако, работал большой с очень небольшой настройки, и на самом деле действительно увеличили наши серверы пропускной способности друг с другом. знак равно

В расширенной заметке, здесь вы можете найти более подробные объяснения о настройке некоторых частей производительности OpenVPN.

Виниций М
источник
0

Для меня у меня был VPS-сервер с настройкой openvpn-сервера в Японии, и мое клиентское соединение использовало DDWRT в режиме клиента OpenVPN в Нью-Йорке. Я получал только 1-2 Мбит / с при соединении 100 Мбит. Лучшее, что я смог оптимизировать для этого, было 5 Мбит / с, чего было достаточно для того, что мне было нужно, и это было настолько оптимизировано, насколько я могу, я верю.

Настройки моего 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

Мои настройки клиента DDWRT OpenVPN также видны на моем скриншоте:

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

введите описание изображения здесь

введите описание изображения здесь

Патоши パ ト シ
источник