radvd что это в роутере
IPv6 в Linux
Листинг
В своей статье я хотел бы поговорить об основах реализации протокола IPv6 в Linux и провести сравнение IPv6 и IPv4 в этой операционной системе.
Краткая история IPv6
Протокол IPv4 был создан рабочими группами IETF (Internet Engineering Task Force — целевая группа инженерной поддержки Интернета) в начале 70-х гг. и с тех пор сыграл важнейшую роль в развитии Всемирной паутины. Два десятка лет спустя, в начале 90-х, IETF приступила к разработке следующего поколения этого IP-протокола, сначала новинка носила название IPng (IP Next Generation — IP следующего поколения), а затем была переименована в IPv6. Для выработки стандартов этого протокола в IETF создана специальная рабочая группа IPv6.
Первая спецификация IPv6 была опубликована в 1995 г., а в 1998-м ей на смену пришел документ RFC 2460. Первой коммерческой платформой с поддержкой новой версии протокола стала выпущенная в конце 1997 г. IBM AIX 4.3. В Sun Solaris протокол IPv6 поддерживается начиная с версии 8, которая появилась на свет в начале 2000 г.
В Linux протокол IPv6 пришел довольно давно — в ноябре 1996-го его реализовал в ядре 2.1.8 этой ОС Педро Рок на основе BSD API. При этом бóльшая часть изменений в ядре Linux коснулась сетевого уровня L3.
Большой вклад внес также Хельсинкский технологический университет, где развернут проект MIPv6 (Mobile IPv6 — мобильный IPv6)
Преимущества IPv6
Главная цель разработки IPv6 состояла в решении проблемы с “нехваткой адресов”: в отличие от IPv4 с его пределом в 232 IP-адреса новый протокол способен поддерживать до 2128 возможных адресов. Это расширило адресное пространство до такой степени, что его вряд ли удастся заполнить в ближайшие десятилетия. Оно настолько велико, что практически устраняет необходимость в NAT (network address translation — преобразование сетевого адреса). А это во многих случаях дает серьезные преимущества, упрощая, например, одноранговые подключения IP-телефонии и других приложений.
В средах IPv4 технология NAT широко используется мобильными устройствами. Устранив же это звено, мы избавляемся от трафика сообщений типа KEEP ALIVE, которые необходимы, чтобы преобразование адресов оставалось активным. А такие сообщения транслируются довольно часто — примерно один раз в 40—120 с, так что без них мобильные устройства станут потреблять заметно меньше энергии, а значит, смогут дольше сохранять работоспособность в режиме ожидания. А ведь не стоит забывать, что мобильные устройства не только передают такие сообщения, но и могут получать их от других абонентов сети, что делает ситуацию еще более сложной.
Однако расширенное адресное пространство — далеко не единственное преимущество IPv6. Многолетний опыт работы с IPv4 позволил внести в новый IP-протокол целый ряд улучшений. В этой статье мы постараемся остановиться на них и пояснить, как они реализуются в Linux, а также продемонстрировать, в чем IPv6 превосходит IPv4.
Адреса IPv6
Адрес IPv6 содержит 8 групп по 16 разрядов каждая, что в сумме составляет 128 разрядов. В общем виде это выглядит так: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx (символом х здесь обозначено шестнадцатеричное число). Иногда в адресе IPv6 может встречаться последовательность из двух двоеточий (::) — она заменяет начальные нули. Адрес локального хоста, скажем, в IPv6 имеет вид ::1.
По умолчанию протокол IPv4 в качестве широковещательного адреса использует 255.255.255.255, т. е. тот же самый, что и ARP (address resolution protocol — протокол разрешения адресов). Но для IPv6 смежным протоколом является не ARP, а ICMPv6, поэтому вместо широковещательного адреса применяется групповая адресация, а широковещательных адресов здесь нет.
В протоколе IPv6 групповыми адресами являются все те, что начинаются на FF. Линейно-локальный групповой адрес (FF02::1) представляет группу “все хосты”, повторяя тем самым функциональность широковещательных адресов IPv4.
Конфигурирование адресов IPv6
Существует два способа динамической конфигурации адресов IPv6 на хостах (в отличие от статической конфигурации, которую задает системный администратор). Первый — это конфигурация с проверкой состояния, использующая, например, протокол DHCPV6 (он напоминает DHCP из мира IPv4). В действующей ныне версии только такая динамическая конфигурация и доступна.
Второй способ проверки состояния не предусматривает, поэтому здесь конфигурировать клиент не нужно. Конфигурируется только маршрутизатор, где установлен демон конфигурации без проверки состояния, например RADVD или Quagga. Работа первого из них будет рассмотрена и проиллюстрирована ниже, а вот Quagga, который также может посылать сообщения Router Advertisement и принимать Router Solicitations, рассматриваться в данной статье не будет из-за близкого сходства с RADVD.
RADVD
Сообщения типа RA содержат 64-битное поле префикса, играющее, как мы сейчас увидим, очень важную роль в конфигурировании адресов IPv6 на хостах. Получив сообщение RA, хост генерирует IP-адрес на основании содержащегося здесь префикса и MAC-адреса. Если включено защитное расширение Privacy Extension (т. е. при компоновке ядра была задана опция ядра CONFIG_IPV6_PRIVACY, что в большинстве дистрибутивов делается по умолчанию, и вызвана соответствующая sysctl), в адрес IPv6 вносится случайный элемент, затрудняющий идентификацию машины. Подробнее этот аспект рассматривается в статье “Privacy Extensions for Stateless Address Autoconfiguration in IPv6” (“Защитные элементы автоконфигурации адресов без проверки состояния в протоколе Ipv6”).
Но на этом процесс генерации адреса еще не заканчивается. Как убедиться, что в ЛВС уже нет другого такого же адреса? Вероятность этого, конечно, мала, но если такое произойдет, могут возникнуть серьезные проблемы. Так что адрес пока выделяется условно и может применяться только для поддержания связи посредством “соседских” сообщений типа Neighboring.
После этого начинается выполнение процесса под названием DAD (Duplicate Address Detection — обнаружение дублирующихся адресов), который использует сообщения типа Neighbor Solicitation и Neighbour Advertisement. Если другого такого же адреса IPv6 в ЛВС не найдено, он становится постоянным и может применяться со всеми типами пакетов, а не только с Neighboring, как до этого.
Если же обнаружится дублирование, сгенерированный адрес удаляется и в журнале syslog появляется примерно такая запись: “eth0: duplicate address detected!” (“eth0: обнаружено дублирование адреса!”). В подобных случаях системному администратору приходится конфигурировать адрес вручную.
В ядре предусмотрена специальная опция для поддержки Optimistic DAD (CONFIG_IPV6_OPTIMISTIC_DAD) и соответствующая запись sysctl. Это значит, что адрес начинает использоваться со всеми типами пакетов еще до окончания процесса DAD. Как ни мало времени он занимает (обычно не более 1—2 с), в некоторых случаях — главным образом во встроенных системах — возникает необходимость в оптимизированном DAD.
В листинге radvd.conf (см. рис.) представлен файл конфигурации RADVD ( /etc/radvd.conf ). Сообщения типа Router Advertisement с таким префиксом начинают периодически рассылаться при запуске демона RADVD. Хосты используют этот префикс ( 2002:db8:0:1 ) для конфигурирования адресов IPv6 на базе собственных МАС-адресов. Кроме того, в них обычно добавляется элемент случайности (если только в ядре не отключена опция CONFIG_IPV6_PRIVACY).
Срок действия префикса определяется двумя параметрами файла radvd.conf — AdvPreferredLifetime и AdvValidLifetime. Первый из них задает время в секундах, в течение которого адрес, сгенерированный из префикса в режиме автоконфигурации адресов без проверки состояния, остается привилегированным. По истечении этого времени адрес перестает реагировать (например, на команду ping6). Вторая опция AdvValidLifetime определяет время в секундах, на протяжении которого продолжает действовать сгенерированный из данного префикса адрес. Когда этот период истекает, адрес удаляется.
Одной из самых интересных и мощных функций, реализованных в IPv6, является перенумерация (Renumbering) — замена на всех хостах текущего адреса (который создан из текущего префикса) на другой с новым префиксом. Такая операция может потребоваться, скажем, при смене провайдера.
RADVD позволяет выполнять перенумерацию хостов IPv6 легко и просто. Для этого достаточно включить в radvd.conf другой префикс, добавить к текущему префиксу AdvPreferredLifetime и AdvValidLifetime и перезапустить демон RADVD. После этого все хосты сразу же получат другой адрес, сгенерированный из нового префикса посредством конфигурирования без проверки состояния, а затем, когда истечет заданное время, все созданные на основе прежнего префикса адреса будут удалены.
Можно также заставить хосты добавить маршрутизатор RADVD в качестве стандартного, задав полю AdvDefaultLifetime файла radvd.conf любое значение, кроме нуля. Это время жизни в секундах относится к маршрутизатору по умолчанию, его максимальное значение может составлять до 18,2 ч. Значение 0 указывает, что стандартный маршрутизатор на хостах не задан. При остановке демона RADVD он посылает сообщение Neighbour Advertisement с нулевым параметром Router Lifetime, после чего все получившие его хосты удаляют заданный по умолчанию маршрутизатор RADVD из своих таблиц маршрутизации.
Заголовок IPv6
В IPv6 заголовок стал намного проще, чем в протоколе IPv4, чтобы свести к минимуму его обработку на промежуточных маршрутизаторах. Знание этого заголовка очень важно для понимания всего протокола IPv6.
Длина заголовка IPv4 может меняться в пределах от 20 до 60 байтов (дополнительные байты сверх минимальных 20 используются для описания опций IP). В протоколе же IPv6 заголовок имеет постоянную длину 40 байтов, поэтому поля, указывающего его длину (как в IPv4), здесь нет. Отсутствует в этом заголовке и механизм описания IP-опций, который снижает производительность IPv4. Вместо него в IPv6 применяется более эффективная система нанизывания расширений. Структура заголовка IPv6 представлена в таблице.
Пробуем IPv6 в домашней сети
Давно хотел пощупать что это такое. Много новостей связанных с ipv6 мелькает в интернете. Близится всемирный день запуска, прошлогодний день тестирования я как-то пропустил. Да и вообще за ним будущее и я считаю лучше быть впереди чем потом догонять.
А недавняя статья на хабре окончательно сподвигла меня изучить этот вопрос на собственном опыте.
Дано: домашний сервер-роутер на Ubuntu Server 11.10, стационарный компьютер и нетбук на Kubuntu 11.10 и мобильный телефон на Android. Теоретически всё это умеет ipv6, посмотрим что будет на практике.
Установку и настройку тоннеля через Hurricane Electric можно сделать по множеству инструкций в интернете, например по упомянутой выше статье. В итоге имеем: полностью настроенный сервер имеющий связь как с ipv4 так и ipv6. Устройства в сети получают префикс от radvd и сами настраивают себе адрес, но адрес DNS сервера приходится прописывать ручками и самое главное «но» — все устройства в сети переподключаются раз в 1-2 минуты, что на web-серфинге не сказывается, а вот аську тут же банят за слишком частые попытки подключения. Будем искать решение, а так же разбираться как это всё работает.
Попытаюсь пересказать принцип работы назначения адресов ipv6 человеческим языком:
Адреса link-local, которые хосты ipv6 сети сами себе назначают используя свой MAC адрес и стандартный префикс fe80. это понятно и нам в данный момент не интересно.
Далее хост используя этот link-local адрес отправляет в сеть запрос в поисках роутера (Router Solicitation) и если роутер там есть то он отвечает (Router Advertisement), а вот тут есть два пути:
1. Если роутер просто роутер, то он присылает в ответ префикс сети. Далее хост сам себе назначает адрес используя этот префикс и свой MAC адрес и добавляет маршрут по умолчанию на этот роутер.
2. А если роутер еще и DHCPv6 то запускается другой процесс назначения адреса, аналогичный DHCPv4.
На это влияет бит Managed Address Configuration Flag (M) в ответе Router Advertisement.
Так же там есть бит Other Stateful Configuration Flag (O) который говорит нужно ли еще другие параметры получать, например маршруты, адрес DNS сервера, адрес NTP и т.д.
Radvd умеет только первый вариант, для всего остального нужен полноценный DHCPv6 сервер. В моей сети уже есть dnsmasq который занимается раздачей адресов и пересылкой dns запросов. Но к сожалению он не умеет ipv6. Или умеет? Самая свежая версия dnsmasq 2.60 умеет и Router Advertisement и DHCPv6. Отлично!
В репозиториях Ubuntu свежей версии нет, только 2.59, качаем из репозитория Debian Unstable. Там добавляется одна новая зависимость, её можно поставить из родного репозитория.
enable-ra
dhcp-range=2001:470:aaab:aaaa::2, 2001:470:aaab:aaaa:ffff:ffff:ffff:ffff, 64, 12h
Можно конечно не всю /64 подсеть использовать, а поменьше, но пусть резвится, тем более алгоритм генерации адресов другой, более хитрый, а не подряд как в DHCPv4.
Перезапускаем dnsmasq, перезапускаем сеть на клиенте и вуаля, всё получили и адрес и маршрут и адрес DNS равный адресу роутера.
Проверяем, всё работает, aaaa.test-ipv6.com открывается. DNS на роутере доступен по обоим v4 и v6 адресам. Отлично!
Берем в руки телефон с Android. Печаль. IPv6 он не получает. Выясняем что Android не умеет получать адрес от DHCPv6, совсем, никакой версии. Читаем man дальше и в конфиг dnsmasq.conf добавляем следующее:
dhcp-range=2001:470:aaab:aaaa. ra-only, 64, 12h
Теперь наш dnsmasq отвечает двумя Router Advertisement один с установленными флагами M и O, а другой со сброшенными. Android телефон воспринимает только второй, а вот linux клиенты воспринимают оба, и по этому получают по два адреса. Но это не страшно, я считаю. Один из них dnsmasq запоминает (выданный DHCPv6) и можно получать доступ к клиентам по имени. А вот телефон, увы, получит только адрес, DNS он будет знать только с ipv4 именем (192.168.1.1).
Кстати, теоретически существует конфигурация M=0, O=1, так называемая DHCPv6 stateless, когда адреса назначаются автоматически, а другие параметры получаются от DHCPv6, но я не уверен, что dnsmasq так умеет, Android такое примет, да и имена внутри сети не помешают. Есть ещё «костыль» RDNSS (Router Advertisement Options for DNS Configuration). Его умеет radvd на стороне сервера, а на клиентов нужно устанавливать rdnssd, в том числе и на Windows. Для Android всё равно не поможет, он его тоже не умеет.
Отключаем ipv4 и ищем где у нас проблемы с конфигами сервисов. Либо адреса заменяем на имена, либо к ipv4 адресам добавляем ipv6. Со стационарного компьютера все сервисы доступны по ipv6, а вот на нетбуке возникли проблемы. NFS шара монтируется с помощью autofs, а видимо в нем баг и он не разрешает имя сервера по ipv6. Если просто mount делать, то успешно монтируется.
Возвращаем обычный интернет, ибо ipv6 пока скуден, google только поиск, википедия только через sixxs.net, несколько радиостанций, несколько трекеров. Ждем 6 июня.
Что мы получили? Готовность №1 к World IPv6 Launch домашней сети и бесценный опыт.
Автоматизация настройки адресов в 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 — домашняя сеть
Abstract: Рассказ про некоторые возможности IPv6 на примере конфигурации сложной домашней IPv6-сети. Включает в себя описания мультикаста, подробности настройки и отладки router advertisement, stateless DHCP и т.д. Описано для linux-системы. Помимо самой конфигурации мы внимательно обсудим некоторые понятия IPv6 в теоретическом плане, а так же некоторые приёмы при работе с IPv6.
Зачем IPv6?
Вполне понятный вопрос: почему я ношусь с IPv6 сейчас, когда от него сейчас нет практически никакой пользы?
Сейчас с IPv6 можно возиться совершенно безопасно, без каких-либо негативных последствий. Можно мирно разбираться в граблях и особенностях, иметь его неработающим месяцами и nobody cares. Я не планирую в свои старшие годы становиться зашоренным коболистом-консерватором, который всю жизнь писал кобол и больше ничего, и все новинки для него «чушь и ерунда». А вот мой досточтимый воображаемый конкурент, когда IPv6 станет продакт-реальностью, будет либо мне не конкурентом, либо мучительно и в состоянии дистресса разбираться с DAD, RA, temporary dynamic addresses и прочими странными вещами, которым посвящено 30+ RFC. А что IPv6 станет основным протоколом ещё при моей жизни — это очевидно, так как альтернатив нет (даже если бы они были, их внедрение — это количество усилий бОльшее, чем завершение внедрения IPv6, то есть любая альтернатива всегда будет отставать). И что адреса таки заканчиваются видно, по тому, как процесс управления ими перешёл во вторую стадию — стадию вторичного рынка. Когда свободные резервы спекуляций и хомячаяния адресов закончится, начнётся этап суровой консолидации — то есть выкидывание всего неважного с адресов, перенос всех «на один адрес» и т.д. Примерно в это время IPv6 начнёт использоваться для реальной работы.
Впрочем, рассказ не про будущее IPv6, а про практику работы с ним. В Санкт-Петербурге есть такой провайдер — Tierа. И я их домашний пользователь. Это один из немногих провайдеров, или, может быть, единственный в городе, кто предоставляет IPv6 домашним пользователям. Пользователю выделяется один IPv6 адрес (для маршрутизатора или компьютера), плюс /64 сетка для всего остального (то есть в четыре миллиарда раз больше адресов, чем всего IPv4 адресов быть может — и всё это в одни руки). Я попробую не просто описать «как настроить IPv6», но разобрать базовые понятия протокола на практических примерах с теоретическими вставками.
У провайдера сеть 2a00:11d8:1201:32b0::/64 маршрутизируется через 2a00:11d8:1201:0:962b:18:e716:fb97 (то есть через мой компьютер). Заметим, это всё, что я получил. Никаких шлюзов и т.д. — тут начинается магия IPv6, и самое интересное. «Оно работает само».
Начнём с простого: настройка 2a00:11d8:1201:0:962b:18:e716:fb97 на eth2 для компьютера. Для удобства чтения все конфиги и имена файлов я оставлю на последнюю секцию.
Мы прописываем ipv6 адрес на интерфейсе eth2… И чудо, он начинает работать. Почему? Каким образом компьютер узнал, куда надо слать пакеты дальше? И почему /128 является валидной сетью для ipv6? Ведь /128 означает сеть размером в 1 ip-адрес и не более. Там не может быть шлюза!
Для того, чтобы понять, что происходит, нам надо взглянуть на конфигурацию сети (я вырежу всё лишнее, чтобы не пугать выводом):
# ip address show eth2 (обычно сокращают до ip a s eth2 )
Упс. А почему у нас на интерфейсе два адреса? Мы же прописывали один? Наш адрес называется ‘scope global’, но есть ещё и ‘scope link’…
Часть первая: scope
В процессе проектирования IPv6 вопрос ‘scope’ много и тщательно обсуждался, потому что исходное деление IPv4, даже с последующими дополнениями, явно не соответствовало потребностям реальных конфигураций. Например, если у вас объединяются две организации, в каждой из которых используется сеть 10.0.0.0/8, то вас ждёт множество «приятных» сюрпризов. В IPv6 решили с самого начала сделать множество градаций видимости, что позволило бы более комфортно осуществлять дальнейшие манипуляции.
Из всего этого на практике я видел использование только host/interface, link/local и global. В свете /64 и пусть никто не уйдёт обиженным, специально возиться с site-local адресами будет только параноик.
Второй важной особенностью IPv6 является официальное (на всех уровнях спецификаций) признание того, что у интерфейса может быть несколько IP-адресов. Этот вопрос в IPv4 был крайне запутан и часто приводил к ужасным последствиям (например, запрос получали на один интерфейс, а отвечали на него через другой, но с адресом первого интерфейса).
Так как в отличие от IPv4 у IPv6 может быть несколько адресов на интефрейсе, то компьютеру не нужно выбирать «какой адрес взять». Он может брать несколько адресов. В случае IPv4 сваливание на link-local адрес происходило в режиме «последней надежды», то есть по большому таймауту.
А в IPv6 мы можем легко и просто с самого первого момента, как интерфейс поднялся, сделать ему link local (и уже после этого думать о том, какие там global адреса есть).
Более того, в IPv6 есть специальная технология автоматической генерации link-local адреса, которая гарантирует отсутствие дублей. Она использует MAC-адрес компьютера для генерации второй (младшей) половинки адреса. Поскольку MAC-адреса уникальны хотя бы в пределах сегмента (иначе L2 сломан и всё прочее автоматически не работает), то использование MAC-адреса даёт нам 100% уверенность в том, что наш IPv6 адрес уникален.
Принцип довольно простой:
MAC-адрес eth2 — это 00:18:e7:16:fb:97, а локальный адрес ipv6 — F80:000218:e7ff:fe16:fb97. Да-да, именно так, как выделено жирным. Зачем было в середину всобачивать ff:fe — не знаю. Сам алгоритм называется modified EUI-64. Сам этот алгоритм очень мотивирован и полон деталей. С позиции системного администратора — пофигу. Адрес есть и есть. Интересным может быть, наверное, обратный алгоритм — из link-local узнать MAC и не более.
Итак, у нас на интерфейсе два адреса. Мы даже знаем, как появились они оба (один автоматически при подъёме интерфейса, второй прописали мы). Мы даже знаем, как система поняла, что адрес глобальный — он из «global» диапазона.
Но каким образом система узнала про то, кто его шлюз по умолчанию? И как вообще может жить /128?
Часть вторая, промежуточная: мультикасту мультикаст мультикастно мультикастит
Посмотрим на таблицу маршрутизации:
Что мы тут видим? Первое — говорит нам, что наш IPv6 адрес — это адрес нашего интерфейса eth2. Второе говорит, что у нас есть link-local сегмент в eth2. У обоих источник — это kernel.
А вот третье — это интрига. Это шлюз по умолчанию, который говорит, что весь трафик надо отправлять на fe80::768e:f8ff:fe93:21f0 на интерфейсе eth2, и источником информации о нём является некое «ra», а ещё сказано, что оно протухает через 1779 секунд.
Что? Где? Куда? Кто? За что? Почему? Зачем? Кто виноват?
Но перед ответом на эти вопросы нам придётся познакомиться с ещё одной важной вещью — multicast. В IPv4 muticast был этакой технологией «не от мира сего». Есть, но редко используется в строго ограниченных случаях. В IPv6 эта технология — центральная часть всего и вся. IPv6 не сможет работать без мультикаста. И без понимания этого многие вещи в IPv6 будут казаться странными или ломаться в неожиданных местах.
Кратко о типах трафика, возможно кто-то пропустил эту информацию, когда изучал IPv4:
Так вот, в IPv6 НЕТ БРОДКАСТОВ. Вообще. Вместо них есть мультикаст. И некоторые из мультикаст-адресов являются ключевыми для работы IPv6.
В практическом смысле это означает, что мы можем отправить бродкаст пинг всем узлам, или всем маршрутизаторам. Правда, нам для этого придётся указать имя интерфейса, в отношении которого мы интересуемся cоседями.
Мультикаст-групп (группой называют все узлы, которые слушают данный мультикаст-адрес) много. Среди них — специальная группа FF02::6A с названием «All-Snoopers». Именно этой группе и рассылаются routing advertisements. Когда мы хотим их получать — мы вступаем в соответствующую группу. Точнее не мы, а наш компьютер.
Часть третья: routing advertisements
В IPv6 придумали такую замечательную вещь — когда маршрутизатор рассылает всем желающим информацию о том, что он маршрутизатор. Рассылает периодически.
В отношении этого вопроса есть целый (всего один, что удивительно) RFC: tools.ietf.org/html/rfc4286, но нас интересует из всего этого простая вещь: маршрутизатор рассылает информацию о том, что он маршрутизатор. И, может быть, чуть-чуть ещё информации о том, что в сети происходит.
Вот откуда наш компьютер узнал маршрут. Некий маршрутизатор сказал ему «я маршрутизатор». И мы ему поверили. Почему мы выбрали именно его среди всех окружающих маршруштизаторов (см ответ на пинг на FF02::2 выше) мы обсудим чуть дальше. Пока что скажем, что этот «настоящий» маршрутизатор правильно себя анонсировал.
Таким образом, происходит следующая вещь:
У нас адрес 2a00:11d8:1201:0:962b:18:e716:fb97/128, и ещё есть link-local. Мы слышим мультикаст от роутера, верим ему, и добавляем в таблицу маршрутизации нужный нам адрес как default. С этого момента мы точно знаем, что адрес в сети. Таким образом, отправка трафика в интернет больше не проблема. Мы генерируем пакет с src=2a00:11d8:1201:0:962b:18:e716:fb97 и отправляем его на шлюз по умолчанию, который в нашем случае — fe80::768e:f8ff:fe93:21f0. Другими словами, мы отправляем трафик не своему «шлюзу» в сети, а совсем другому узлу совсем по другому маршруту. Вполне нормальная вещь как для IPv6, так и для IPv4, правда, для IPv4 это некая супер-крутая конфигурация, а для IPv6 — часть бытовой повседневности.
Въедливый читатель может спросить несколько вопросов: что значит «написано на интерфейсе»? И что значит «neighbor discovery»?
Вопросы справедливые. Для начала попробуем выяснить, какие узлы у нас есть в сети из подсети 2a00:11d8:1201::/64
Для того, чтобы посмотреть router advertisement на интерфейсе нам поднадобится программа radvdump из пакета radvd. Она позволяет печатать анонсы, проходящие на интерфейсах, в человеческом виде. Заметим, сам пакет radvd нам ещё пригодится (так как его демон — radvd позволяет настроить анонсирование со своих интерфейсах).
Итак, посмотрим, что аносирует нам Tiera:
radvdump eth2 (и подождать прилично, ибо анонсы не очень часто рассылаются)
Таким образом всё просто — адрес мы указали, маршрутизатор нам «себя» прислал, ядро маршрут обновило. Вуаля, у нас IPv6 на компьютере заработал.
Белый IPv6-адрес для каждого в домашней сети
Получить IPv6 адрес для компьютера — этого маловато будет. Хочется так, чтобы каждое мобильное устройство сидело не за позорным NAT’ом, а голой задницей с белым адресом в Интернете. Желательно ещё при этом так, чтобы злые NSA/google не могли по хвостику моего адреса (в котором закодирован MAC) отслеживать мои перемещения между разными IPv6-сетями (хотя в условиях установленного play services эта параноидальность выглядит наивной и беззащитной).
Но, в любом случае, у нас задача раздать интернет дальше.
Так как fb97 уже является адресом моего компьютера, настройка машрутизации плёвое дело:
… и у нас через пол-часика полностью отваливается IPv6 на компьютере? Почему? Кто виноват?
Оказывается, линукс не слушает routing advertisement, если сам является маршрутизатором. Что, в общем случае, правильно, потому что если два маршрутизатора будут объявлять себя маршрутизаторами и слушать маршруты друг друга, то мы быстро получим простейшую петлю из двух зацикленных друг на друга железных болванов.
Однако, в нашем случае мы всё-таки хотим слушать RA. Для этого нам надо включить RA силком.
Заметим, важно, что мы слушаем RA не всюду, а только на одном интерфейсе, с которого ожидаем анонсы.
Теперь маршрутизация работает, маршрут получается автоматически, и можно на каждом мобильном устройстве вручную прописать IPv6 адрес и вручную указать IPv6 шлюз, и вручную прописать IPv6 DNS, и вручную… э… слишком много вручную.
Если мне выдали настройки автоматом, то я так же хочу раздавать их дальше автоматом. Благо, dhcpd отлично справляется с аналогичной задачей для IPv4.
Прелесть IPv6 в том, что мы можем решить эту задачу (раздачу сетевых настроек) без каких-либо специальных сервисов и в так называемом stateless режиме. Главная особенность stateless режима состоит в том, что никто не должен напрягаться и что-то сохранять, помнить и т.д. Проблемы с DHCP в IPv4 чаще всего вызывались тем, что один и тот же адрес выдавали двум разным устройствам. А происходило это из-за того, что злой админ стирал/забывал базу данных уже выданных аренд. А ещё, если железок много и они забывают «отдать аренду», то адреса заканчиваются. Другими словами, stateful — это дополнительные требования и проблемы.
Для решения тривиальной задачи «раздать адреса» в IPv6 придумали stateless режим, который основывается на routing advertisement. Клиентскую часть мы уже видели, теперь осталось реализовать серверную, дабы накормить IPv6 планшетик.
Настройка анонсов маршрутизации (radvd)
Для настройки анонсов используется специальная программа-демон — radvd. С утилитой из её комплекта (radvdump) мы познакомились чуть выше. Прелесть утилиты в том, что она выводит не просто полученные данные, а готовый конфиг radvd для рассылки аналогичных анонсов.
Итак, настраиваем radvd:
Главное тут — префикс и указание на AdvAutonomous.
Запускаем демона, берём ближайший ноутбук (обычная бытовая убунта с обычным бытовым network-manager’ом), рррраз, и получаем…
Откуда у нас столько ipv6 мы поговорим в следующем разделе, а пока что отметим, что адреса сконфигурировались автоматически. И маршруты у нас такие:
Надеюсь, читатель уже вполне понимает, что происходит. Однако… Чего-то не хватает. У нас нет dns-resolver’а. Точнее есть, но выданный dhcpd по IPv4. А у нас пятиминутка любви к IPv6, так то ресолвер нам тоже нужен IPv6.
Тяжело расчехляя aptitude ставим dhcpv6 и прописываем опции nameserver Как бы не так!
К счастью, IPv6 очень долго продумывался и совершенствовался. Так что мы можем решить проблему без участия DHCP-сервера. Для этого нам надо добавить к анонсу маршрута ещё указание на адреса DNS-серверов.
RDNSS в RA
Описывается вся эта примудрость в RFC 6106. По сути — у нас есть возможность указать адрес рекурсивного DNS-сервера (то есть «обычного ресолвера») в анонсе, распространяемом маршрутизатором.
По большому счёту это всё, что мы хотим от DHCP, так что DHCP там тут не нужен. Компьютеры сами делают себе адреса непротиворечивым образом (то есть для исключения коллизий), знают адреса DNS-серверов. Интернетом можно пользоваться.
Для этого мы дописываем в конфиг radvd соответствующую опцию:
(полный конфиг — см. в конце статьи).
Пробуем подключиться снова — и, ура, всё работает.
google.com выбран был не случайно. Сервисы гугля (в немалой степени youtube) — это едва ли не основной источник IPv6 трафика в настоящий момент. Второй источник — торренты, где можно увидеть аж 5-10% пиров в IPv6 варианте.
На этом рассказ можно было закончить, если бы не ещё одна важная деталь — что за третий IPv6-адрес на интерфейсе ноутбука? И что это за temporary dynamic?
Privacy extension
Как я уже упомянул выше, автоматическое конфигурирование IPv6-адреса на основе MAC-адреса сетевого адаптера хорошо всем, кроме того, что создаёт практически идеальное средство для отслеживания пользователей в сети. Вы можете брать любые браузеры и операционные системы, использовать любых провайдеров (использующих IPv6, так что это всё пишется с прицелом на будущее) — но у вас будет один и тот же MAC-адрес, и любой гугуль, NSA или просто спамер смогут вас отслеживать по младшим битам вашего IPv6 адреса. Старшие будут меняться в зависимости от провайдера, а младшие сохраняться как есть.
Для решения этой проблемы были придуманы специальные расширения для IPv6, называющиеся privacy extensions (RFC 4941). Как любое RFC, его чтение — это обычно признак отчаяния, так что по сути этот стандарт описывает как с помощью шаманства и md5 генерировать случайные автоконфигурируемые адреса.
Хост, в нашем случае обычная убунта на обычном ноутбуке, генерирует штатным образом IPv6 адрес из анонса маршрутизатора. После этого она придумывает себе другой адрес, проверяет, что этот адрес не является зарезервированным (например, нам так повезло, и md5 хеш сгенерировал нам все нули — вместо того, чтобы трубить об этом на всех углах, этот изумительный md5 хеш будет выкинут и вместо него будет взят следующий), и, главное, проверяет, что такого адреса в сети нет. Для этого используется штатный механизм DAD (см ниже). Если всё ок, то на интерфейс назначается новосгенерированный случайный адрес, и именно он используется для общения с узлами Интернета. Хотя наш ноутбук с тем же успехом ответит на пинг и по основному адресу.
Этот адрес периодически меняется и он же меняется при подключении к другим IPv6-сетям (и много вы таких знаете в городе. вздох). В любом случае, даже если мы намертво обсыпаны куками и отпечатками всех браузеров, всё-таки маленький кусочек сохраняемой приватности — это лучше, чем не сохраняемый кусочек.
Duplicate Address Detection
Последняя практически важная фича IPv6 — это DAD. Во времена IPv4 на вопрос «а что делать, если адрес, назначаемый на хост, уже кем-то используется в сети» отвечали «а вы не используйте адреса повторно и всё будет хорошо».
На самом деле все вендоры реализовывали свою версию защиты от повторяющегося адреса, но работало это плохо. В частности, линукс пишет о конфликте IPv4 адресов в dmesg, Windows — в syslog… Event… Короче, забыл. В собственную версию журнала и показывает жёлтенко-тревожненький попапик в трее, мол, бида-бида. Однако, это не мешает использовать дублирующийся адрес, если он назначен статикой, и приводит к головоломным проблемам в районе ARP и времени его протухания (выглядит это так: с одного компьютера по сети по заданному адресу отвечает сервер, а с другого, по тому же адресу, допустим, залётный ноутбук, и они ролями периодически меняются).
Многие DHCP-сервера (циски, например), даже имели специальную опцию «проверять пингом» перед выдачей адреса.
Но всё это были доморощенные костыли для подпирания «а вы не нажимайте, больно и не будет».
Конфиги
Эту часть большинство пропустит не читая, ну, такова судьба конфигов — быть писанными, но не читанными.
Используется ли IPv6?
У меня обычный домашний компьютер. Чуть-чуть raid, LVM XFS, BTRFS, LUCKS, свой почтовый и веб-сервера, dns-сервер и т.д. Я подключен к обычному домашнему провайдеру с IPv6.
Вот статистика использования интернета за четыре дня. Собиралась она простым способом:
Если серьёзно, то столь значительные достижения IPv6 (только представьте себе — почти гигабайт трафика в день) большей частью объясняются ютубом и прочими сервисами гугла. Ещё небольшую долю IPv6 принёс пиринг, причём там львиная доля людей — это всякие туннели и teredo (то есть ненастоящие IPv6, использующиеся от безысходности).
С другой стороны, этот показатель почти в три раза больше моего прошлого замера (полтора года назад), когда доля IPv6 едва-едва переваливала за полтора процента.