Как предотвратить зависание TCP-соединения по сети OpenVPN?


19

Новые подробности добавлены в конце этого вопроса; Вполне возможно, что я нацелился на причину.

У меня есть VPN на основе OpenVPN UDP, настроенная в tapрежиме (мне нужно, tapпотому что мне нужна VPN для передачи многоадресных пакетов, что, по-видимому, невозможно в tunсетях) с несколькими клиентами через Интернет. Я испытываю частые зависания TCP-соединения через VPN. То есть я установлю TCP-соединение (например, SSH-соединение, но другие протоколы имеют аналогичные проблемы), и в какой-то момент во время сеанса кажется, что трафик перестанет передаваться через этот сеанс TCP.

Похоже, это связано с точками, в которых происходит большая передача данных, например, если я выполняю lsкоманду в сеансе SSH или если у меня catдлинный файл журнала. Некоторые поиски в Google приводят к появлению нескольких ответов, подобных предыдущему, в случае сбоя сервера , что указывает на то, что вероятным виновником является проблема MTU: что в периоды большого трафика VPN пытается отправлять пакеты, которые отбрасываются где-то в каналах между Конечные точки VPN. Приведенный выше ответ предлагает использовать следующие параметры конфигурации OpenVPN для смягчения проблемы:

fragment 1400
mssfix

Это должно ограничить MTU, используемый в VPN, до 1400 байт и зафиксировать максимальный размер сегмента TCP, чтобы предотвратить генерацию любых пакетов большего размера. Кажется, это немного смягчает проблему, но я все еще часто вижу зависания. Я использовал несколько размеров в качестве аргументов для fragmentдирективы: 1200, 1000, 576, все с похожими результатами. Я не могу думать о какой-либо странной сетевой топологии между двумя сторонами, которая могла бы вызвать такую ​​проблему: VPN-сервер работает на машине pfSense, подключенной напрямую к Интернету, и мой клиент также подключен напрямую к Интернету в другом месте.

Еще одна странная часть головоломки: если я запускаю tracepathутилиту, то, похоже, это помогает решить проблему. Примерный прогон выглядит так:

[~]$ tracepath -n 192.168.100.91
 1:  192.168.100.90                                        0.039ms pmtu 1500
 1:  192.168.100.91                                       40.823ms reached
 1:  192.168.100.91                                       19.846ms reached
     Resume: pmtu 1500 hops 1 back 64 

Вышеуказанный запуск выполняется между двумя клиентами по VPN: я инициировал трассировку от 192.168.100.90пункта назначения 192.168.100.91. Оба клиента были настроены fragment 1200; mssfix;в попытке ограничить MTU, используемый на ссылке. Представленные выше результаты, по-видимому, позволяют предположить, что tracepathудалось обнаружить MTU пути в 1500 байт между двумя клиентами. Я бы предположил, что он будет несколько меньше из-за настроек фрагментации, указанных в конфигурации OpenVPN. Я нашел этот результат несколько странным.

Тем не менее, даже более странно: если у меня TCP-соединение в остановленном состоянии (например, сеанс SSH с распечаткой каталога в середине), то выполнение tracepathкоманды, показанной выше, приводит к повторному запуску соединения ! Я не могу найти никакого разумного объяснения, почему это так, но я чувствую, что это может указывать на решение, которое в конечном итоге искоренит проблему.

Кто-нибудь есть какие-либо рекомендации для других вещей, чтобы попробовать?

Изменить: я вернулся и посмотрел на это немного дальше, и нашел только более запутанную информацию:

  • Я установил для соединения OpenVPN фрагмент в 1400 байт, как показано выше. Затем я подключился к VPN через Интернет и использовал Wireshark для просмотра пакетов UDP, которые были отправлены на сервер VPN во время задержки. Ни один из них не был больше указанного 1400 байт, поэтому фрагментация работает нормально.

  • Чтобы убедиться, что даже 1400-байтового MTU будет достаточно, я пропинговал сервер VPN с помощью следующей команды (Linux):

    ping <host> -s 1450 -M do
    

    Это (я полагаю) отправляет 1450-байтовый пакет с отключенной фрагментацией (я, по крайней мере, убедился, что это не сработало, если я установил явно слишком большое значение, например, 1600 байт). Они, кажется, работают просто отлично; Я получаю ответы от хозяина без проблем.

Так что, может быть, это не проблема MTU вообще. Я просто не понимаю, что еще это может быть!

Редактировать 2: Кроличья нора только продолжает углубляться: теперь я немного больше изолировал проблему. Похоже, это связано с конкретной ОС, которую использует VPN-клиент. Я успешно продублировал проблему как минимум на трех компьютерах с Ubuntu (версии с 12.04 по 13.04). Я могу надежно продублировать замораживание соединения SSH в течение минуты или около того, просто cat-ing большой файл журнала.

Однако , если я проведу тот же тест, используя компьютер CentOS 6 в качестве клиента, то я не вижу проблемы! Я тестировал ту же версию клиента OpenVPN, что и на машинах с Ubuntu. Я могу catчасами регистрировать файлы, не видя замораживания соединения. Это, кажется, дает некоторое представление о конечной причине, но я просто не уверен, что это за понимание.

Я проверил трафик через VPN с помощью Wireshark. Я не эксперт по TCP, поэтому я не уверен, что делать с мрачными подробностями, но суть в том, что в какой-то момент пакет UDP теряется из-за ограниченной пропускной способности интернет-соединения, что вызывает повторные передачи TCP внутри VPN-туннель. На клиенте CentOS эти повторные передачи происходят правильно, и все идет хорошо. В некоторый момент с клиентами Ubuntu, тем не менее, удаленный конец начинает повторную передачу одного и того же сегмента TCP снова и снова (с задержкой передачи, увеличивающейся между каждой повторной передачей). Клиент отправляет то, что выглядит как действительный TCP ACK, для каждой повторной передачи, но удаленный конец все еще продолжает периодически передавать один и тот же сегмент TCP. Это расширяет до бесконечности и соединение останавливается. Мой вопрос здесь будет:

  • У кого-нибудь есть какие-либо рекомендации по устранению неполадок и / или определению основной причины проблемы TCP? Как будто удаленный конец не принимает сообщения ACK, отправленные VPN-клиентом.

Одно общее отличие между узлом CentOS и различными выпусками Ubuntu состоит в том, что Ubuntu имеет гораздо более свежую версию ядра Linux (от 3.2 в Ubuntu 12.04 до 3.8 в 13.04). Возможно, указатель на какую-то новую ошибку ядра? Я предполагаю, что если бы это было так, то я был бы не единственным, кто столкнулся с проблемой; Я не думаю, что это кажется особенно экзотической установкой.


Маршрутизация многоадресных пакетов по tunсети должна быть возможна посредством запуска демонов многоадресной маршрутизации (таких как pimd ) и использования сервером OpenVPN --topologyопций, настроенных на «подсеть» - см. Руководство
kostix

Указывает ли что-нибудь в журналах VPN-клиент или сервер во время этих проблем?
mgorven

@mgorven: определенно не на клиенте. Я должен сделать некоторую работу, чтобы получить в журналах сервера.
Джейсон Р

@mgorven: у меня наконец-то появилась возможность вернуться к этому. Когда это происходит, в журналах клиента или сервера ничего не происходит. Это действительно сбивает с толку.
Джейсон Р

1
Есть ли вероятность того, что у клиентов, которые замораживаются, есть локальные брандмауэры, которые отбрасывают пакеты, необходимые для фрагментации ICMP, в отличие от тех, которые этого не делают, и, следовательно, правильно фрагментируют?
MadHatter поддерживает Монику

Ответы:


10

Эта команда решает это для меня:

$ sudo ip link set dev tun0 mtu 1350 && echo ":)"

Вы можете проверить настройки tun0 с помощью

$ ip a s

Ура!


На стороне клиента или сервера ??
Мэтт

Большое спасибо! @ Matt, это зависит от того, где находится проблема. Для нас это было на сервере, но это может быть на стороне клиента. Также значение может отличаться, вы можете проверить, ping <host> -s 1350 -M doчтобы найти правильное значение
Eino Gourdin

2

Отключите масштабирование окна в TCP с помощью:

sysctl -w net.ipv4.tcp_window_scaling=0

После этого SSH для систем Debian / Ubuntu через VPN работают нормально для меня.


0

В Windows, используя Putty, вы должны изменить MTU, перейдя в локальное соединение для vpn-соединения -> подробности о сетевом интерфейсе (TAP windows Adapter или что-то в этом роде) -> Дополнительно -> Свойства -> MTU (измените его на что-то ниже 1500). Возможно, вам придется восстановить. У меня это работало на Windows и Putty


-1

Похоже, это проблема буферизации. У меня та же проблема, и я могу избежать ее, ограничивая скорость передачи. Не лучший способ, но он может помочь кому-то найти лучшее решение для этого.

Смотрите обновление 1 здесь: Как предотвратить зависание SSH через соединение клиента openvpn с клиентом

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.