February 5, 2020

Непростой протокол. Автоматизируем настройку адресов в IPv6

Источник: t.me/Bureau121

Содержание статьи

  • Адреса link-local
  • Уникальные адреса хостов
  • Router Advertisement (SLAAC)
  • DHCPv6
  • Настраиваем RA для DHCPv6
  • Настраиваем DHCPv6
  • Заключение

В IPv4 есть всего два варианта: статическая настройка адреса и шлюза по умолчанию или DHCP. Сегодня мы рассмотрим в деталях, что же пришло на смену классическому DHCP из IPv4, как оно работает и как с этим жить.

Нужно помнить, что в IPv6 наконец исчез целый ряд устаревших технологий. В частности, в нем больше нет широковещательной рассылки (broadcast), во всех протоколах ее заменила многоадресная рассылка (multicast) и стандартизованные групповые адреса: например, ff02::1 — все хосты в сегменте, ff02::2 — все маршрутизаторы.

Кроме того, не все механизмы автоматической настройки требуют участия сервера или маршрутизатора.

Адреса link-local

Начнем с концепции адресов типа 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 — /64. Это очень много — 2^64 адресов! Казалось бы, абсурдная идея, но для нее есть основания. В 64 бита можно поместить существующий глобально уникальный идентификатор или сгенерировать случайный с очень низкой вероятностью конфликтов.

Каждый заводской MAC-адрес гарантированно уникален, поэтому можно избежать потенциальных конфликтов адресов навсегда, просто использовав MAC-адрес сетевой карты как часть ее адреса IPv6. Этот механизм называется EUI-64 (Extended Unique Identifier). В деталях про него можно прочитать в приложении к RFC 2373.

Размер MAC-адреса — 48 бит (шесть байт), а нам нужно 64, поэтому он делится на две части по три байта и в середину вставляется магическое число 0xFFFE. Кроме того, инвертируется седьмой бит MAC-адреса — у глобально уникальных он по умолчанию установлен в ноль.

Поскольку адреса типа link-local не маршрутизируются, никаких проблем с приватностью такой подход не создает. Для присвоения публичных адресов он, очевидно, проблематичен — злоумышленник с доступом к дампам трафика или логам сервера легко может отождествить адреса из разных сетей — например, из дома, с работы или публичной точки доступа Wi-Fi в гостинице — с одним устройством и отследить перемещения пользователя.

В современном мире это далеко не самая большая угроза приватности, так что мы не будем рассматривать механизмы борьбы с ней в деталях, но они существуют. Один вариант, IPv6 privacy extensions, описан в RFC 3041. Важнее то, что в IPv6, вернее в NDP — эквивалент ARP, встроен механизм выявления коллизий адресов. Узлы сначала присваивают адресу состояние tentative и ждут, не придет ли пакет NDP с этим адресом в источнике. Если такой пакет приходит, адрес не активируется.

Таким образом, идея автоматически сгенерированных адресов применима и к локальным адресам, и к публичным. Для настройки нужен только адрес сети.

Маршрутизаторы при настройке сетевых карт нередко позволяют указать вручную только адрес сети, но оставить систему генерировать идентификатор хоста самостоятельно: например, interface Gi0; ipv6 address 2001:db8::/64 eui-64 в Cisco IOS, set interfaces ethernet eth0 ipv6 address eui64 2001:db8::/64 в VyOS. Хосты адрес своей сети обычно не знают, поэтому его нужно получить из внешнего источника. Тут и вступает в действие SLAAC (StateLess Address AutoConfiguration) через router advertisement.

Router Advertisement (SLAAC)

Нужно помнить, что ARP в IPv6 тоже нет, его роль взял на себя NDP — Neighbor Discovery Protocol, описанный в RFC 4861. В отличие от ARP, это не отдельный протокол промежуточного уровня между сетевыми и канальным, а подмножество ICMPv6. Это стало возможно именно потому, что адреса link-local обязательны: в сети не может быть хостов с неопределенным адресом.

Он заметно функциональнее своего предшественника, и в числе прочего в нем есть явное разделение между ролями хоста и маршрутизатора. В IPv4 адрес маршрутизатора можно было только настроить вручную или получить через DHCP, в IPv6 же маршрутизаторы рассылают пакеты с информацией о том, что они готовы маршрутизировать трафик хостов, и заодно сообщают им свой адрес.

Этот же протокол способен передать хостам адрес сети, в которой они оказались, чтобы они смогли сами настроить себе адреса.

Попробуем настроить этот механизм на GNU/Linux. Для рассылки router advertisement будем использовать пакет radvd. Он обычно присутствует в репозиториях, и сложностей с его установкой возникнуть не должно.

Предположим, что на eth0 маршрутизатора настроен адрес 2001:db8::1/64. Для начала включим маршрутизацию IPv6: sudo sysctl -w net.ipv6.conf.all.forwarding=1. Затем напишем следующее в /etc/radvd.conf:

interface eth0 {
    IgnoreIfMissing on;
    AdvManagedFlag off;
    AdvReachableTime 0;
    AdvSendAdvert on;
    AdvOtherConfigFlag off;
    prefix 2001:db8::/64 {
        AdvOnLink on;
        AdvAutonomous on;
    };
};

После запуска в radvd мы увидим в дампе трафика следующую картину:

11:36:49.958369 IP6 (flowlabel 0xf840b, hlim 255, next-header ICMPv6 (58) payload length: 56) fe80::a00:27ff:fe76:3417 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 56

hop limit 64, Flags [none], pref medium, router lifetime 1800s, reachable time 0s, retrans time 0s

prefix info option (3), length 32 (4): 2001:db8::/64, Flags [onlink, auto], valid time 86400s, pref. time 14400s

source link-address option (1), length 8 (1): 08:00:27:76:34:17

Это и есть router advertisement. Адрес назначения ff02::1 — групповой адрес всех хостов. Обрати внимание: в качестве адреса источника используется адрес link-local, а не глобальный публичный адрес.

Если в качестве клиентского хоста Linux, то вручную автонастройку можно включить с помощью опции sudo sysctl -w net.ipv6.conf.eth0.accept_ra=1, хотя проще сделать это через NetworkManager. После этого на интерфейсе ты увидишь автоматически настроенный адрес, а в ip -6 route — запись вида default via fe80::a00:27ff:fe76:3417. Все автоматически настроенные маршруты в IPv6 используют именно адрес link-local в качестве адреса шлюза, как на хостах, так и на маршрутизаторах с RIPng, OSPFv3, а нередко и с BGP.

Через router advertisement можно раздавать только маршруты и адреса сетей. Есть расширения для раздачи адресов серверов DNS, но для раздачи дополнительной информации вроде серверов NTP или вовсе произвольных опций без DHCPv6 не обойтись.

DHCPv6

DHCPv6 похож на своего предшественника из IPv4, но отличается деталями реализации, и про эти различия нужно помнить, чтобы правильно его настроить.

Поскольку настройка маршрута по умолчанию в IPv6 делается автоматически через router advertisement, в DHCPv6 эта возможность не предусмотрена — не ищи ее в документации.

В IPv4 хосты рассылают широковещательный запрос к серверу DHCP. В IPv6, даже когда хост настроен использовать DHCPv6, он не станет это делать, если маршрутизатор не скажет ему о присутствии в сети сервера.

Настраиваем RA для DHCPv6

В нашем radvd.conf была опция AdvAutonomous on. Согласно RFC 4862, флаг autonomous означает, что никакой другой механизм раздачи настроек в сети не предусмотрен и хостам следует настраивать свои адреса на основе информации об адресе сети из пакета: 2001:db8::/64 в нашем случае. Если этот флаг выставлен в ноль, то хосты игнорируют информацию об адресе сети из пакетов router advertisement.

Должны ли хосты отправлять запрос к серверу DHCPv6, определяют флаги Managed и OtherConfig. Флаг Managed означает, что хосты должны получить адреса через DHCPv6. Флаг OtherConfig означает, что хосты должны использовать SLAAC, но через DHCPv6 доступны дополнительные настройки.

Поэтому, прежде чем настраивать сервер DHCPv6, нужно снова поправить /etc/radvd.conf и прописать там AdvManagedFlag on и AdvAutonomous off, затем перезапустить сервис.

Настраиваем DHCPv6

Сервер DHCPv6 можно найти в пакете ISC DHCP, в разных дистрибутивах он называется или dhcp-server, или isc-dhcp-server. Расположение конфига дистрибутиво-зависимо и настраивается в опциях запуска, условно будем считать, что он лежит в /etc/dhcpd/dhcpd6.conf. Напишем туда для теста минимальный конфиг:

shared-network TEST {
    subnet6 2001:db8::/64 {
        range6 2001:db8::1000 2001:db8::2000;
        option dhcp6.name-servers 2001:db8::100;
    }
}

Теперь осталось запустить сервис, настроить на клиенте опцию получать настройки из DHCPv6 и посмотреть, что будет.

Заключение

В корпоративных сетях IPv6 все еще скорее исключение, чем правило, но, когда он туда доберется, эта статья, я надеюсь, поможет тебе быть к этому готовым.

ПОДПИСАТЬСЯ - Бюро121