← Назад в базу знаний

Почему VPN умирает при работе с UDP: разбор QoS и MTU

Почему VPN умирает при работе с UDP: разбор QoS и MTU

Суть проблемы

VPN-туннель работает — и вдруг всё пропало. Пинг идёт, но пакеты с данными не проходят. Или проходят, но с дикими задержками. Знакомая картина? Скорее всего, вы упёрлись в две вещи: QoS-деприоритизацию UDP-трафика и фрагментацию на уровне MTU.

UDP не имеет механизма восстановления. Потерял пакет — всё, данные ушли в никуда. TCP хотя бы перешлёт. А тут — тишина. Особенно это заметно в WireGuard, где весь трафик идёт по UDP.

Как работают очереди на маршрутизаторах

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

Тут вступает в игру QoS. Маршрутизатор смотрит на заголовки пакетов и решает: кому жить, а кому умереть. UDP-трафик от VPN часто помечается как низкоприоритетный. Почему? Потому что провайдеры считают, что UDP — это стриминг, торренты или VoIP. А это — нагрузка на сеть.

Пример: у вас канал 100 Мбит/с. Вы скачиваете торрент — это TCP, он адаптируется. А ваш WireGuard-туннель шлёт UDP-пакеты. Роутер видит UDP — и режет его до 10 Мбит/с. VPN работает, но скорость — как через dial-up.

MTU и фрагментация — тихий убийца

MTU — максимальный размер пакета, который может пройти через интерфейс без фрагментации. Стандарт для Ethernet — 1500 байт. Но VPN добавляет свои заголовки.

WireGuard: 60 байт на заголовок. OpenVPN: до 80 байт. IPSec: 50-60 байт. Итого — если ваш пакет 1500 байт, то внутри туннеля он становится 1560. А это уже больше, чем MTU.

Что происходит? Пакет фрагментируется. Роутер режет его на куски. Каждый кусок отправляется отдельно. Потеряли один кусок — потеряли весь пакет. А с учётом QoS, который и так не любит UDP... Получаем полный отказ.

Как проверить MTU

Не гадайте. Проверяйте.

```bash

ping -M do -s 1472 8.8.8.8

```

Флаг `-M do` запрещает фрагментацию. Размер 1472 — это 1500 минус 28 байт заголовка ICMP. Если пинг проходит — MTU 1500 доступен. Нет — уменьшайте.

Для WireGuard есть более точный метод:

```bash

wg show

```

Смотрим на `transfer` и `received`. Если передача растёт, а получение стоит на месте — проблема с MTU.

Настройка MTU в WireGuard

В конфиге WireGuard можно задать MTU напрямую:

```ini

[Interface]

PrivateKey = ваш_ключ

Address = 10.0.0.2/24

MTU = 1420

```

Почему 1420? Это 1500 минус 80 байт на заголовки WireGuard. Безопасный вариант. Но можно подобрать точнее.

На Linux можно проверить оптимальный MTU:

```bash

ping -M do -s 1392 10.0.0.1

```

Если пакет 1392 проходит, а 1400 нет — ставьте MTU 1420. Запас в 28 байт на заголовки IP.

QoS-маркировка — ваш друг

Проблема QoS решается маркировкой пакетов. В WireGuard можно задать fwmark:

```ini

[Interface]

PrivateKey = ваш_ключ

Address = 10.0.0.2/24

MTU = 1420

Table = off

PostUp = wg set %i fwmark 0x1234

```

А затем настроить правила маршрутизации:

```bash

ip rule add not fwmark 0x1234 table 100

ip route add default via 192.168.1.1 table 100

```

Это заставит пакеты WireGuard идти по отдельному маршруту, минуя очереди, которые душат UDP.

Для OpenVPN есть опция `mark`:

```

mark 0x1234

```

Но это работает только на Linux.

Настройка DSCP

DSCP — поле в заголовке IP, которое говорит маршрутизатору о приоритете. Вы можете выставить его вручную.

Для WireGuard на Linux:

```bash

iptables -t mangle -A OUTPUT -p udp --dport 51820 -j DSCP --set-dscp 46

```

DSCP 46 — это Expedited Forwarding. Максимальный приоритет. Но осторожно: некоторые провайдеры сбрасывают такие метки. Проверяйте на практике.

Реальный кейс: офисная сеть

Был у меня клиент — офис на 50 человек. Все работают через WireGuard-туннель к серверу в другом городе. Всё работало, пока не начали проводить видеоконференции.

Симптомы: пинг до сервера 30 мс, но скорость — 2 Мбит/с вместо 50. Работать невозможно.

Диагностика: проверил MTU. Оказалось — PPPoE-подключение, MTU 1492. А WireGuard с MTU 1420 — всё равно фрагментировался, потому что добавил свои заголовки поверх.

Решение: выставил MTU 1400 в конфиге WireGuard. Проблема ушла. Но через неделю вернулась — провайдер включил QoS, который резал UDP-трафик.

Победили маркировкой DSCP. В итоге — стабильные 45 Мбит/с через туннель.

Кейс: домашний роутер

Другой случай. Домашний роутер Asus с прошивкой Merlin. WireGuard-туннель к VPS. Скорость — 30 Мбит/с при канале 100.

Проблема оказалась в том, что роутер обрабатывал UDP-трафик через software-очередь. Аппаратное ускорение (NAT acceleration) не работало для VPN-трафика.

Решение: отключил аппаратное ускорение для WireGuard-интерфейса. Скорость выросла до 80 Мбит/с. Но пинг подрос с 15 до 25 мс.

Кейс: мобильный оператор

Мобильные сети — отдельная песня. Операторы агрессивно режут UDP. Особенно если видят VPN-трафик.

Симптомы: на 4G VPN работает, но каждые 5-10 минут — обрыв на 30-60 секунд.

Причина: оператор сбрасывает UDP-пакеты, которые идут без активности больше N секунд. WireGuard держит соединение, но если трафика нет — оператор убивает сессию.

Решение: включил PersistentKeepalive в WireGuard:

```ini

[Peer]

PublicKey = ключ_сервера

AllowedIPs = 0.0.0.0/0

Endpoint = сервер:51820

PersistentKeepalive = 25

```

Каждые 25 секунд — пакет поддержания. Оператор видит активность и не убивает сессию.

Что делать с OpenVPN

OpenVPN на UDP — та же история. Но есть особенности.

Во-первых, OpenVPN добавляет больше заголовков. MTU считается так:

```

MTU = 1500 - 20 (IP) - 8 (UDP) - 32 (OpenVPN) = 1440

```

Но лучше проверить:

```bash

openvpn --mtu-test --remote server_ip

```

Во-вторых, OpenVPN поддерживает `mssfix`:

```

mssfix 1360

```

Это ограничивает размер TCP-сегментов внутри туннеля. Полезно, когда MTU нестабилен.

Инструменты диагностики

`mtr` — лучший друг при диагностике сетевых проблем:

```bash

mtr -u -c 100 10.0.0.1

```

Флаг `-u` — UDP. Покажет, где теряются пакеты.

`tcpdump` для анализа:

```bash

tcpdump -i eth0 udp port 51820 -w wireguard.pcap

```

Смотрим на размер пакетов. Если видите пакеты больше 1400 байт — фрагментация.

Настройка через sysctl

На Linux можно настроить буферы и таймауты:

```bash

net.core.rmem_max = 26214400

net.core.wmem_max = 26214400

net.ipv4.udp_mem = 65536 131072 262144

```

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

Провайдер душит VPN — что делать

Если провайдер агрессивно режет UDP, есть варианты:

1. Перейти на TCP. OpenVPN поддерживает TCP. WireGuard — нет, но можно завернуть в udp2raw или obfs4.

2. Использовать UDP с меньшим размером пакетов. Ставьте MTU 1280 — минимальный для IPv6, но работает и для IPv4.

3. Шифровать трафик так, чтобы провайдер не мог определить, что это VPN. WireGuard легко детектится по заголовкам. А вот OpenVPN с `--tls-crypt` — сложнее.

Протоколы и их поведение

| Протокол | Заголовок | Типичный MTU | Устойчивость к потерям |

|----------|-----------|--------------|----------------------|

| WireGuard | 60 байт | 1420 | Низкая |

| OpenVPN UDP | 32 байта | 1440 | Средняя |

| IPSec | 50-60 байт | 1400 | Средняя |

| SSTP | TCP | 1460 | Высокая |

Настройка серверной части

На сервере тоже надо настраивать. Если сервер за NAT — открывайте порты. И проверяйте, не режет ли ваш хостинг UDP.

На VPS с Ubuntu:

```bash

iptables -A INPUT -p udp --dport 51820 -j ACCEPT

```

И не забывайте про `/etc/sysctl.conf`:

```

net.ipv4.conf.all.rp_filter = 0

net.ipv4.conf.default.rp_filter = 0

```

Это отключит reverse path filtering, который может блокировать пакеты при асимметричной маршрутизации.

Итоговая схема настройки

Полный рабочий конфиг WireGuard для проблемной сети:

```ini

[Interface]

PrivateKey = ключ

Address = 10.0.0.2/24

MTU = 1380

Table = off

PostUp = wg set %i fwmark 0x1234

PostUp = iptables -t mangle -A OUTPUT -p udp --dport 51820 -j DSCP --set-dscp 46

[Peer]

PublicKey = ключ_сервера

AllowedIPs = 0.0.0.0/0

Endpoint = сервер:51820

PersistentKeepalive = 25

```

MTU 1380 — компромисс. Почти везде работает. DSCP 46 — попытка повысить приоритет. fwmark — для маршрутизации.

Проверка после настройки

Проверяем скорость:

```bash

iperf3 -u -c 10.0.0.1 -b 100M

```

Смотрим потери:

```bash

netstat -s | grep -i "udp"

```

Считаем ошибки. Если потери выше 1% — надо копать дальше. Проверяем MTU на всём пути:

```bash

tracepath 10.0.0.1

```

Резюме

UDP-проблемы VPN решаемы. Главное — системный подход. Сначала MTU, потом QoS, потом маркировка. И не забывайте про keepalive — он спасает от обрывов.

Если всё сделано правильно, VPN будет работать стабильно даже на плохих каналах. Но помните: идеальной сети не бывает. Всегда оставляйте запас в настройках.

✔️Купить прокси