"Теоретически канал с адресацией EUI 64 может соединить порядка " запись вида не понятна и отнимает время на попытку ее осмыслить. ее можно заменить например на записи вида 264 или 1,8 * 1019
|
Протокол розыска соседей
Для начала мы рассмотрим уже готовое решение из нашего арсенала: ARP. Этот протокол достаточно гибок, чтобы работать с разными типами канальных и сетевых адресов, так что мы могли бы легко приспособить его и для нужд IPv6. Тем не менее, у нас есть повод, чтобы отказаться от ARP и создать новый механизм розыска соседей IPv6. В вину ARP мы поставим его… широковещание. Как так? Ведь мы сами только что сказали, что широковещание открывает нам светлый путь к розыску соседей! Не подлежит сомнению, что это была плодотворная идея. Но, чтобы перейти "от идеи к модели", нам надо учесть современные возможности каналов. В самом начале они поддерживали только два режима передачи, широковещательный и индивидуальный; однако с тех пор появился и прочно утвердился еще один режим, групповой.
В чем широковещательный режим проигрывает групповому? Прежде всего, у широковещания нулевая избирательность. Представим себе канал в смешанной сети, где одни узлы поддерживают только IPv4, другие — только IPv6, третьи — только ISO и т.д. Всякий раз, когда узел IPv4 посылает в такой канал запрос ARP, его принимают, анализируют и только затем отбрасывают все те узлы, которым вообще нет дела до IPv4; их вычислительные ресурсы расходуются при этом совершенно впустую, а в большой сети непроизводительный расход "виртуальной энергии" достигает заметной величины.
Ходит легенда о больших плоских ЛВС, настолько перегруженных широковещательным трафиком, что только самый современный и мощный компьютер может справиться с его приемом. Если же компьютер слабоват, то он практически повиснет, пытаясь принять, чтобы тут же отбросить, бесконечный поток не интересных ему широковещательных кадров.
Кстати, потребление электроэнергии компонентами и узлами сети тоже зависит от того, насколько оптимизировано в ней распространение трафика.
Это положение можно было бы значительно улучшить, если бы розыск соседей перешел на групповое вещание. В простом канале типа "общая шина" нежелательный групповой трафик отфильтруют сетевые адаптеры, а в современной коммутируемой ЛВС он даже не попадет в те сегменты, где его никто не ожидает. Вот нам задача номер один.
Например, коммутируемая ЛВС Ethernet сможет оптимизировать групповой трафик, если в ней применяется "подслушивание IGMP/MLD" (IGMP/MLD snooping) [RFC 4541] (см. §6.4) или специализированный протокол GMRP [IEEE 802.1ak 2007].
В IPv4 существовала группа "все узлы данной подсети", 224.0.0.1, а ей отвечал определенный групповой канальный адрес. Например, в Ethernet это был адрес MAC 01-00-5E-00-00-01. Но, увы, построить на этом стандартный механизм розыска соседей было нельзя, потому что поддержка группового вещания в IPv4 так и осталась необязательной [§3.3.7 RFC 1122].
Теперь же, в IPv6, групповое вещание — обязательная возможность (см. §2.8), и мы могли бы основать розыск соседей на групповом адресе "все узлы канала", FF02::1. Это сразу ограничило бы круг вовлеченных в него узлов только теми, что поддерживают IPv6. Но не можем ли мы придумать решение еще лучше?
Подсказкой нам послужит внушительная длина адреса IPv6. А что если мы закодируем в групповом адресе самую характерную часть искомого индивидуального адреса? Положим, канал объединяет какое-то число узлов IPv6. Их интерфейсам, смотрящим в этот канал, назначена одна и та же подсеть, но идентификатор интерфейса у каждого свой. Кроме того, мы заранее знаем, что длина этого идентификатора 64 бита. Значит, мы могли бы перенести их во внутриканальный групповой адрес с определенным префиксом, назначенным для этой цели. Допустим, если бы это был префикс FF02::/64, то из индивидуального адреса 2001:DB8:1:2:3:4:5:6 (И) мы получили бы групповой адрес FF02::3:4:5:6 (Г) . Теперь узел Б, владелец адреса И, должен вступить в группу Г и принимать запросы о розыске соседей. Его сосед А, разыскивающий адрес И, пошлет запрос по адресу Г и прицельно попадет запросом в узел Б, потому что в данной подсети ни у кого больше нет такого идентификатора интерфейса.
На словах звучит эффектно; а что произойдет в действительности? Прежде всего, узел А должен преобразовать адрес Г в групповой канальный адрес. Эта процедура не представляет сложности, потому что она выполняется локально (см. §4.1.1), однако часть битов идентификатора группы при этом, как правило, теряется. Так, например, при инкапсуляции Ethernet из группового адреса IPv6 в групповой адрес MAC переходят только младшие 32 бита. Кроме того, каждая группа занимает какое-то количество ресурсов в интеллектуальной ЛВС, оптимизирующей групповой трафик. Говоря проще, коммутаторам такой ЛВС приходится следить за "географией" каждой группы. Поэтому давайте ограничим общее число групп, которые могут возникнуть на одном канале при розыске соседей. Для этого пусть в групповой адрес Г попадают только избранные биты адреса И.
Но сколько и каких битов искомого адреса будет лучше всего взять? Мы уже выяснили, что они должны принадлежать идентификатору интерфейса. Когда администратор сети назначает эти идентификаторы вручную, то, скорее всего, он будет выбирать небольшие числа: 1, 2, 3… Если же идентификатор создается из адреса MAC 48 по рецепту §2.7, то мы должны учесть структуру этого адреса. Старшие 24 бита в нем — это OUI. Если, например, организация закупает для своей сети оборудование избранного производителя, то поле OUI в его адресах MAC окажется одинаковым (или будет принимать ограниченный набор значений). В то же время, младшие 24 бита в адресе MAC (добавочный идентификатор) носят куда более случайный характер, потому что в пределах одного OUI они уникальны, а каждый производитель назначает их независимо от своих конкурентов. Наконец, если у интерфейса есть адрес EUI-64, то добавочный идентификатор занимает в нем 40 бит. Их распределение зависит от политики производителя; в частности, при последовательном назначении старшие биты могут совпадать в пределах одной партии оборудования, а младшие будут разными. Таким образом, младшие 24 бита искомого адреса — это хороший выбор при разных политиках назначения идентификаторов интерфейсам. Тогда общее число групп, которые могут возникнуть в одном канале при розыске соседей, не превысит . Да, это тоже немало, но, тем не менее, существенно меньше, чем первоначальные .
Попытайтесь вспомнить или выяснить, почему , а не . (Подсказка: в формате "модифицированный EUI-64" тоже есть бит I/G, он же g, а розыск ведется только по индивидуальному адресу.)
Итак, мы вполне обоснованно решили, что в особый групповой адрес Г попадают только 24 младших бита искомого адреса И. Соответственно, заранее известный групповой префикс должен быть длиной 104 бита. На эту роль назначен общепринятый префикс FF02::1:FF00:0/104 [§2.7.1 RFC 4291]. Например, из нашего адреса И, то есть 2001:DB8:1:2:3:4:5:6, получится такой адрес Г: FF02::1:FF05:6. Общепринятый термин для внутриканального группового адреса, составленного по этому рецепту, — групповой адрес искомого узла (solicited-node multicast address).
Таково общепринятое английское название, тогда как русскоязычная терминология IPv6 еще только формируется. Обнаруженный нами у других авторов2 R. Stewart, M. Tüxen, P. Lei. SCTP: What is it, and how to use it? BSDCan 2008. http://www.intuit.ru/department/network/pami/1/6.html [ ] вариант "адрес активного узла" кажется нам не совсем удачным, так как он плохо передает смысл данного понятия.
Теперь мы знаем, по какому адресу надо слать запрос о розыске соседа. Это адрес группы искомого узла, объединяющей все интерфейсы канала с индивидуальными адресами, у которых младшие 24 бита такие же, как в искомом адресе. Хотя в такую группу могут попасть несколько интерфейсов с разными адресами, розыск соседей становится значительно прицельнее, нежели при широковещании или рассылке по групповому адресу "все узлы". Конечно, теперь всякий узел IPv6, назначая своему интерфейсу индивидуальный адрес, обязан вступить на этом интерфейсе в соответствующую группу искомого узла, чтобы принимать запросы от соседей. Когда же адрес удаляется, узел должен выйти из этой группы, если только на интерфейсе не остается других адресов с теми же 24-мя младшими битами. На этом наша первая задача решена.
На первый взгляд, число групп искомого узла, в которые узлу надо вступить на данном интерфейсе, равно числу индивидуальных адресов на этом интерфейсе. Но чуть более внимательный анализ обнаруживает известное нам свойство: разные индивидуальные адреса отображаются в один и тот же групповой адрес искомого узла, если в них совпадают 24 младших бита. Таким образом, аккуратный выбор идентификаторов интерфейса может сократить число групп искомого узла, которые придется слушать. Простейший подход сводится к тому, чтобы все идентификаторы интерфейса сделать одинаковыми, например, основанными на модифицированном EUI-64 этого интерфейса. Тогда адреса IPv6 этого интерфейса будут отличаться только префиксами подсети, а их группы искомого узла заведомо совпадут. Почему число таких групп стоит ограничивать? Во-первых, как мы сказали на с. 103, группы расходуют ресурсы сети. А во-вторых, современные сетевые адаптеры могут сами фильтровать групповой трафик, чтобы освободить шину и центральный процессор, но длина аппаратного фильтра в них ограничена. Когда узел слушает много разных групп и длина такого фильтра оказывается превышена, адаптер вынужден принимать весь групповой трафик в надежде, что центральный процессор разберется.
Группа искомого узла — это лишь частный случай применения группового вещания IPv6 для направленного розыска сетевых ресурсов. В общем случае, узел, обладающий ресурсом, вычисляет групповой адрес как функцию от имени ресурса и вступает в эту группу, а узел-искатель, зная имя ресурса, проводит то же самое вычисление и направляет по полученному групповому адресу запрос. К примеру, так можно разыскивать хост по его символьному имени: от имени хоста в заданной кодировке вычисляют хэш-функцию подходящей длины и добавляют к ее значению общепринятый групповой префикс. На этой идее уже основан один экспериментальный протокол для запроса информации об узлах IPv6 [RFC 4620].
Следующий вопрос заключается в том, как будет устроен протокол розыска соседей. Пока что мы не определились даже с его уровнем в стеке. Привлечение групповых адресов сетевого уровня означает, что новый протокол мы должны разместить над IPv6, а не рядом с ним, в отличие от IPv4 и ARP. По сути, розыск соседей — это один из аспектов управления IPv6, так что давайте поступим просто: пусть розыск соседей станет подмножеством ICMPv6. Это подмножество кратко обозначают ND (от neighbor discovery) [RFC 4861].
Как следствие, сообщения ND будут инкапсулированы в пакеты IPv6, а тогда на них смогут распространяться пакетные фильтры и прочие правила сетевой политики. Поэтому придется быть вдвойне осторожным, чтобы по ошибке не блокировать легитимный трафик ND и тем самым не "сломать" механизм разрешения адресов — ведь от его сбоя пострадает передача всего индивидуального трафика!
Такая позиция ND в стеке протоколов позволит применять его на любых каналах, способных инкапсулировать IPv6. Хотя сам по себе розыск соседей необходим далеко не всем типам каналов, например, он явно избыточен на каналах "точка-точка", мы создадим механизмы на основе протокола ND, которые будут уместны независимо от типа канала. Поэтому сразу выдвинем вот какое положение: ND будет работоспособен на всех каналах IPv6, которые поддерживают групповое вещание [§3.2 RFC 4861].
Означает ли наш выбор, что сообщения ND смогут пересекать границы каналов? Ведь в общем случае пакеты ICMPv6 подлежат маршрутизации наравне с другими пакетами IPv6. Между тем, из самого определения соседства следует, что пакеты ND должны распространяться только в пределах одного канала. Опасность здесь не только в утечке ND за границы канала, но и в проникновении фальшивых сообщений ND из-за этих границ.
Сможет ли адресат пакета ND узнать, что источник пакета — не его сосед? Если такой адресат не доверяет никому, то задача без дополнительных механизмов неразрешима. Но если адресат доверяет маршрутизаторам данного канала, то он может учесть, что всякий законопослушный маршрутизатор уменьшает значение "предельное число шагов" в заголовке IPv6 транзитного пакета. Сами по себе эти сведения еще ничем не помогают, так как адресат не знает, каким было начальное значение этого поля. Можем ли мы просто зафиксировать это значение? Допустим, мы решили, что начальное значение "предельного числа шагов" в пакетах ND всегда будет X. Теперь адресат пакета сравнивает видимое им значение с X и, если они совпадают, заключает, что пакет пришел от соседа. Но злоумышленник может как-нибудь узнать число шагов H до атакуемого узла и установить поле "предельное число шагов" равным , если отвечает соседству. Как помешать злоумышленнику? Если школьная арифметика помогла ему, то она поможет и нам! По условию задачи, , так как злоумышленник — не сосед атакуемого узла. (Если бы он оказался соседом, узлу пришлось бы совсем несладко!) Значит, злоумышленнику придется увеличить значение "предельного числа шагов" относительно X: . Единственный случай, когда он не сможет этого сделать, — это если значение X уже будет максимально возможным, а именно 255.
Этот трюк работает, только если маршрутизаторы правильно обрабатывают пакеты с нулевым значением "предельного числа шагов", как мы обсудили в §3.2. В противном случае декремент этого значения даст 255 согласно беззнаковой арифметике по модулю 256.
Атаки на ND со стороны соседей нам еще предстоит рассмотреть.
Обнаруженный нами трюк способен защитить от дистанционных атак не только ND и не только в среде IPv6. Ведь все, что ему нужно, — это поле "предельное число шагов" или "TTL" в сетевом заголовке. За свою универсальность этот трюк получил пышноватое название "обобщенный механизм безопасности на основе TTL" (Generalized TTL Security Mechanism), сокращенно GTSM [RFC 5082].
Другой пример протокола, который может выиграть от применения GTSM, — это BGP. Исторически идея GTSM появилась именно в применении к BGP [§4 RFC 5082], а затем ее обобщили и на другие случаи.
Конечно, GTSM не заменяет собой прочие механизмы сетевой безопасности, такие как фильтрация пакетов на границах канала. Просто любая хорошо построенная оборона обязана быть глубоко эшелонированной.
Итак, участники ND обязаны применять GTSM: источник пакета ND должен установить поле "предельное число шагов" равным 255, а его адресат обязан убедиться, что это значение сохранилось [§6.1, §7.1, §8.1 RFC 4861].
Теперь можно перейти к отдельным сообщениям ND. Чтобы провести разрешение сетевого адреса, достаточно двух видов сообщений, которые в первом приближении выглядят как запрос и ответ. Но, как мы помним, даже в ARP строгую последовательность "запрос-ответ" приходилось нарушать, когда узлу надо было послать "добровольный ARP" (gratuitous ARP), чтобы самому объявить соседям свой канальный адрес.
В ARP не имело значения, представлял ли собой добровольный ARP запрос или ответ, потому что алгоритм получателя ARP [RFC 826] проверял код операции только после того, как обновлял локальный кэш.
Не Конфуций ли сказал: если название неправильное, то и слова не повинуются? Поэтому давайте для начала исправим терминологию. Сообщение, которое несет сведения о сетевом и канальном адресах узла, мы назовем объявлением соседа (neighbor advertisement), сокращенно NA. Узел вправе выслать это объявление добровольно или по запросу. Другие же узлы могут запросить такое объявление, когда им это нужно, послав вызов соседа (neighbor solicitation), сокращенно NS.