01.12.2022

Эксперимент с сетью IPv6 с доступом к IPv4

Решил провести эксперимент как будет вести себя Linux в сети с доступом только про протоколу IPv6. В качестве шлюза выбрал Ubuntu Linux. Сеть из этих двух машин создал в VirtualBox. При этом первая машина имеет два сетевых интерфейса, один из которых подключен к моей локальной сети, а второй к внутренней сети VirtualBox. Вторая машина подключена только ко внутренней сети.

В чём суть проблемы?

Во время перехода интернета с IPv4 на IPv6 необходимо как-то обеспечить работу сети с учётом сервисов, которые работают только по IPv4. Можно использовать дуалстэк, т.к. использовать внутри сети IPv4 и IPv6 адресации. При этом для IPv4, скорее всего, будет использован NAT. Схема хоть и рабочая, но в больших сетях заставит дополнительно трудиться и настраивать два протокола вместо одного.

Суть второго метода - использовать в сети адресацию только IPv6. Для доступа к ресурсам IPv4 применяется трансляция NAT64 на одном из узлов, который имеет IPv4 адрес. Схема работы примерно как в первом случае, всё равно используется NAT, но при этом нет необходимости в настройке IPv4.

Как же заставить приложения обратиться к нашему узлу трансляции? Самое простое - манипуляция с DNS запросами. В случае, если при получении адреса через DNS не возвращаются записи типа AAAA, а только записи A, то DNS должен создать «недостающие» записи, которые и направят запрос на сервер трансляции NAT64.

Ограничения подобной схемы:

  1. При обращении по IPv4 адресу непосредственно, возникнет ошибка, т.к. протокол IPv4 не поддерживается хостом. Для решения этой проблемы можно использовать пакет clatd на клиентской машине.
  2. Если домен использует DNSSEC и не имеет записей AAAA, то наши «фейковые» AAAA записи не будут иметь корректной цифровой подписи. По имеющейся у меня информации это не сильно критично, потому что узлов с DNSSEC и без записей AAAA (тех, для которых потребуется трансляция) крайне мало.

Какой софт понадобится?

В качестве сервера я использовал машину с Ubuntu Linux 22.04 LTS.

Подготовка к установке

Первое, что необходимо сделать, определиться с адресацией IPv6, которая будет использована для для механизма трансляции. Этот префикс необходимы выбирать исходя из адресации вашей сети. В качестве диапазона может быть использован глобально уникальный диапазон адресов или локально уникальный или префикс 64:ff9b::/96. Обратите внимание, что использование префикса 64:ff9b::/96 запрещает узлам IPv6 связываться с узлами IPv4, имеющими частные (RFC1918) адреса, в соответствии с RFC 6052. Глобально уникальный диапазон адресов позволит пользоваться вашим сервисом даже за пределами вашей сети. Остальное доступно только в пределах локальной сети при настройке соответствующей маршрутизации.

В дальнейшем я буду использовать диапазон 64:ff9b::/96.

Я пользуюсь провайдером «Ростелеком» который выделяет мне сеть /56. Однако префикс этой сети динамический, т.к. меняется периодически, арендованный маршрутизатор не умеет выдавать доступные мне подсети. Поэтому, для эксперимента я использовал туннельного брокера, который мне выделяет постоянную сеть /48.

Выделим диапазон для нашей сети, которая будет пользоваться сервисами NAT64 и DNS64. Я буду использовать 2001:db8:feee:1::/64.

Внешний адрес сервера, который будет выполнять функции NAT64 будет 2001:db8:feee::2. Доступ в интернет он будет иметь через IPv4 10.0.2.15 (в моём случае это был VirtualBox с NAT).

Настройка Bind 9 (DNS64)

Настройку можно начать с DNS. Bind 9 начиная с версии 9.8 позволяет использовать специальную опцию dns64, которую необходимо разместить в секции options:

options {
...
    dns64 64:ff9b::/96 {
        suffix ::;
        clients { any; };
        mapped { any; };
    };
};

Перезапускаем службу named. Теперь ответ от DNS сервера должен запись AAAA, которая указывает на адрес из выбранного диапазона. Проверим любой адрес, который не имеет записей AAAA в DNS, например, habr.com:

# nslookup
> habr.com
Server:  127.0.0.53
Address: 127.0.0.53#53

Non-authoritative answer:
Name: habr.com
Address: 178.248.237.68
Name: habr.com
Address: 64:ff9b::b2f8:ed44
>

При этом, если мы запрашиваем адрес, который уже имеет записи AAAA, то ответ не модифицируется:

> tavda.info
Server:  127.0.0.53
Address: 127.0.0.53#53

Non-authoritative answer:
Name: tavda.info
Address: 89.208.105.251
Name: tavda.info
Address: 2a0e:d602:1:f8::a

Настройка radvd

Настроим radvd для анонсов маршрутизатора. Используем выбранную сеть 2001:db8:feee:1::/64. В качестве DNS сервера будем предлагать 2001:db8:feee::2 - адрес нашего сервера-маршрутизатора.

interface enp0s8
{
    AdvSendAdvert on;
    MinRtrAdvInterval 30;
    MaxRtrAdvInterval 100;
    prefix 2001:db8:feee:1::/64
    {
        AdvOnLink on;
        AdvAutonomous on;
        AdvRouterAddr off;
    };
    RDNSS 2001:db8:feee::2 {
    };
};

Настройка TAYGA (трансляция NAT64)

Файл конфигурации TAYGA в Ubuntu расположен по пути /etc/tayga.conf. В нём необходимо выделить адреса IPv4 и IPv6, которые не будут совпадать с адресами хоста, а также пул адресов IPv4, который будет использован при трансляции:

tun-device nat64
ipv4-addr 10.0.2.129
ipv6-addr 2001:db8:feee::3
prefix 64:ff9b::/96
dynamic-pool 10.0.2.128/25
data-dir /var/spool/tayga

Наиболее значимые опции, которые необходимо изменить под свою сеть:

Подробнее смотрите в переводе комментариев из файла конфигурации TAYGA.

Включение маршрутизации

Для включения маршрутизации необходимо включить передачу пакетов через хост через sysctl. В Ubuntu можно просто создать файл /etc/sysctl.d/99-route.conf:

net.ipv6.conf.all.forwarding = 1
net.ipv4.ip_forward = 1

После создания выполните sysctl --system или перезапустите систему. После этого клиенты вашей сети могут полноценно использовать интернет через NAT64.

Что делать если приложению требуется IPv4

Решить эту проблему можно только непосредственно на клиенте. Для этого можно использовать компонент clatd. Он также использует TAYGA при своей работе. Настраивать этот компонент почти не придётся. Достаточно прописать одну строку, где указать используемый в нашей сети префикс для трансляции NAT64. В файле /etc/clatd.conf добавим строку:

plat-prefix=64:ff9b::/96

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

# ip a
...
3: clat: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 500
    link/none
    inet 192.0.0.1/32 scope global clat
       valid_lft forever preferred_lft forever
    inet6 fe80::8617:661d:4056:8be3/64 scope link stable-privacy
       valid_lft forever preferred_lft forever

Теперь приложения, которые не используют DNS64 или обращаются в сеть по протоколу IPv4 смогут пользоваться интернет. Например, таким образом можно решить проблему с запуском Steam.


Если данная заметка оказалась вам полезной, можете поблагодарить автора финансово на сервисе Boosty или любой суммой через сервис QIWI.