slaac ipv6 что это
Протокол динамического конфигурирования узлов
Ретрансляция сообщений DHCP
Конфигурирование функции ретрансляции разрешает маршрутизатору пересылать широковещательные сообщения DHCP-протокола. Для этого на интерфейсе G0/0 маршрутизатора R-A конфигурируется команда с адресом DHCP-сервера:
В этом случае маршрутизатор выступает в роли ретранслятора. Он получает от узла А широковещательные запросы (DHCP DISCOVER, DHCP REQUEST) и пересылает их на уникальный адрес (192.168.20.2) DHCP-сервера, который выделяет адреса узлу А.
В схеме сети рис. 8.5 между маршрутизатором и DHCP-сервером установлен коммутатор. Длительные процессы протоколов STP, RSTP могут стать причиной не назначения узлам адресной информации сервером. В этом случае рекомендуется конфигурировать порты коммутатора как граничные. Граничные порты сразу переходят в состояние пересылки (Forwarding), минуя состояния прослушивания (Listening) и обучения (Learning). За счет этого сокращается длительность переходных процессов протоколов STP, RSTP.
Маршрутизатор может не только выступать в роли DHCP-сервера, но и быть клиентом, когда получает IP-адрес для своего интерфейса от сервера провайдера. Обычно этот метод используется в домашних сетях и малых офисах SOHO по требованию провайдера. Конфигурирование интерфейса GigabitEthernet производится по команде:
8.3. Общие сведения о протоколе DHCPv6
В сетях IPv6 индивидуальные глобальные адреса могут быть созданы вручную администратором или получены автоматически (динамически). Причем, существуют разные способы динамического назначения адресов:
Режим SLAAC
Для того чтобы маршрутизатор начал рассылать адресную информацию, ему надо разрешить маршрутизацию IPv6:
Получив объявление RA, узел сам формирует индивидуальный глобальный адрес IPv6, добавляя к полученному префиксу идентификатор интерфейса длиной 64 бита (механизм EUI-64 или генерация случайного числа). Кроме того, в режиме SLAAC в сообщении RA содержится информация о шлюзе по умолчанию.
Если на интерфейсе маршрутизатора был изменен режим динамического назначения адресов, то для восстановления режима SLAAC необходимо установить флаги М и О в нулевое состояние
Автоматизация настройки адресов в IPv6
IPv6 всем известен своей сложностью в настройке, во многом — оправданно. Взамен наследия IPv4 появились новые концепции и способы настройки. Авторы стека протоколов IPv6 хотели сделать его более простым в настройке и самонастраивающимся. К сожалению, простота для пользователя нередко оборачивается проблемами для админастратора.
В IPv4 есть всего два варианта: статическая настройка адреса и шлюза по умолчанию или DHCP. В этой статье мы рассмотрим в деталях, что же пришло на смену классическому DHCP из IPv4, как оно функционирует и как с этим жить.
Автоматизация настройки адресов в IPv6
Начнем с того, что в IPv6 наконец исчез целый ряд старых технологий. В частности, разработчики отказались от широковещательной рассылки (broadcast), во всех протоколах ее заменила многоадресная рассылка (multicast) и стандартизованные групповые адреса: например, ff02::1 — все хосты в сегменте, ff02::2 — все маршрутизаторы.
Кроме того, не все механизмы автоматической настройки требуют участия сервера или маршрутизатора.
Адреса link-local в IPv6
Начнем с концепции адресов типа link-local. Они выделяются из сети ff00::/8 и присваиваются всем сетевым картам при загрузке системы. В отличие от IPv4, в IPv6 их использование обязательно. Это дает возможность каждому устройству иметь адрес и взаимодействовать с другими устройствами той же сети, независимо от того, успешно ли отработали другие механизмы настройки и включены ли они вообще.
Для рассылки пакетов через multicast нужен адрес источника, а broadcast в IPv6, как мы помним, нет. По этой причине наличие адреса на начальном этапе загрузки особенно важно. В IPv4 с его массовым применением широковещательной рассылки данную проблему «решали», используя адрес 0.0.0.0 вместо адреса источника или назначения.
Изолированная сеть в теории может работать на одних адресах link-local, с точки зрения хостов они неотличимы от любых других. Различие есть только для маршрутизаторов, которые по стандарту обязаны не пересылать пакеты с link-local в адресе назначения в другие сети.
На практике, конечно, от сети мало пользы без соединения с интернетом или другими частными сетями, поэтому перейдем к механизмам настройки публичных адресов.
Эта идея не нова: в IPv4 они уже существовали и выделялись из сети 169.254.0.0/16, но широкого распространения не приобрели. Одна из причин этого — сложно предотвратить конфликты адресов. Успешная реализация этой идеи требует достаточно надежных и практичных способов обеспечить адресам хостов уникальность. Посмотрим, как эта проблема решается в IPv6.
Уникальные адреса хостов в IPv6
Каждый заводской MAC-адрес гарантированно уникален, поэтому вы можете избежать потенциальных конфликтов адресов навсегда, просто использовав MAC-адрес сетевой карты как часть ее адреса IPv6. Данный механизм называется EUI-64 (Extended Unique Identifier). В деталях про него можете прочитать в приложении к RFC 2373.
Размер MAC-адреса — 48 бит (шесть байт), а нам нужно 64, поэтому он делится на две части по три байта и в середину вставляется магическое число 0xFFFE. Кроме того, инвертируется седьмой бит MAC-адреса — у глобально уникальных он по умолчанию установлен в ноль.
Поскольку адреса типа link-local не маршрутизируются, никаких проблем с приватностью такой подход не создает. Для присвоения публичных адресов он, очевидно, проблематичен — злоумышленник с доступом к дампам трафика или логам сервера легко может отождествить адреса из разных сетей — например, из дома, с работы или публичной точки доступа WiFi в гостинице — с одним устройством и отследить местоположение пользователя.
В сегодняшнем мире это далеко не самая большая угроза приватности, так что мы не будем рассматривать механизмы борьбы с ней в деталях, но они существуют. Один вариант, IPv6 privacy extensions, описан в RFC 3041. Важнее то, что в IPv6, вернее в NDP — эквивалент ARP, встроен механизм выявления коллизий адресов. Узлы сначала присваивают адресу состояние tentative и ждут, не придет ли пакет NDP с этим адресом в источнике. Если такой пакет приходит, адрес не активируется.
Таким образом, идея автоматически сгенерированных адресов применима и к локальным адресам, и к публичным. Для потребуется только адрес сети.
Router Advertisement (SLAAC)
Стоит помнить, что ARP в IPv6 тоже нет, его роль взял на себя NDP — Neighbor Discovery Protocol, описанный в RFC 4861. В отличие от ARP, это не отдельный протокол промежуточного уровня между сетевыми и канальным, а подмножество ICMPv6. Это стало возможно именно потому, что адреса link-local обязательны: в сети не может быть хостов с неопределенным адресом.
Он намного функциональнее своего предшественника, и кроме всего прочего в нем есть явное разделение между ролями хоста и маршрутизатора. В IPv4 адрес маршрутизатора можно было только настроить ручками или получить через DHCP, в IPv6 же маршрутизаторы рассылают пакеты с информацией о том, что они готовы маршрутизировать трафик хостов, и заодно сообщают им свой адрес.
Этот же протокол может передать хостам адрес сети, в которой они оказались, чтобы они смогли самостоятельно настроить себе адреса.
Попробуем настроить этот механизм на GNU/Linux. Для рассылки router advertisement будем использовать пакет radvd. Он обычно присутствует в репозиториях, и сложностей с его установкой возникнуть не должно.
IPv6 SLAAC Attack
Прочитал недавно статью «IPv6 под прицелом» и решил написать более подробно об атаке SLAAC (SLAAC Attack), т.к. эту атаку я уже давно в голове держу, развернутого материала на русском не нашел, да и самому интересно ее было повторить.
Суть атаки
В чем суть атаки? Во-первых, она очень простая и надежная, т.к. использует стандартные технологии и инструменты ОС. По сути, вы просто становитесь единственным IPv6-маршрутизатором в сети и раздаете клиентам IPv6-подсеть, из которой клиенты берут себе адреса либо автоматически генерируя их (SLAAC), либо спрашивая у вашего же DHCPv6-сервера. Напомню, что IPv6 включен по умолчанию во всех современных десктопных, мобильных и серверных ОС, имеет приоритет над IPv4 (кроме некоторых случаев), адрес IPv6, в отличие от IPv4, может быть получен в любой момент, а не только в момент совершения подключения, и крупные веб-сайты уже давно доступны через IPv6. Атака работает как в проводных сетях, так и в беспроводных. Не все свитчи, даже современные, поддерживают фильтрацию Router Advertisement, и, как я полагаю, не все включают эту функцию, даже если она поддерживается свитчем, полагая, что раз в сети нет IPv6, то и фильтровать ничего не нужно. К слову, на данный момент, фильтр Router Advertisement можно обойти на всех свитчах, использовав недостатки реализации.
Я смог придумать две реализации атаки:
Реализация №1
С помощью этого способа, вы сможете перехватывать только реальный IPv6-трафик к хостам, которые имеют AAAA-запись. Вам понадобится IPv6-подсеть длиной /64 и какой-либо софт для Router Advertisement, я использовал dnsmasq. IPv6-подсеть 6to4 не подойдет, т.к. все 6to4-адреса имеют приоритет ниже, чем IPv4, так что нужно использовать туннельный брокер. Клиентам будем раздавать только сам диапазон адресов, без DNS, и не используя DHCPv6.
Демон dnsmasq умеет брать подсеть прямо с интерфейса, для этого достаточно указать в конфигурационном файле следующую строку:
Где wlp3s0 — сетевой интерфейс, в моем случае, беспроводной. Устанавливаем глобально маршрутизируемую подсеть 2001:470::/64 на интерфейс, запускаем dnsmasq, смотрим в wireshark:
Все компьютеры в сети сразу же назначили себе IPv6-адрес и установили маршрут по умолчанию:
Не забудьте включить маршрутизацию!
Недостаток этой реализации в том, что через ваш маршрутизатор пойдет только IPv6-трафик. Опять же, вероятнее всего, IPv4-адрес вашего компьютера будет за NAT, а значит получить IPv6-подсеть может быть не так-то просто, т.к. самый популярный протокол туннелирования — SIT — не работает за NAT. Нужно использовать либо туннелирование по протоколу AYIYA, который поддерживается у меньшинства туннельных брокеров, либо придумывать свои схемы проброса. Атака может быть замечена, если атакуемый использует какой-либо сайт с привязкой по IP. Зато, эта атака технически очень простая и применить ее можно буквально за минуту.
Реализация №2
Что же делать, если у необходимого нам хоста нет IPv6-адреса, а нам так хочется совершить незаметную MITM-атаку? Есть замечательный выход из этой ситуации — NAT64+DNS64. NAT64 позволяет вам сделать отображение всего диапазона IPv4 в /96-диапазон адресов IPv6, а DNS64 сможет отдавать такие адреса клиентам.
Под Linux существует три NAT64-демона: TAYGA (userspace) и Ecdysis (kernelspace), Jool (kernelspace), а поддержка DNS64 есть в Bind9, Unbound и специальном демоне totd, который заброшен, но все еще компилируется и работает.
Первым делом, мы должны выбрать какие-то 2 подсети, которые будем раздавать нашим клиентам. Первая подсеть нужна для отображения адресов, а вторая для маршрутизации. Я решил использовать 2001:db8:1:ffff::/96 (из диапазона «для документации») в качестве первой подсети, а в качестве второй — fde4:8dba:82e1:ffff::/64 (IPv6 ULA, аналог внутрисетевых диапазонов в IPv4).
Перенастраиваем dnsmasq:
Указываем наши настройки в TAYGA:
И в totd:
И запускаем все демоны. В итоге, получается как-то так:
Весь трафик, отправленный на диапазон 2001:db8:1:ffff::/96, фактически пойдет через IPv4.
К сожалению, DNS устанавливается только при подключении, т.к. Router Advertisement принимает ядро, а для получения DNS нужен DHCPv6, чем ядро уже не занимается. Аналогичное поведение наблюдается в Windows 7 (другие версии не пробовал).
Автоконфигурация в IPv6
В IPv6 появился новый механизм автоконфигурации узла. Называется он Stateless Address Autoconfiguration или SLAAC. Используется он для автоматического получения IP адреса и сетевого префикса узлом, без использования DHCPv6 сервера, или совместно с ним.
Действительно, когда мы создаём некоторую сеть, мы прописываем адрес шлюза и префикс этой сети на маршрутизаторе. Этой информации достаточно, чтобы выдавать адреса устройствам. Механизм SLAAC позволяет маршрутизатору назначать устройствам адреса даже если в сети нет DHCPv6.
Маршрутизатор Cisco с рабочим IPv6 интерфейсом рассылает в сеть информацию об этой сети, включающую в себя сетевую часть IP адреса и длину префикса. Кроме того, в этом сообщении содержится адрес шлюза по умолчанию для сети. Подробнее о структуре IPv6 адреса можно прочитать здесь. Сообщение это называется Router Advertisement (RA) и отправляется обычно раз в 200 секунд на мультикастовый адрес FF02::1 (подробнее об этом адресе можно прочитать в статье про мультикаст в IPv6).
Если в сети появилось новое устройство, которому необходим адрес, ему необязательно ждать 200 секунд до ближайшей рассылки, оно может направит запрос маршрутизатору (Router Solicitation или RS) и попросить его выслать настройки немедленно. Запрос маршрутизатору выполняется на адрес FF02::2.
Оба сообщения RA и RS отправляются посредством протокола ICMPv6, с мультикастовым адресом получателя в IP пакете.
Для того чтобы маршрутизатор начал полноценно обслуживать сеть (рассылать в неё RA и отвечать на RS), мало настроить IPv6 адрес на интерфейсе, необходимо так же включить режим маршрутизации для IPv6 сетей, введя команду ipv6 unicast routing в режиме глобальной конфигурации.
Существует три способа назначения адреса:
В случае использования третьего варианта, DHCP сервер выдаёт клиенту полный IPv6 адрес – все 128 бит, который назначается на интерфейсе клиента. В случае использования первых двух вариантов, маршрутизатор сообщает клиенту только сеть, в которой он находится, шлюз и префикс. Таким образом, клиенту недостаёт второй половины IP адреса (идентификатора интерфейса). Напомню, что адрес состоит из 128 бит, а маршрутизатор выдаёт максимум, только первые 64. Оставшиеся 64 бита, где должна находиться информация о хосте, должны быть заполнены самим устройством, маршрутизатору не важно, что именно устройство туда поместит, важно, чтобы первые 64 бита (сеть) были правильными. Для генерации правой половины IP адреса используется алгоритм EUI-64 или вообще генерируется случайный набор цифр.
Маршрутизация IPv6 через WireGuard с поддержкой SLAAC
Вдохновившись аргументами из статьи «IPv6 — прекрасный мир, стоящий скорого перехода на него», мне стало катастрофически не хватать IPv6. Конечная цель: обеспечить каждое из своих устройств уникальным публичным псевдостатическим IPv6.
Для дома решение довольно простое: при наличии статического IPv4, можно получить подсеть IPv6 от туннельного брокера и на этом вопрос можно считать закрытым.
А вот с мобильными устройствами так не получится: услуга статического IPv4 тут скорее редкость; да и при наличии бесплатного WiFi я выберу подключение к нему, а не к мобильной сети.
Остаётся единственный вариант — использовать VPN. Существующие на GitHub решения типа “wireguard-install” или “openvpn-install” имеют фатальный недостаток: они отдают клиенту единственный IPv6/128 адрес, а чтобы у клиентов появилась возможность автоконфигурации, нужна целая /64 подсеть.
Предлагается решение на основе WireGuard.
Вам понадобятся
Особый виртуальный сервер. Для реализации задуманного, нужно купить VDS, которому хостер согласится отдать хотя бы /60 подсеть. Как оказалось, найти такое — достаточно сложная задача: в худшем случае, хостеры почему-то продают IPv6 поштучно; в лучшем — только /64 подсети. В результате долгих поисков и благоприятного стечения обстоятельств, был найдена компания Melbicom, которая способна выделить /56 подсеть на VDS.
Linux + wireguard + udppd + nftables. На моём сервере установлен ArchLinux, но описанное решение может быть воспроизведено и на других дистрибутивах.
Условные обозначения
ens3 – имя сетевого интерфейса.
Далее в тексте используются следующие «IP» адреса:
2a06:X:X:a::2/128 и 213.x.x.2/24 – IPv6 и IPv4 адреса VDS. Назначаются хостером автоматически и бесплатно к каждому приобретаемому VDS.
2a06:X:X:100::/56 – Маршрутизируемая до VDS подсеть /56 IPv6. Заказывается отдельно.
2a06:X:X:111::/64 – подсеть для клиента (мобильного устройства), которая выделяется из заказанной выше /56 подсети.
2a06:X:X:111:a:b:c:d/64 – пример IPv6 клиента (мобильного устройства), где a:b:c:d (interface id) выбирается клиентом самостоятельно.
Тестирование наличия выделенной /56 подсети
Изначально, на сервере, сеть не должна быть настроена, но должна маршрутизироваться до него. Содержимое /etc/systemd/network/ens3.network выглядит примерно так:
19:14:39.689842 IP6 fe80::XX > ff02::XX ICMP6, neighbor solicitation, who has 2a06:X:X:111:a:b:c:d, length 32
Установка ndppd
Ndppd — это демон, задача которого слушать интерфейс: ожидать «neighbor solicitation» и отвечать «router advertisement» Таким образом, вышестоящий роутер узнает, куда адресовать трафик выделенной подсети. Далее этот трафик через wireguard будет передан клиенту.
К сожалению, в ArchLinux ndppd пока доступен только из AUR. Если в вашем дистрибутиве он доступен из репозиториев, переходите к следующем разделу.
Переходим в пользователя:
su router
Теперь из-под пользователя выполняем команды:
git clone https://aur.archlinux.org/ndppd.git
Возвращаемся в root:
exit
Переходим в каталог ndppd:
cd /home/router/ndppd
Настройка ndppd
Создаём файл /etc/ndppd.conf с содержимым:
ens3 – имя интерфейса
Подробное описание параметров изложено в документации.
Далее активируем сервис:
systemctl enable ndppd
и запускам:
systemctl start ndppd
Установка системных переменных
Чтобы заработала пересылка IPv6 пакетов между интерфейсами, необходимо в каталоге /etc/sysctl.d/ создать файл wireguard.conf с содержимым:
Первая строка включает пересылку IPv4, вторая — IPv6. Подробное описание каждого из параметров можно узнать из документации.
Настройка WireGuard на сервере
Создаём публичный и приватный ключи сервера:
wg genkey | tee server-private.key | wg pubkey > server-public.key
Создаём публичный и приватный ключи клиента:
wg genkey | tee client1-private.key | wg pubkey > client1-public.key
Создаём pre-shared key:
wg genpsk > pre-shared.key
Создаём файл /etc/wireguard/wg0.conf:
Активируем и запускаем демона wireguard:
systemctl enable wg-quick@wg0 && systemctl start wg-quick@wg0
В случае изменения конфигурации, перезапуск удобно выполнять командой:
wg-quick down wg0 && wg-quick up wg0
Настройка nftables
Поскольку iptables постепенно выходит из употребления, я предпочитаю nftables.
Для конфигурации нужно создать или отредактировать файл /etc/nftables.conf :
Настройка WireGuard на клиенте
Конфигурация клиента выглядит так:
Бонус: обход блокировок
Если из-за политики государства, часть Интернета заблокирована, при помощи клиента WireGuard на роутере с OpenWRT можно обойти блокировку.
Для этого переносим конфиг клиента на роутер с OpenWRT, указав в параметре AllowedIPs заблокированные подсети. Например, чтобы разблокировать Яндекс из Украины, нужно указать:
Список подсетей Яндекса взят отсюда https://ipinfo.io/AS13238
IPv4 заработает сразу. А чтобы заработал IPv6, нужно при помощи nat6 подменить префикс клиента. В разделе Firewall :: Custom Rules допишем следующие пользовательские правила: