В своей статье я хотел бы поговорить об основах реализации протокола 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.
Последующие годы ознаменовались многими дополнениями, одним из основных источников которых стал проект USAGI , зародившийся в 2000 г. в Японии. Эта инициатива, сокращенное название которой расшифровывается как UniverSAl playGround for IPv6 (универсальная тестовая площадка для IPv6), нацелена на разработку отсутствующих реализаций в соответствии с RFC 2460.
Большой вклад внес также Хельсинкский технологический университет, где развернут проект 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 подсистема использует четыре новых типа кодов ICMP. Два из них — Neighbor Solicitation и Neighbour Advertisement -- идентичны запросам и ответам ARP соответственно, а Router Advertisement и Router Solicitation аналогов в IPv4 не имеют и будут рассмотрены ниже.
В протоколе IPv6 групповыми адресами являются все те, что начинаются на FF. Линейно-локальный групповой адрес (FF02::1) представляет группу “все хосты”, повторяя тем самым функциональность широковещательных адресов IPv4.
Пользовательские элементы Linux применяют для управления адресами IPv6 те же средства, что и для IPv4. Обычно для этого бывает достаточно добавить некоторые опции, указывающие на использование нового протокола. Например, пометить адреса IPv6 посредством “ifconfig eth0 inet6...” или “ip -6 addr.” Можно также отобразить таблицы маршрутизации как “route -A inet6” или “ip -6 route show” и т. д.
Конфигурирование адресов IPv6
Существует два способа динамической конфигурации адресов IPv6 на хостах (в отличие от статической конфигурации, которую задает системный администратор). Первый — это конфигурация с проверкой состояния, использующая, например, протокол DHCPV6 (он напоминает DHCP из мира IPv4). В действующей ныне версии только такая динамическая конфигурация и доступна.
Второй способ проверки состояния не предусматривает, поэтому здесь конфигурировать клиент не нужно. Конфигурируется только маршрутизатор, где установлен демон конфигурации без проверки состояния, например RADVD или Quagga. Работа первого из них будет рассмотрена и проиллюстрирована ниже, а вот Quagga, который также может посылать сообщения Router Advertisement и принимать Router Solicitations, рассматриваться в данной статье не будет из-за близкого сходства с RADVD.
RADVD
RADVD расшифровывается как Router Advertisement daemon (демон запросов маршрутизатора). Эта работающая на маршрутизаторах программа обеспечивает конфигурирование адресов IPv6 на хостах без проверки состояния. Разработали ее Пекка Савола, Ларс Феннеберг, Педро Рок и др., а сейчас сопровождает Пекка Савола (см. .www.litech.org/radvd/). Этот демон периодически рассылает собственные сообщения типа Router Advertisement, а также слушает запросы маршрутизаторов Router Solicitations (RS), на которые отвечает сообщениями Router Advertisement (RA).
Сообщения типа 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 представлена в таблице.
Версия (4) |
Класс трафика (8) |
Метка потока (20) | ||
Длина информационной части (16) |
Следующий заголовок (8) |
Максимум сетевых сегментов (8) | ||
Адрес источника (128) | ||||
Адрес получателя (128) |
Заголовок IPv6 Версия (4) Класс трафика (8) Метка потока (20) Длина информационной части (16) Следующий заголовок (8) Максимум сетевых сегментов (8) Адрес источника (128) Адрес получателя (128)
Отказались разработчики IPv6 и от поля с контрольной суммой, которое имеется в IPv4, что также позволило повысить скорость обработки пакетов. Контрольная сумма обрабатывается на уровнях 2 и 4, так что включать ее еще и в уровень 3 (сетевой) необходимости нет. В этом отношении IPv6 реализован лучше своего предшественника.
Как известно, на каждом маршрутизаторе, через который проходят пакеты IPv4, значение поля TTL (time-to-live — время жизни) уменьшается на единицу. В результате контрольную сумму заголовка IPv4 приходится пересчитывать, так как она в числе прочего определяется и значением в данном поле. В IPv6, естественно, такой пересчет не производится, поскольку в заголовке пакетов контрольная сумма не указывается.
Метка потока предусмотрена для управления качеством обслуживания пакетов, но в настоящее время не используется. Предельное значение сетевых сегментов по умолчанию равно 64, что аналогично полю TTL в заголовке IPv4.
Заголовок IPv6 отличается высокой гибкостью применения, так как расширяется очень просто. Это достигается вставкой между ним и транспортным заголовком (TCP/UDP) так называемых “заголовков расширений” (Extension Headers), которые могут относиться к одному из перечисленных ниже типов:
- опции “шаг-за-шагом” (hop-by-hop) — IPPROTO_HOPOPTS); ·
- пакет маршрутизации — IPPROTO_ROUTING; ·
- фрагментированный пакет — IPPROTO_FRAGMENT; ·
- опции ICMPV6 — IPPROTO_ICMPV6; ·
- следующего заголовка нет — IPPROTO_NONE; ·
- опции получателя — IPPROTO_DSTOPTS; ·
- опции мобильности — IPPROTO_MH; ·
- другие протоколы — TCP,UDP и т. д.
Если в процессе синтаксического разбора хост не может распознать заголовка расширения, генерируется ошибка ICMP, уведомляющая о проблеме с параметрами (тип ICMPV6_PARAMPROB, код ICMPV6_UNK_NEXTHDR), и пакет удаляется.
Когда в пакете имеется заголовок расширения hop-by-hop, синтаксический разбор этого заголовка производится на каждом узле, через который проходит пакет. Синтаксический разбор других заголовков расширения выполняется только в том случае, если указанный в заголовке IPv6 адрес получателя совпадает с адресом узла. Не вдаваясь в технические подробности, можно сказать, что механизм заголовков расширения IPv6 создает меньшую нагрузку на сеть и более эффективен, чем обработка опций в IPv4.
IPsec
Протокол безопасности IPsec для IPv6 является обязательным, а в IPv4 используется по желанию разработчика. Впрочем, большинство современных операционных систем применяют IPsec и для IPv4, и для IPv6. Такой “двоякий” подход наблюдается в ядрах Linux 2.6.x, но реализация IPv6 выполнена здесь лучше.
DNS
Для поддержки IPv6 была создана новая запись ресурса DNS Resource Record, имеющая тип “АААА” и позволяющая ассоциировать доменное имя с адресом IPv6. Скорректированы также запросы DNS и методы разрешения адресов.
В феврале этого года IANA добавила записи DNS для адресов PIv6 в шесть из тринадцати серверов корневых имен, после чего хосты Интернета получили возможность поддерживать связь по новому протоколу.
Протокол MLD
Групповые адреса типа Multicast используются для одновременной рассылки пакетов на несколько машин. В IPv4 такая возможность реализована посредством протокола IGMP (Internet Group Management Protocol — интернет-протокол группового управления), а в IPv6 для этого применяются протоколы MLDv1 и MLDv2 (Multicast Listener Discovery — обнаружение слушателей многоадресных пакетов). Первый из них основан на IGMPv2, а второй — на IGMPv3. Оба они работают посредством сообщений ICMPv6. Узлы, желающие получать многоадресные пакеты для определенной группы, называются “слушателями”, и о них говорят, что они “присоединились” к группе.
Недавно поддержка многоадресной маршрутизации IPv6 появилась в ядре Linux — ее добавил сюда Йосифодзи Хидеяки, один из тех, кто развивает новый IP-протокол в этой операционной системе. Его работа основана на патчах Майкла Хёрдта (lwn.net/Articles/276614/) из расположенного во французском городе Страсбурге исследовательского центра LSIIT Laboratory. В дополнение к элементам ядра многоадресная маршрутизация содержит и пользовательские компоненты, так называемые PIM. Ее поддержка в IPv6 выходит за рамки настоящей статьи, поэтому лишь отметим, что в IP-протокол нового поколения заложены все функции многоадресной маршрутизации, которые имеются в нынешнем IPv4, причем некоторые из них улучшены.
Заключение
Похоже, что IPv6 в Linux уже вышел на рабочий уровень и обрел стабильность. Переход на новый протокол продлится долго, но в целом Linux уже готова к этому процессу. Как видно из настоящей статьи, IPv6 имеет ряд преимуществ перед IPv4, включая: ·
расширенное адресное пространство, которое избавляет:
- от грозящей IPv4 нехватки адресов и
- необходимости NAT; ·
- простоту конфигурации IP-адресов без проверки состояния, благодаря которой не требуется настраивать отдельные хосты; ·
- простой способ перенумерования; ·
- упрощенный (по сравнению с IPv4) заголовок IP-пакетов; ·
- отсутствие фрагментации на маршрутизаторах (свойственной IPv4) — она производится только на хостах, использующих обнаружение PMTU.
Имеются, конечно, у IPv6 на Linux и некоторые недостатки, не упомянутые в настоящей статье. До сих пор, скажем, здесь не реализован LVS (Linux Virtual Server — виртуальный сервер Linux). Зато перевести приложения на IPv6 сравнительно просто. В целом же переход на IPv6 выглядит неизбежным, так как новый протокол дает по сравнению с IPv4 много серьезных преимуществ. Вот только этот процесс потребует времени, так что нам еще предстоит сталкиваться с сетями, где одни машины поддерживают исключительно IPv4, другие — только IPv6, третьи — оба эти протокола. Сегодня, к счастью, уже имеется масса технологий туннелирования, помогающая справляться с такими сетями. Так что даже несмотря на некоторые сложности переходного периода, протокол нового поколения IPv6 обязательно выйдет в сеть и в конце концов значительно улучшит ее. Следите за этим!
Об авторе. Рами Роузен закончил факультет информатики израильского технического института Technion в Хайфе и сейчас работает программистом ядра Linux в одной из начинающих компаний. Связаться с ним можно по адресу: ramirose@gmail.com.