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

IPv6-туннелирование через NAT64: как это влияет на скорость и стабильность прокси-соединений

IPv6-туннелирование через 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% проблем. Остальное — это уже вопросы к провайдеру или к вашей сетевой архитектуре.

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