Время от времени, мне встречаются темы на форумах, в которых люди соединяют несколько офисов с использованием OpenVPN и получают низкую скорость, сильно ниже скорости канала. У кого-то это может быть 20 Мбит/с при канале в 100 Мбит/с с обеих сторон, а кто-то еле получает и 400 Кбит/с на 2 Мбит/с ADSL/3G и высоким пингом. Зачастую, таким людям советуют увеличить MTU на VPN-интерфейсе до чрезвычайно больших значений, вроде 48000, или же поиграться с параметром mssfix. Частично это помогает, но скорость внутри VPN все еще очень далека от канальной. Иногда все сваливают на то, что OpenVPN — userspace-решение, и это его нормальная скорость, учитывая всякие шифрования и HMAC'и. Абсурд!
Немного истории
На дворе июль 2004 года. Типичная скорость домашнего интернета в развитых странах составляет 256 Кбит/с-1 Мбит/с, в менее развитых — 56 Кбит/с. Ядро Linux 2.6.7 вышло не так давно, а 2.6.8, в котором TCP Window Scale включен по умолчанию, выйдет только через месяц. Проект OpenVPN развивается уже 3 года как, к релизу готовится версия 2.0.
Один из разработчиков добавляет код, который устанавливает буфер приема и отправки сокета по умолчанию в 64 КБ, вероятно, чтобы хоть как-то унифицировать размер буфера между платформами и не зависеть от системных настроек. Однако, в Windows что-то поломали, и указание размера буферов у сокета приводит к странным проблемам с MTU на всех адаптерах в системе. В конечном итоге, в релиз OpenVPN 2.0-beta8 попадает следующий код:
#ifndef WIN32
o->rcvbuf = 65536;
o->sndbuf = 65536;
#endif
Немного технической информации
Если вы пользовались OpenVPN, вы знаете, что он может работать как через UDP, так и через TCP. Если на TCP-сокете установить какое-то маленькое значение буфера, в нашем случае 64 КБ, то алгоритм подстройки TCP-окна просто не сможет выйти за это значение.
Что же это значит? Предположим, вы подключаетесь к серверу в США из России через OpenVPN со стандартными значениями буферов сокета. У вас широкий канал, скажем, 50 МБит/с, но в силу расстояния, пинг составляет 100 мс. Как вы думаете, какой максимальной скорости вы сможете добиться? 5.12 Мбит/с. Вам необходим буфер размером как минимум 640 КБ, чтобы загрузить ваш 50 Мбитный канал.
OpenVPN через UDP будет работать несколько быстрее из-за собственной реализации пересылки пакетов, но тоже далеко не идеально.
Что делать?
Как вы могли уже догадаться, данный размер буфера все еще применяется в самом последнем релизе OpenVPN. Как же нам исправить ситуацию? Самый корректный вариант — запретить OpenVPN менять размер буферов у сокета.
Нужно добавить следующие строки как в серверный, так и в клиентский конфигурационные файлы:
sndbuf 0
rcvbuf 0
Если же по какой-то причине нет возможности поменять конфигурационные файлы клиента, следует отдавать достаточно большие размеры буферов с сервера:
sndbuf 0
rcvbuf 0
push "sndbuf 393216"
push "rcvbuf 393216"
Но у меня Windows!
Если у вас и OpenVPN-сервер работает на Windows-машине, и все клиенты подключаются только из-под Windows, то поздравляю — вам ничего менять не нужно, у вас и так все должно работать быстро.
Вялотекущий баг на багтрекере OpenVPN
Автор: ValdikSS