VPN медленно работает: диагностика по шагам
«VPN тормозит» — это симптом, а не диагноз, и за ним может стоять с десяток разных причин: от перегруженного процессора сервера до банально неправильного MTU. Проблема в том, что большинство инструкций в интернете начинают сразу с экзотики — congestion control, offloading, кастомные sysctl — хотя в девяти случаях из десяти виновата одна из трёх банальных вещей. Ниже — чек-лист, который стоит проходить по порядку: от простого к сложному, без пропуска шагов.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Шаг 0: убедитесь, что проблема действительно в VPN
Прежде чем лезть в конфиги, отделите VPN от остального. Отключите туннель и измерьте скорость напрямую до того же сервера (или до любого стороннего) через speedtest-cli или обычный сайт спидтеста. Если без VPN тоже медленно — дело в интернет-канале клиента или в маршруте до сервера, и вся дальнейшая диагностика туннеля бессмысленна.
Дальше сравните с другим сервером или локацией, если есть доступ. Если VPN медленный именно и только на одном сервере — проблема на его стороне (CPU, диск, сеть хостера). Если медленно везде — проблема на стороне клиента: драйвер сетевой карты, антивирус с DPI-инспекцией трафика, Wi-Fi вместо кабеля, или провайдер клиента режет VPN-трафик шейпингом.
Отдельно проверьте время суток и загрузку. Разница в 2-3 раза между утром и вечером почти всегда означает переполненный аплинк у провайдера или у хостера, а не проблему в настройках. Здесь же полезно сразу снять базовые метрики: пинг и джиттер без нагрузки, чтобы позже сравнивать с показателями под нагрузкой — методика измерения описана в статье как измерить реальный пинг до сервера.
Шаг 1: CPU сервера — самая частая причина
WireGuard и OpenVPN шифруют и расшифровывают каждый пакет, и это стоит процессорного времени. На слабом VPS с 1 vCPU или на переподписанном (oversold) сервере хостера именно CPU чаще всего оказывается узким местом — вы упираетесь не в канал, а в то, сколько пакетов в секунду успевает обработать одно ядро.
Проверка простая:
# загрузка во время активной передачи через VPN
top
# или подробнее по ядрам
mpstat -P ALL 1 5
Если во время теста скорости одно ядро (обычно то, что обслуживает процесс wg или openvpn) уходит в 100%, а остальные простаивают — это и есть узкое место. WireGuard работает в ядре и обычно однопоточный по одному туннелю, OpenVPN в userspace ещё требовательнее к CPU при прочих равных.
Что делать:
- Проверить steal time на VPS:
top→ колонка%st. Если она заметно выше нуля, у хостера переподписан процессор, и это не лечится настройками — только сменой сервера или тарифа. - Для OpenVPN — переключиться с AES-256-CBC на AES-256-GCM (использует AES-NI эффективнее и параллелится лучше) или рассмотреть переход на WireGuard, который в среднем заметно легче по CPU при сравнимом уровне защиты — подробное сравнение в статье WireGuard или OpenVPN: что выбрать для сервера.
- Проверить, что AES-NI вообще доступен процессору:
grep aes /proc/cpuinfo. Если флага нет (редкость на современном железе, но встречается на старых или урезанных виртуальных инстансах), шифрование идёт программно и упирается в CPU гораздо раньше. - Замерить сырую производительность шифрования:
openssl speed -evp aes-256-gcm. Число само по себе мало что скажет без сравнения, но если оно в разы ниже, чем на соседнем современном сервере — это сигнал.
Если на слабом тарифе стабильно упираетесь в CPU при обычной нагрузке (не при DDoS, а просто при повседневном использовании) — это повод перейти на сервер с более производительными ядрами, а не бесконечно тюнинговать конфиг.
Арендуйте сервер под свои задачи!
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверШаг 2: выбор шифрования и протокола
Даже если CPU не является узким местом, выбор шифра и протокола ощутимо влияет на латентность и пропускную способность, особенно на слабых каналах или мобильном интернете.
Ориентировочная разница между вариантами (порядок величины, не точные цифры — на вашем железе и канале будет своё):
| Вариант | Накладные расходы | Когда уместен |
|---|---|---|
| WireGuard (ChaCha20-Poly1305) | Минимальные | Мобильные клиенты, слабый CPU, по умолчанию |
| OpenVPN + AES-256-GCM | Средние | Нужна гибкость OpenVPN, есть AES-NI |
| OpenVPN + AES-256-CBC | Выше | Устаревшие клиенты, легаси-инфраструктура |
| OpenVPN по TCP | Заметно выше при потерях пакетов | Только если UDP жёстко блокируется |
Последняя строка отдельно важна: OpenVPN по умолчанию рекомендуют гонять по UDP, но при блокировках его иногда заворачивают в TCP. Проблема в том, что TCP-в-TCP (приложение уже открывает TCP-соединение поверх VPN, который сам работает по TCP) даёт эффект «TCP meltdown» — при малейшей потере пакетов оба уровня TCP начинают пересчитывать окна одновременно, и скорость проседает нелинейно. Если это ваш случай — переходите на UDP везде, где возможно, либо на WireGuard, который принципиально работает только по UDP.
Проверить текущий шифр в OpenVPN — в конфиге сервера и клиента должна совпадать директива cipher (или data-ciphers в новых версиях 2.5+):
# server.conf / client.conf
data-ciphers AES-256-GCM:CHACHA20-POLY1305
data-ciphers-fallback AES-256-GCM
Шаг 3: MTU и фрагментация пакетов
Это один из самых недооценённых источников «медленного VPN» — не потому что он редкий, а потому что симптомы обманчивы: скорость на маленьких файлах и в браузере нормальная, а вот скачивание больших файлов, видеозвонки или загрузка тяжёлых страниц заикаются. Причина — фрагментация пакетов из-за неверного MTU.
VPN добавляет к каждому пакету заголовки (у WireGuard это обычно порядка 60 байт, у OpenVPN — больше, в зависимости от протокола и шифра). Если MTU туннеля выставлен как у обычного Ethernet (1500), пакеты, которые были на пределе снаружи, внутри туннеля превышают лимит и либо фрагментируются (что дорого по CPU и снижает скорость), либо теряются целиком, если где-то по пути стоит блокировка ICMP fragmentation needed.
Диагностика — классический бинарный поиск через ping с запретом фрагментации:
# Linux/macOS: -M do запрещает фрагментацию, -s задаёт размер данных
ping -M do -s 1472 8.8.8.8
# Windows: -f запрещает фрагментацию, -l задаёт размер
ping -f -l 1472 8.8.8.8
Уменьшайте размер, пока пакет не перестанет проходить с ошибкой Packet needs to be fragmented but DF set — это и есть верхняя граница MTU минус 28 байт (заголовки IP+ICMP). Проделайте то же самое поверх поднятого VPN-туннеля, направляя пинг на адрес внутри VPN-подсети — так вы найдёте эффективный MTU именно для туннелированного трафика.
Типичные рабочие значения, с которых стоит начинать подбор:
- WireGuard:
MTU = 1420в конфиге интерфейса (wg0.conf, параметрMTU), иногда приходится опускать до 1380-1400 на мобильных сетях или при двойном туннелировании. - OpenVPN:
tun-mtu 1400плюсmssfix 1360в конфиге сервера и клиента, чтобы принудительно подрезать MSS TCP-соединений внутри туннеля.
# wg0.conf
[Interface]
MTU = 1420
# openvpn server.conf / client.conf
tun-mtu 1400
mssfix 1360
Если после правки MTU крупные закачки перестали заикаться, а мелкие запросы как работали, так и работают — вы попали точно в цель.
Шаг 4: провайдер, маршрут и качество сети хостера
Если CPU свободен, шифрование адекватное, а MTU выставлен верно — переходите на уровень сети. Здесь два независимых фактора: маршрут от клиента до сервера и качество сети у самого хостера.
Маршрут проверяется через mtr (лучше, чем однократный traceroute, потому что показывает потери и джиттер на каждом хопе за время наблюдения, а не разовый снимок):
mtr -rw -c 100 your-server-ip
Смотрите на столбец Loss% — потери больше 1-2% на промежуточном хопе, которые не повторяются на следующем, обычно можно игнорировать (особенность ICMP-приоритизации на транзитных роутерах). А вот стабильные потери на всех хопах после определённой точки и высокий джиттер (StDev) — реальная проблема маршрута, обычно на стороне upstream-провайдера хостера или на пиринге между сетями клиента и сервера.
Что можно сделать:
- Если маршрут кривой именно до конкретной локации — попробовать сервер в другом регионе. Разница между российским и зарубежным провайдером по факту сводится именно к качеству маршрутов и пирингов для конкретной пары «откуда вы» → «куда сервер», универсально лучшего варианта не существует.
- Проверить, не упирается ли скорость в лимит тарифа. Многие бюджетные VPS продаются с ограничением полосы (например, 100 Мбит/с гарантированных, остальное — best effort), и в часы пик вы физически не получите больше заявленного. Это стоит уточнять у хостера явно, а не полагаться на маркетинговые «безлимит».
- Отдельно замерить пропускную способность именно до сервера, а не до интернета в целом, через
iperf3(если есть второй сервер или доступ к серверу для установкиiperf3 -s):
# на сервере
iperf3 -s
# на клиенте
iperf3 -c your-server-ip -t 30 -P 4
Параллельные потоки (-P 4) помогают отличить лимит одного TCP-соединения (упирается в congestion control) от лимита канала целиком.
Шаг 5: congestion control и TCP-настройки сервера
Это последний по порядку шаг не случайно — он даёт эффект только если всё предыдущее уже в порядке, а часто его пробуют первым и разочаровываются в результате. Congestion control влияет на то, как быстро TCP-соединение «разгоняется» и как ведёт себя при потере пакетов — это особенно заметно на маршрутах с высокой задержкой (трансатлантические, трансконтинентальные) и при периодических потерях пакетов.
Проверить текущий алгоритм на сервере:
sysctl net.ipv4.tcp_congestion_control
# список доступных в вашем ядре
sysctl net.ipv4.tcp_available_congestion_control
BBR на маршрутах с высокой задержкой и заметными потерями пакетов зачастую даёт более стабильную скорость, чем классический CUBIC, который трактует любую потерю пакета как сигнал перегрузки и резко режет окно — а на дальних маршрутах потери время от времени случаются даже без реальной перегрузки. Включается на современных ядрах Linux (4.9+) так:
# /etc/sysctl.conf или /etc/sysctl.d/99-bbr.conf
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# применить без перезагрузки
sysctl -p
Важная оговорка: это влияет на TCP-соединения самого сервера. На WireGuard, который работает по UDP и не имеет собственного congestion control, настройка на сам туннель не влияет напрямую — зато влияет на TCP-трафик приложений внутри туннеля, потому что congestion control учитывается конечными точками TCP-соединения, а не транзитными узлами.
Ещё один параметр, который стоит проверить на серверах с несколькими одновременными клиентами — размеры буферов приёма/отправки:
net.core.rmem_max = 26214400
net.core.wmem_max = 26214400
net.ipv4.tcp_rmem = 4096 87380 26214400
net.ipv4.tcp_wmem = 4096 65536 26214400
Увеличение буферов помогает на каналах с высоким произведением задержки на пропускную способность (bandwidth-delay product) — чем дальше и «толще» канал, тем больше данных должно помещаться «в полёте» до получения подтверждения. Значения выше — отправная точка для сервера с гигабитным каналом и задержками в пределах 100-200 мс; менять их без замеров iperf3 до и после — гадание, а не тюнинг.
Арендуйте сервер под свои задачи!
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
С чего начинать диагностику, если непонятно, где проблема?
Всегда с шага 0 — сравнения скорости с VPN и без него, на разных серверах и в разное время суток. Это отсекает половину гипотез за пять минут и экономит часы блуждания по sysctl.
WireGuard работает медленнее OpenVPN — это нормально?
Обычно наоборот: WireGuard легче по CPU и быстрее на большинстве сценариев за счёт более простого протокола и работы в ядре. Если у вас обратная картина — проверьте MTU отдельно для каждого протокола, они часто настроены по-разному, и именно рассинхрон MTU — самая частая причина такого парадокса.
Правка MTU ничего не изменила — что дальше?
Значит, проблема, скорее всего, не в фрагментации. Возвращайтесь к шагам 1 и 4 — проверьте загрузку CPU под нагрузкой и снимите mtr заново именно во время теста скорости, а не в состоянии покоя.
BBR можно включать всегда «на всякий случай»?
Да, он безопасен и в большинстве случаев либо не хуже CUBIC, либо заметно лучше на дальних маршрутах. Специфических противопоказаний для VPN-сервера нет, но и чудес на коротких маршрутах без потерь пакетов не ждите — разницы почти не будет.
Как понять, что дело не в настройках, а просто в слабом тарифе?
Если под нагрузкой CPU стабильно на пределе, а steal time (%st в top) заметно выше нуля даже без пиковой нагрузки — это архитектурное ограничение тарифа, и никакая настройка шифрования или MTU физически не даст больше ресурсов, которых нет.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →