VPN тормозит: диагностика MTU, фрагментации и потери скорости в туннеле

Снижение скорости при работе через VPN — не баг конкретного клиента, а следствие нескольких механизмов, которые накладываются друг на друга. Основные виновники: превышение MTU и фрагментация пакетов, ретрансмиссии из-за TCP поверх TCP, криптографические накладные расходы и неоптимальная маршрутизация. Ниже — разбор каждого фактора и конкретные шаги диагностики.

MTU и инкапсуляция: где теряются байты​


Каждый VPN-протокол оборачивает исходный IP-пакет в дополнительный заголовок. Стандартный MTU Ethernet — 1500 байт. Когда туннель добавляет свои заголовки, полезная нагрузка должна уменьшиться, иначе пакет не пройдёт.

Структура накладных расходов для типичных протоколов:

ПротоколВнешний заголовокВнутренний overheadРекомендуемый MTU туннеля
WireGuard (UDP)IP (20) + UDP (8)28 (4 type + 8 counter + 16 auth tag)1420
OpenVPN (UDP)IP (20) + UDP (8)~20–40 (зависит от шифра)1400–1440
OpenVPN (TCP)IP (20) + TCP (20)~20–401360–1400
IPsec (ESP, transport)IP (20) + ESP (~20–24)12–16 (IV + ICV)~1400–1420

WireGuard инкапсулирует IP-пакеты поверх UDP. Суммарный overhead для IPv4 составляет 56 байт: 20 (IP) + 8 (UDP) + 28 (заголовок WireGuard-пакета: 4 байта типа, 8 байт счётчика, 16 байт тега аутентификации Poly1305). Теоретический максимум полезной нагрузки — 1444 байта. Однако стандартный MTU интерфейса wg0 установлен в 1420 байт — это консервативное значение с запасом на IPv6 (где IP-заголовок занимает 40 байт вместо 20) и возможную дополнительную инкапсуляцию.

Если клиент отправляет пакет размером 1500 байт через туннель с MTU 1420, происходит одно из двух:

  1. Фрагментация — пакет разбивается на несколько фрагментов. Каждый фрагмент несёт свой IP-заголовок, что увеличивает общий объём трафика.
  2. Отбрасывание — если установлен бит Don't Fragment (DF), пакет отбрасывается, и отправитель получает ICMP-сообщение «Fragmentation Needed». Если ICMP заблокирован файрволом, отправитель не узнает о проблеме и будет повторять попытку.

Диагностика MTU: пошаговая проверка​


Шаг 1. Определение максимального размера пакета без фрагментации​


На Linux используется ping с флагом DF и указанием размера полезной нагрузки:

Bash:
ping -M do -s 1400 -c 5 10.0.0.1

Здесь 10.0.0.1 — адрес VPN-сервера или удалённого хоста за туннелем. Параметр -s задаёт размер данных (без учёта 8 байт ICMP-заголовка и 20 байт IP-заголовка). Если пакет проходит — увеличивайте размер. Если получаете ошибку message too long — уменьшайте.

На Windows аналогичная проверка:

Код:
ping -f -l 1400 10.0.0.1

Флаг -f устанавливает DF, -l задаёт размер данных.

Шаг 2. Вычисление оптимального MTU​


Найдите максимальный размер данных, который проходит без фрагментации. Формула:

Код:
MTU_туннеля = максимальный_размер_данных + 28

28 байт — это IP-заголовок (20) + ICMP-заголовок (8). Для WireGuard результат обычно составляет 1420, для OpenVPN over UDP — около 1400–1440 в зависимости от шифра.

Шаг 3. Проверка на стороне сервера​


Убедитесь, что MTU туннельного интерфейса на сервере совпадает с клиентским:

Bash:
ip link show wg0

В выводе будет строка вида mtu 1420. Если значение отличается от клиентского, пакеты будут фрагментироваться или отбрасываться на одном из концов.

Шаг 4. Проверка прохождения ICMP​


PMTUD (Path MTU Discovery) зависит от ICMP-сообщений типа 3, код 4 (Fragmentation Needed). Если промежуточный маршрутизатор или файрвол блокирует ICMP, клиент не узнает о необходимости уменьшить размер пакета. Проверьте:

Bash:
traceroute -M do -s 1472 10.0.0.1

Если трассировка обрывается на определённом хопе без сообщения о фрагментации — ICMP фильтруется.

Фрагментация IP: скрытый убийца производительности​


Когда пакет превышает MTU следующего звена и бит DF не установлен, маршрутизатор разбивает его на фрагменты. Каждый фрагмент:

  • Несёт полный IP-заголовок (20 байт), что увеличивает общий объём.
  • Обрабатывается независимо: потеря одного фрагмента приводит к отбрасыванию всего исходного пакета.
  • Требует сборки на стороне получателя, что добавляет задержку и нагрузку на CPU.

Для VPN это особенно критично, потому что туннель уже добавил свои заголовки. Пакет, который был бы целым без туннеля, после инкапсуляции превышает MTU физического канала и фрагментируется.

Признаки фрагментации в выводе tcpdump:

Bash:
tcpdump -i eth0 -nn 'ip[6:2] & 0x3fff != 0'

Этот фильтр показывает пакеты с ненулевым offset фрагментации. Если такие пакеты появляются в большом количестве — MTU настроен неверно.

Почему потеря одного фрагмента обходится дорого​


При фрагментации пакета размером 1500 байт на два фрагмента (например, 1480 + 20 байт данных) потеря любого из них приводит к полной потере исходного пакета. На канале с потерей 1% вероятность потери хотя бы одного фрагмента из двух составляет примерно 2%, из трёх — около 3%. Эффективная потеря растёт линейно с числом фрагментов, а TCP интерпретирует это как перегрузку и снижает окно.

TCP поверх TCP: почему OpenVPN на TCP тормозит сильнее​


Когда VPN-туннель работает поверх TCP (например, OpenVPN в режиме --proto tcp), возникает проблема, известная как TCP meltdown:

  1. Приложение отправляет данные через туннель.
  2. Туннельный TCP-сегмент теряется или приходит с задержкой.
  3. TCP туннеля запускает ретрансмиссию и уменьшает congestion window.
  4. Внутренний TCP приложения тоже обнаруживает потерю (таймаут) и уменьшает своё окно.
  5. Два уровня TCP конкурируют за восстановление, многократно снижая пропускную способность.

Результат: при потере даже 1–2% пакетов пропускная способность TCP-туннеля падает в разы сильнее, чем UDP-туннеля при тех же условиях.

WireGuard использует только UDP, что исключает эту проблему. OpenVPN по умолчанию также рекомендует UDP. TCP-режим OpenVPN оправдан только когда UDP полностью заблокирован (корпоративные файрволы, цензура).

Как проверить, что проблема в TCP-туннеле​


Сравните скорость через один и тот же сервер в режимах UDP и TCP. Если разница кратная (в 3–10 раз при нестабильном канале) — проблема именно в TCP meltdown.

Дополнительно можно посмотреть ретрансмиссии:

Bash:
ss -ti | grep retrans

Большое число ретрансмиссий на туннельном интерфейсе подтверждает проблему.

Альтернатива: TCP только для управляющего канала​


Некоторые реализации (например, OpenVPN с --proto tcp на управляющем канале и UDP для данных) позволяют обойти цензуру без полного TCP meltdown. Если UDP заблокирован, но есть возможность использовать TLS-туннель (например, через stunnel или obfsproxy), это предпочтительнее чистого TCP-режима.

Другие факторы потери скорости​


Криптографические накладные расходы​


Шифрование и аутентификация каждого пакета требуют CPU. На современных процессорах с аппаратным ускорением (AES-NI, AVX2) overhead минимален — единицы процентов. На старых CPU или ARM-устройствах без аппаратного ускорения шифрование может стать узким местом.

WireGuard использует ChaCha20-Poly1305, который эффективно работает даже без аппаратного ускорения AES, что делает его быстрым на широком спектре устройств.

Проверка загрузки CPU во время активной передачи:

Bash:
top -bn1 | grep -E 'softirq|ksoftirqd'

Если ksoftirqd потребляет значительную долю CPU при активной передаче через туннель — криптография или сетевой стек не справляются.

Неоптимальная маршрутизация​


VPN-сервер может находиться географически далеко или за несколькими промежуточными хопами. Каждый хоп добавляет задержку. Проверьте RTT до сервера без туннеля:

Bash:
ping -c 20 vpn-server.example.com

Если базовый RTT высокий (>100 мс), туннель не сможет обеспечить низкую задержку независимо от настроек MTU.

Ограничения сервера​


Если VPN-сервер обслуживает много клиентов одновременно, пропускная способность делится между ними. Это особенно актуально для публичных VPN-сервисов. Проверка: сравните скорость в часы пик и в непиковое время.

MTU на промежуточных устройствах​


Некоторые маршрутизаторы, NAT-устройства или облачные балансировщики могут иметь MTU меньше 1500 (например, PPPoE-соединения с MTU 1492, GRE-туннели с MTU 1476). В этом случае даже правильно настроенный MTU туннеля 1420 может оказаться слишком большим.

Типичные значения MTU на различных уровнях:

Тип соединенияMTU
Ethernet1500
PPPoE1492
GRE-туннель1476
Jumbo Frame9000

Если между клиентом и VPN-сервером есть PPPoE-звено, максимальный размер пакета снижается до 1492, и туннельный MTU нужно уменьшить ещё на 8 байт.

Настройка MTU: практические команды​


WireGuard​


MTU задаётся в конфигурации интерфейса или при создании:

Bash:
ip link set wg0 mtu 1420

Или в конфигурационном файле (зависит от дистрибутива и менеджера сетей). Для systemd-networkd:

INI:
[WireGuard]
MTUBytes=1420

OpenVPN​


В конфигурации клиента и сервера:

Код:
tun-mtu 1400

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

Принудительное снижение MSS (TCP Clamping)​


Если PMTUD не работает из-за блокировки ICMP, можно принудительно ограничить MSS для TCP-соединений, проходящих через туннель:

Bash:
iptables -t mangle -A FORWARD -o wg0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1380

Это заставляет TCP-соединения использовать меньший размер сегмента, избегая фрагментации. Значение MSS = MTU туннеля − 40 (IP + TCP заголовки). Для MTU 1420: MSS = 1380.

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

Чек-лист диагностики​


ШагДействиеОжидаемый результат
1ping -M do -s 1400 <server>Пакеты проходят без ошибок
2Увеличивать -s до появления ошибкиОпределить максимальный размер
3ip link show <tunnel_if>MTU совпадает на клиенте и сервере
4tcpdump с фильтром фрагментовФрагментация отсутствует
5traceroute -M doICMP Fragmentation Needed не блокируется
6Сравнить UDP и TCP режимыUDP не даёт кратного падения
7ss -ti на туннельном интерфейсеРетрансмиссии минимальны
8top / mpstat во время нагрузкиCPU не перегружен softirq
9ping до сервера без туннеляБазовый RTT приемлемый

Если после всех проверок скорость остаётся низкой, а MTU, фрагментация и TCP meltdown исключены — проблема, скорее всего, на стороне сервера (перегрузка, ограничение полосы) или в канале между вами и сервером (потери, джиттер). В этом случае стоит попробовать другой сервер или другого провайдера.

Источники​


 
Назад
Верх Низ