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

Туннелирование IPv6 через IPv4: как работает NAT64 и где оно подводит

Туннелирование IPv6 через IPv4: как работает NAT64 и где оно подводит

IPv6 существует с 1998 года. Протокол прописан в RFC 2460, потом обновлён в RFC 8200. Но интернет до сих пор сидит на IPv4. Причина простая — NAT. Миллионы устройств за одним белым адресом. Провайдеры не спешат менять инфраструктуру, потому что всё работает.

А когда всё работает — ничего не трогают. Знакомая история.

NAT64 появился как мост между мирами. Позволяет IPv6-клиенту ходить на IPv4-серверы. И наоборот. Но дьявол, как обычно, в деталях.

Архитектура NAT64: как это устроено

NAT64 — это не туннель в классическом понимании. Туннель (6in4, GRE, IPIP) инкапсулирует пакет целиком. NAT64 работает на уровне трансляции адресов. Разбирает заголовок IPv6, вытаскивает payload, заворачивает в IPv4. Механизм описан в RFC 6146.

Схема работы:

```

IPv6-клиент → NAT64-шлюз → IPv4-сервер

2001:db8::1 192.0.2.10

```

Ключевой элемент — префикс NAT64. Обычно это `64:ff9b::/96` из RFC 6052. Но можно назначить свой. Шлюз слушает этот префикс, получает пакеты, транслирует.

Пример на Linux с Tayga:

```bash

/etc/tayga.conf

prefix 2001:db8:64::/96

dynamic-pool 192.0.2.100/24

tun-device nat64

data-dir /var/spool/tayga

Запуск

tayga --mktun

ip link set nat64 up

ip addr add 2001:db8:64::1/96 dev nat64

ip addr add 192.0.2.1/24 dev nat64

tayga

```

Теперь IPv6-клиент с адресом `2001:db8:64::c000:20a` попадёт на IPv4-адрес `192.0.2.10`. Простая арифметика: последние 32 бита IPv6-адреса — это IPv4-адрес назначения.

Префикс 64:ff9b::/96: стандарт и его ограничения

RFC 6052 определяет Well-Known Prefix. Идея хорошая — все NAT64-шлюзы в мире слушают один префикс. Но на практике это создаёт проблемы.

Представьте: у вас два NAT64-шлюза. Оба с `64:ff9b::/96`. Клиент отправляет пакет на `64:ff9b::c000:20a`. Какой шлюз поймает? Тот, который ближе по маршрутизации. Если маршрут не прописан — пакет уйдёт в никуда.

Поэтому на практике используют собственные префиксы. Например, `2001:db8:64::/96`. Это даёт контроль над маршрутизацией. Но ломает совместимость — клиент должен знать префикс конкретного оператора.

MTU: первая грабля

IPv6 имеет MTU 1280 байт минимум. IPv4 — 576. Разница огромная. NAT64-шлюз должен фрагментировать пакеты. Но IPv6 не поддерживает фрагментацию на промежуточных узлах. Только конечные хосты.

Решение — уменьшить MTU на клиенте. Или использовать PLPMTUD (Packetization Layer Path MTU Discovery). На практике многие просто ставят MTU 1280 на IPv6-интерфейсе. Это работает, но теряется производительность.

Пример настройки в Linux:

```bash

ip link set eth0 mtu 1280

```

Проверка:

```bash

ping6 -M do -s 1200 2001:db8:64::c000:20a

```

Если пакет 1200 байт проходит, а 1300 нет — проблема в MTU.

DNS64: обязательный компаньон

NAT64 без DNS64 не работает. Клиент запрашивает AAAA-запись. DNS64-сервер синтезирует её из A-записи. Добавляет префикс NAT64 к IPv4-адресу. Клиент получает IPv6-адрес, отправляет пакет на шлюз.

Настройка BIND с DNS64:

```

options {

dns64 2001:db8:64::/96 {

clients { any; };

mapped { any; };

exclude { 127.0.0.0/8; 10.0.0.0/8; };

};

};

```

Проблема: DNS64 не знает о недоступных IPv4-серверах. Если сервер лежит, клиент получит синтезированный адрес и будет ждать таймаут. Время ожидания TCP в IPv6 — 75 секунд. Пользователь подумает, что сайт умер.

Какие проблемы реально всплывают

Фрагментация и UDP

UDP-пакеты больше MTU IPv4 (576 байт) фрагментируются. NAT64-шлюз должен собрать фрагменты. Это нагрузка на CPU. При DDoS-атаках шлюз захлёбывается.

Тест на фрагментацию:

```bash

ping6 -s 1400 2001:db8:64::c000:20a

```

Если ответа нет, а на 1200 байтах есть — фрагментация сломана.

TCP MSS Clamping

TCP-сегменты с опцией MSS (Maximum Segment Size) должны быть скорректированы. Иначе клиент отправит сегмент 1460 байт, шлюз не сможет его упаковать в IPv4-пакет.

Настройка iptables для clamping:

```bash

iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

```

Проблемы с приложениями

Некоторые приложения хранят IP-адреса в данных. FTP — классический пример. Команда PORT передаёт IPv4-адрес в ASCII. NAT64 не знает о прикладном уровне. FTP через NAT64 ломается.

Решение — использовать FTP в пассивном режиме с ALG (Application Layer Gateway). Но ALG — это дополнительный костыль.

ICMPv6 и ошибки

ICMPv6 Type 2 (Packet Too Big) должен транслироваться в ICMPv4 Type 3 Code 4. Многие NAT64-шлюзы не делают этого корректно. В результате клиент не узнаёт о проблемах с MTU.

Проверка:

```bash

ping6 -M do -s 1400 2001:db8:64::c000:20a

```

Если ответ "Packet Too Big" не приходит — шлюз не транслирует ICMP.

Кейс: IPv6-only сеть и старый сервер

Пример: компания перевела офис на IPv6-only. Сервер 1С работает на IPv4. Адрес 10.0.0.5. Через NAT64 сотрудники ходят на него.

Проблема: 1С использует длинные TCP-соединения. NAT64-шлюз держит таблицу трансляции. Таймаут по умолчанию — 60 секунд. Если соединение простаивает дольше — таблица очищается. Пакет приходит, но шлюз не знает, куда его направить. Соединение рвётся.

Решение: увеличить таймаут в Tayga:

```bash

tayga --set-timeout 3600

```

Или настроить keepalive на клиенте:

```bash

sysctl net.ipv4.tcp_keepalive_time=120

sysctl net.ipv4.tcp_keepalive_intvl=30

```

Кейс: DNS64 и недоступный сервер

Сайт компании переехал на IPv6. Но часть поддоменов осталась на IPv4. DNS64 синтезирует AAAA-записи для всех. Один поддомен оказался недоступен — сервер лежит.

Клиент получает AAAA-адрес. Отправляет TCP SYN. Ждёт. 75 секунд. Потом таймаут. Пользователь обновляет страницу — снова 75 секунд. Итог: сайт "не работает", хотя проблема в одном поддомене.

Решение: настроить DNS64 с исключениями. Или использовать fallback на IPv4-доступ через NAT64.

Кейс: VoIP и SIP через NAT64

SIP использует SDP (Session Description Protocol). В нём передаются IP-адреса и порты. NAT64 не умеет их транслировать. Звонки через NAT64 работают только с ALG.

Тест:

```bash

sipsak -s sip:user@example.com -v

```

Если ответ "401 Unauthorized" — SIP-запрос прошёл. Если таймаут — проблема с трансляцией.

Таблица сравнения: NAT64 vs туннели

| Параметр | NAT64 | 6in4 туннель | GRE |

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

| Протокол | Трансляция | Инкапсуляция | Инкапсуляция |

| MTU | 1280 байт | 1480 байт | 1476 байт |

| Задержка | +0.1-0.5 мс | +0.5-1 мс | +0.5-1 мс |

| Совместимость | Только IPv6-клиенты | Все | Все |

| NAT на пути | Не нужен | Проблемы | Проблемы |

| Прикладной уровень | Не знает | Не знает | Не знает |

Когда NAT64 не нужен

Если у вас есть белые IPv4-адреса — не мучайтесь. NAT64 добавляет задержку, сложность, точки отказа. Туннель 6in4 проще и надёжнее.

Но если IPv4-адресов нет, а IPv6-only сеть нужна — NAT64 единственный вариант. Плюс DNS64. Плюс ALG для некоторых протоколов.

Настройка полного стека

Для теста на Ubuntu:

```bash

apt install tayga bind9

Tayga

cat > /etc/tayga.conf <

prefix 2001:db8:64::/96

dynamic-pool 192.0.2.100/24

tun-device nat64

data-dir /var/spool/tayga

EOF

tayga --mktun

ip link set nat64 up

ip addr add 2001:db8:64::1/96 dev nat64

ip addr add 192.0.2.1/24 dev nat64

tayga

Маршрут

ip -6 route add 2001:db8:64::/96 dev nat64

DNS64 в BIND

cat >> /etc/bind/named.conf.options <

dns64 2001:db8:64::/96 {

clients { any; };

mapped { any; };

};

EOF

systemctl restart bind9

```

Проверка:

```bash

dig AAAA example.com @127.0.0.1

ping6 2001:db8:64::c000:20a

```

Итоги

NAT64 — рабочий инструмент, но с кучей оговорок. MTU, фрагментация, ICMP, прикладные протоколы — всё это требует внимания. Настроить и забыть не получится.

Если выбираете между NAT64 и туннелями — считайте задачи. Для доступа к IPv4-ресурсам из IPv6-only сети NAT64 обязателен. Для связки двух IPv6-сетей через IPv4 — туннель проще и быстрее.

И помните: NAT64 не решает проблему перехода. Он лишь откладывает её. Полный переход на IPv6 — единственное настоящее решение. Но это уже совсем другая история.

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