IPv6-туннелирование через NAT64: как это влияет на скорость и стабильность прокси-соединений
Содержание
- MTU, фрагментация и другие сюрпризы NAT64
- Задержки: откуда берутся лишние 30-50 мс
- Как NAT64 влияет на стабильность прокси
- Провайдеры, которые ломают NAT64
- Настройка прокси для работы с NAT64
- Сравнение скорости: IPv4 vs NAT64 vs IPv6
- Кейс: игровой прокси за NAT64
- Кейс: веб-скрапинг через NAT64
- Кейс: видеозвонки через NAT64
- Когда NAT64 оправдан для прокси
- Диагностика проблем с NAT64
MTU, фрагментация и другие сюрпризы NAT64
NAT64 — это не туннель в чистом виде, а трансляция адресов. Но для IPv6-клиента, который хочет достучаться до IPv4-сервера, всё выглядит как туннель: пакет уходит в v6, а возвращается из v4. Разница в заголовках — 20 байт против 40. Казалось бы, мелочь. Но именно эти 20 байт ломают жизнь.
Когда IPv6-пакет проходит через NAT64, шлюз вынужден пересобирать заголовок. Если MTU на клиенте установлен в 1500, а у шлюза в 1480, начинается фрагментация. IPv6, в отличие от IPv4, не фрагментируется маршрутизаторами — он шлёт ICMPv6 Packet Too Big. Клиент должен сам уменьшить размер. Но не все стеки это корректно обрабатывают.
Пример: сервер с nginx 1.24, отдающий файлы через прокси. Клиент сидит за NAT64 с MTU 1480. При передаче больших блоков данных TCP-сегменты в 1448 байт проходят, а вот 1460 — уже нет. В итоге — дикие таймауты и ретрансмиссии. Лечится настройкой MSS clamping на прокси:
```bash
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
```
Для IPv6 аналогично:
```bash
ip6tables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
```
Задержки: откуда берутся лишние 30-50 мс
NAT64 добавляет задержку не потому, что он медленный, а потому что он вынужден держать таблицу трансляций. Каждое новое соединение — это запись в stateful-таблице. Пока запись создаётся, пакет ждёт. На современных шлюзах это микросекунды, но на дешёвых роутерах — до 5-10 мс на соединение.
Хуже другое. Если ваш прокси-сервер сидит за NAT64, а клиент приходит по IPv4, каждый пакет проходит двойную трансляцию: v4->v6 на входе, v6->v4 на выходе. Это уже не 5 мс, а 15-20 мс на каждое соединение. Для HTTP это незаметно, а вот для SSH-интерактива или WebSocket — ощутимо.
Реальная цифра: на прокси-сервере в Европе с NAT64-шлюзом в Азии пинг до конечного сервера вырос с 45 мс до 78 мс. Причина — не физическое расстояние, а обработка на шлюзе и потеря возможности использовать IPv6-маршруты напрямую.
Как NAT64 влияет на стабильность прокси
Самая частая проблема — истечение таймаутов в NAT64-таблице. По умолчанию UDP-записи живут 30-60 секунд, TCP — 2-4 часа. Если прокси использует UDP (например, для DNS или QUIC), а клиент молчит дольше таймаута — соединение рвётся. Приходится переустанавливать.
Второй момент — NAT64 не умеет пробрасывать порты. Если вам нужно принимать входящие соединения на прокси через IPv6, а шлюз раздаёт только исходящие — придётся использовать TUN-интерфейс и собственный туннель поверх. Это добавляет ещё один уровень инкапсуляции.
Пример: прокси на базе 3proxy с IPv6-адресом за NAT64. Внешние клиенты по IPv4 подключаются нормально, а вот IPv6-клиенты не могут — шлюз не пробрасывает порты. Решение — поднять WireGuard-туннель до внешнего IPv4-сервера и поверх него гнать IPv6. Получается двойная инкапсуляция, но стабильно.
Провайдеры, которые ломают NAT64
Есть два типа NAT64: провайдерский и локальный. Провайдерский — когда ваш оператор выдаёт только IPv6-адрес, а IPv4-доступ идёт через его шлюз. Локальный — когда вы сами поднимаете NAT64 на своём сервере.
Провайдерский NAT64 — это лотерея. Некоторые операторы ставят агрессивные таймауты (30 секунд для UDP), другие — ограничивают количество одновременных трансляций на одного абонента. Через прокси это выливается в периодические обрывы.
Локальный NAT64 стабильнее, но требует сервера с реальным IPv4-адресом. И тут возникает вопрос: зачем тогда вообще IPv6? Ответ: для доступа к IPv6-only ресурсам, которых становится всё больше. Прокси, который умеет работать с обоими протоколами, получает преимущество.
Настройка прокси для работы с NAT64
Если вы используете прокси на lexic.ml, настройка сводится к двум вещам: корректный MTU и таймауты. Для Jool (популярный NAT64-модуль для Linux) рекомендуется включать `--enable-socket` и настраивать таймауты под ваш трафик.
Пример конфигурации для Jool:
```bash
jool instance add --netfilter --pool6 64:ff9b::/96
jool global update --udp-timeout 300
jool global update --tcp-timeout 7200
```
Увеличение таймаутов решает проблему с UDP, но увеличивает нагрузку на память. Для прокси с сотнями соединений это критично. Компромисс — 120 секунд для UDP и 3600 для TCP.
Сравнение скорости: IPv4 vs NAT64 vs IPv6
Таблица с реальными замерами на прокси-сервере в Франкфурте (nginx 1.24, конфиг по умолчанию, 100 запросов по 10 МБ):
| Тип соединения | Средняя скорость | Пинг до сервера | Потери пакетов |
|----------------|------------------|-----------------|----------------|
| IPv4 напрямую | 92 Мбит/с | 12 мс | 0.1% |
| IPv6 напрямую | 94 Мбит/с | 11 мс | 0.1% |
| IPv6 через NAT64 | 61 Мбит/с | 18 мс | 0.8% |
| IPv4 через NAT64 | 57 Мбит/с | 21 мс | 1.2% |
Разница в скорости — из-за фрагментации и повторной сборки пакетов. Потери — из-за таймаутов на шлюзе. Для прокси это означает, что каждый десятый запрос может подвиснуть.
Кейс: игровой прокси за NAT64
Проблема: игровой сервер с прокси за провайдерским NAT64. Игроки жалуются на лаги и дисконнекты. Причина — UDP-таймаут в 30 секунд на шлюзе. Игровой трафик — это короткие UDP-пакеты каждые 1-2 секунды, но если игрок замер (пауза в игре), соединение рвётся.
Решение: на прокси подняли UDP-keepalive. Каждые 20 секунд отправляется пустой UDP-пакет на игровой сервер. Это держит запись в NAT64-таблице активной. После внедрения количество дисконнектов упало с 15% до 0.5%.
Кейс: веб-скрапинг через NAT64
Проблема: скрапер на Python, который ходит по сайтам через прокси за NAT64. Каждое соединение — новое, и NAT64-шлюз не успевает создавать записи. В итоге — ошибки соединения и потерянные данные.
Решение: использование persistent-сессий в requests. Один TCP-сокет переиспользуется для нескольких запросов. Это снижает нагрузку на NAT64 и ускоряет скрапинг в 2 раза. Код:
```python
import requests
session = requests.Session()
adapter = requests.adapters.HTTPAdapter(pool_connections=10, pool_maxsize=10)
session.mount('http://', adapter)
session.mount('https://', adapter)
for url in urls:
response = session.get(url, timeout=5)
process(response.text)
```
Кейс: видеозвонки через NAT64
Проблема: WebRTC-приложение на IPv6-клиенте не могло установить соединение с IPv4-сервером через NAT64. Симптом — постоянные STUN-таймауты и невозможность проброса медиатрафика.
Причина: STUN-пакеты шли через NAT64, а ответы приходили с IPv4-адреса. WebRTC не понимал, что это тот же хост. Решение — включить ICE-TCP вместо ICE-UDP. TCP-соединения через NAT64 работают стабильнее, потому что не зависят от UDP-таймаутов.
Когда NAT64 оправдан для прокси
NAT64 имеет смысл, когда у вас нет другого способа получить IPv6-связность. Например, вы арендуете VPS без IPv6-адресов, но хотите принимать IPv6-трафик. Или ваш провайдер не выдаёт IPv4-адреса (такое бывает в мобильных сетях).
Во всех остальных случаях лучше использовать обычные туннели: WireGuard, OpenVPN или 6to4. Они дают меньше накладных расходов и не зависят от таймаутов трансляции. NAT64 — это костыль для переходного периода, и относиться к нему нужно соответствующе.
Диагностика проблем с NAT64
Если прокси за NAT64 работает нестабильно, первым делом проверьте MTU. Команда:
```bash
ping -M do -s 1472 64:ff9b::8.8.8.8
```
Если пакеты не проходят, уменьшайте размер до 1400. Также проверьте таймауты на шлюзе:
```bash
jool global display
```
И смотрите логи на предмет ICMPv6 Packet Too Big:
```bash
tcpdump -i any icmp6
```
Эти три команды решают 90% проблем. Остальное — это уже вопросы к провайдеру или к вашей сетевой архитектуре.