IPv6 теория и практика: введение в IPv6

  • Tutorial
Этой статьёй я хочу начать цикл, посвященный IPv6. Я являюсь инструктором академии Cisco, поэтому, если вы в совершенстве знаете материал нового CCNA Routing & Switching, то скорее всего, не найдёте в цикле ничего нового. Речь пойдёт о структуре и особенностях протокола IPv6, а также, применении его на маршрутизаторах Cisco (маршрутизация RIP, OSPF, EIGRP, списки контроля доступа, и др. – как пойдёт). В первой статье мы поговорим о структуре IPv6 пакета, записи адресов, префиксе. Вторая статья цикла доступна здесь. Информация подойдёт для новичков, имеющих, тем не менее, некоторые знания по IPv4 и модели OSI.
Цикл статей основан на материалах моего блога, которые, в свою очередь, основаны на опыте преподавания, работы с оборудованием и вольном переводе и обдумывании официального курса CCNA Routing & Switching.
Итак, начнём. Не буду останавливаться на стандартных рассуждениях о том, что IPv4 адресов мало, о том, что NAT и прокси – это костыли, о том, что костыли пока работают, и никто не хочет переходить на IPv6, вместо этого – сразу к сути.

Адреса IPv6


Адрес протокола IPv6 состоит из 128 бит, то есть, он в 4 раза длиннее 32-битного IPv4 адреса. Подобно IPv4, в этом адресе можно выделить две части: сеть и хост. То есть, не все биты в адресе имеют одинаковое значение. Часть битов слева (сколько именно зависит от префикса) обозначают сеть, остальные биты справа – идентифицируют устройство внутри сети. Часть, ответственная за хранение информации о хосте называется идентификатор интерфейса (interface id). В отличие от предыдущей версии протокола, в IPv6 не применяются маски подсети, так как они получились бы очень длинными, вместо этого используется префикс. который записывается так же через слеш после адреса. Например, префикс /64 означает, что из 128 бит, первые 64 – это сеть, а оставшаяся часть (в данном случае вторые 64) – это хост. Префикс описывает, сколько бит в адресе используется под хранение информации о сети.
Сам адрес записывают не в десятичном, а в шестнадцатеричном виде – так короче. Адрес разбивается на группы по 16 бит (хекстеты) и каждая группа представляется четырьмя шестнадцатеричными цифрами. Хекстеты отделяются друг от друга знаком двоеточия. Таким образом, адрес состоит из 8 хекстетов ([8 хекстетов]*[16 бит в хекстете]=[128 бит] – общая длина адреса).

Сокращение IPv6


Пример адреса: 2001:0DB8:AA10:0001:0000:0000:0000:00FB. С таким длинным адресом работать достаточно неудобно, поэтому применяют сокращённую запись.
Для того чтобы сократить данный адрес надо последовательно применить два правила.
Правило 1

В каждом хекстете (группе из 4-х цифр) ведущие нули удаляются. Например, во втором хекстете 0DB0 заменяется на DB0. То есть ноль слева удаляется, ноль справа мы не трогаем. Если хекстет состоит из одних нулей, то он заменяется на один нуль. Таким образом адрес 2001:0DB0:0000:123A:0000:0000:0000:0030 преобразуется в 2001:DB0:0:123A:0:0:0:30. А, например, адрес loopback 0000:0000:0000:0000:0000:0000:0000:0001 заменяется на 0:0:0:0:0:0:0:1.
Правило 2

Это правило применяется только после первого. В адрес выбирается одна самая длинная группа, состоящая из полностью нулевых хекстетов, то есть самая длинная последовательность «:0:0:0:» и заменяется на два двоеточия «::». Эту замену можно произвести только один раз и только с самой длинной последовательностью, так как, если бы мы, например, сделали такую замену в двух местах адреса, то потом нельзя было бы восстановить, сколько именно хекстетов мы заменили в первом и во втором случае. Важный момент: нельзя заменять одну группу из :0: на ::, правило два применимо только если есть более одной нулевой группы.
Для примера возьмём адрес из предыдущей замены 2001:DB0:0:123A:0:0:0:30. Самая длинная последовательность из полностью пустых хекстетов – это «:0:0:0:», она начинается сразу после хекстета «123A». Есть ещё последовательность из одного пустого хекстета (между «DB0» и «123A»), но эта – длиннее, так что заменять будем её. Адрес станет совсем небольшим: 2001:DB0:0:123A::30 конечно, длиннее IPv4 адреса, но гораздо короче исходного.
Получение исходного адреса по сокращённой записи

Эта процедура достаточно тривиальна, если мы уже умеем сокращать адреса.
Сначала надо посчитать, сколько хекстетов в адресе осталось. В нашем случае, в адресе 2001:DB0:0:123A::30 осталось 5 хекстетов. Мы знаем, что адрес должен состоять из восьми хекстетов – значит вместо «::» возвращаем три недостающих нулевых, получаем 2001:DB0:0:123A:0:0:0:30. Теперь в каждой группе, где меньше четырёх цифр дописываем слева такое количество нулей, чтобы в группе стало четыре цифры. В результате получим исходный адрес 2001:0DB0:0000:123A:0000:0000:0000:0030.
Примеры

Теперь, чтобы закрепить понимание, приведём несколько примеров сокращения адресов. Сокращать будем по правилам в два этапа.
  • FF80:0000:0000:0000:0123:1234:ABCD:EF12 → FF80:0:0:0:123:1234:ABCD:EF12 → FF80::123:1234:ABCD:EF12
  • FF02:0000:0000:0000:0000:0001:FF00:0300 → FF02:0:0:0:0:1:FF00:300 → FF02::1:FF00:300
  • 2001:0DB8:0000:1111:0000:0000:0000:0200 → 2001:DB8:0:1111:0:0:0:200 → 2001:DB8:0:1111::200
  • 0000:0000:0000:0000:0000:0000:0000:0001 → 0:0:0:0:0:0:0:1 → ::1
  • 0000:0000:0000:0000:0000:0000:0000:0000 → 0:0:0:0:0:0:0:0 → ::

Адрес loopback выглядит в сокращённой записи особенно элегантно ::1. Даже если вы не пользуетесь IPv6, но работаете на одной из современных операционных, систем, у вас наверняка установлен этот протокол. Это легко проверить, пропинговав loopback.
ping ::1
Pinging ::1 with 32 bytes of data:
Reply from ::1: time<1ms
Reply from ::1: time<1ms
Reply from ::1: time<1ms
Reply from ::1: time<1ms
Ping statistics for ::1:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms

При использовании IPv6 адреса в качестве URL, его необходимо заключать в квадратные скобки, при этом, если необходимо указать в URL-е порт, то его следует писать за пределами скобок – http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]:8080/.

Виды IPv6 адресов


Выделяется несколько типов адресов:
  • Глобальный юникаст (Global unicast) – это аналог публичных адресов в IPv4. Большая часть всех адресов относятся именно к этому классу. Эти адреса должны быть уникальными в пределах всего интернета, они выдаются IANA региональным регистраторам, те выдают их провайдерам, а провайдеры – выдают клиентам. Диапазон этих адресов – это все адреса, у которых первые три бита равны «001», что означает все адреса, у которых первый хекстет лежит в диапазоне от 2000 до 3FFF. Из этой группы отдельно выделяется сеть 2001:0DB8::/32, которая, согласно спецификации, используется для примеров и документации.
  • Локальные адреса (Link-local) – адреса, использующиеся для взаимодействия с другими устройствами в той же локальной сети. Отличительной особенностью этих адресов является то, что трафик «с» или «на» эти адреса не маршрутизируется и в принципе не может выйти за пределы той сети, в которой он был создан. Уникальность от этих адресов не требуется – в каждой сети они могут быть одними и теми же. Адреса применяются для разных специальных целей, например, для процедуры обнаружения соседей (аналог ARP в IPv6). Диапазон таких адресов FE80::/10 – что означает все адреса у которых первый хекстет в диапазоне от FE80 до FEBF.
  • Мультикастовые адресе (Multicast) – адреса, использующийся для мультикастовой рассылки. Все эти адреса находятся в диапазоне FF00::/8, что по-русски означает «Всё что начинается с FF». Надо сказать, что мультикаст в IPv6 выполняет важную роль, так как в нём нет широковещательных пакетов и все рассылки делаются мультикастом. Это очень большая тема, поэтому о мультикастах в IPv6 мы поговорим в одной из следующих статей.
  • Loopback – специальный адрес ::1. Все пакеты, идущие на него не выходят за пределы устройства, а попадают обратно на уровень IP. Таким образом, этот адрес аналогичен 127.0.0.1 в IPv4. Командой ping ::1 можно проверить, установлен ли на компьютере стек протоколов TCP/IP и IPv6 в частности.
  • Неопределённый адрес (Unspecified address) – адрес, состоящий из одних нулей. Записывается в сокращённой форме как «::». Такой адрес не может быть назначен интерфейсу, но может использоваться в некоторых пакетах в качестве адреса отправителя. Например, когда устройство ещё не получило IP адрес с помощью автоматической конфигурации, о ней – тоже в одной из следующих статей.
  • Уникальные локальные адреса (Unique local) – аналог приватных адресов в IPv4, то есть они могут маршрутизироваться в пределах нашей внутренней сети, но в интернет их анонсировать нельзя. Вообще, IPv6 подразумевает отказ от приватных адресов в том смысле, в котором они использовались до этого. В IPv4 приватные адреса применяются в основном из-за нехватки публичных и только иногда из соображений безопасности. В IPv6 использовать локальные адреса надо только в том случае, если по соображениям безопасности трафик из данной сети и в неё не должен уходить за пределы нашей зоны ответственности. Во всех остальных случаях следует использовать глобальные юникастовые адреса.
  • Адреса IPv4, отображенные в IPv6 (IPv4 embedded) – это адреса вида ::ffff:xxxx:xxxx, где xxxx:xxxx – это некоторый IPv4 адрес, переведённый в шестнадцатеричный вид. Эти адреса используются для устройств, не поддерживающих IPv6 и обеспечивают способ отображения адресного пространства старой версии протокола в адресное пространство новой.

Выше было сказано, что клиенту, как правило, выдаётся огромная сеть (64 бита префикс), а первые 64 бита – это идентификатор сети. Понятно, однако, что сама эта сеть тоже имеет иерархическую структуру. Как правило, региональный регистратор отдаёт провайдеру сеть с префиксом /48, а провайдер добавляет от себя ещё 16 бит и получает 65536 сетей с префиксом /64, которые затем отдаёт своим клиентам.
UPD1: В комментариях подсказывают «Региональные регистраторы давно уже дают /32 сеть по умолчанию или больше адресов, если сможешь обосновать зачем.»
UPD2: Важное замечание в комментариях относительно IPv4 embedded адресов: «Mapped-адреса используются, прежде всего, в dual-stack. Когда создаётся один сокет IPv6 на оба протокола ( IPv4 и IPv6 ), и везде используется IPv6 адреса. Т. е. если через этот сокет пришли данные через IPv4, адрес будет показан всё равно в виде вышеописанного IPv6 mapped-адреса. На канальном уровне разницы не будет вообще. Там будет старый добрый IPv4, разница только в в унификации отображения для пользователя.»
UPD3: Готова вторая статья цикла.
UPD4: Внимательный пользователь сообщил мне на счёт сокращения адресов интересную информацию, о которой я не знал. Правило 2, по RFC5952, применимо только когда у нас более одной группы, состоящей из нулей. То есть ...:0:… нельзя заменить на ...::..., а ...:0:0:… — уже можно.
Share post

Similar posts

Comments 41

    +2
    Региональные регистраторы давно уже дают /32 сеть по умолчанию или больше адресов, если сможешь обосновать зачем. /48 более актуально для PI сетей.
      +5
      LIR'ы получают /32, на тренинге говорили, что надо стремиться к одному размеру выделяемого клиентам сегмента. Рекомендовано (примерно): /56 на заявку, если есть необходимость в нескольких сетях клиента — /48, если есть более-менее адекватное обоснование — до /32 на клиента (в этом случае LIR'у выдают ещё одну /32).

      LIR, который выдаёт клиентам /64, будет побит камнями, потому что если в BGP будут анонсить квинтиллионы /64, то компания «сисько системсь» озолотится, барыжа маршрутизаторы с терабайтами памяти под full view.

      Таким образом становится понятно, почему сисько рекомендует LIR'ам выдавать побольше /64 и поменьше агрегированных сетей.
        0
        Вы так говорите (про анонсы /64 в BGP), как, например, сейчас провайдеры якобы вываливают в full view каждый ipv4 /32, который они выдают каждому домашнему роутеру на PPPoE. Ну такого же нет. Зачем вы вводите людей в заблуждение?
          +3
          Статью поправили. В оригинале было так, что лиры должны клиентам 64 выдавать.
            +1
            Подпрваил только опечатку "… а провайдер добавляет от себя ещё 16 бит и получает 65536 сетей с префиксом...", было "… получает 216 сетей..." и то что помечено как UPD.
          • UFO just landed and posted this here
              –1
              Ну если у вас есть какой-то пиринг с админом-идиотом на той стороне — то вас жаль.
              • UFO just landed and posted this here
                0
                /32 иногда анонсят аплинкам, которые умеют blackhole community :)
            +2
            У меня такое ощущениие, что эти IPv6 адреса как то чересчур щедро раздаются. Ну зачем каждому человеку 2^64 адресов? Так раздадут и лет через 50 IPv6 закончатся. Это будет вообще весело. Просветите в этом отношении меня, если не сложно.
              +1
              /64 — это минимальный рекомендуемый префикс в основном для механизмов stateless настройки ipv6-адресов. Также начиная от такой длины префикса аппаратные роутеры/коммутаторы оптимально используют TCAM память.

              Нынешняя выдача операторам /32 аналогична выдаче /24 ipv4 (если учитывать размер кусочка от всего пирога адресного пространства ipv6 и ipv4), но /32 ipv6 оператор может использовать на более чем 100000 абонентов (в ipv4 на то потребовалось бы префикса /15).
                0
                «Также начиная от такой длины префикса аппаратные роутеры/коммутаторы оптимально используют TCAM память.»
                Вы не могли бы пояснить почему?
                  +1
                  потому что для префикса /64 достаточно хранить саму сеть, т.е. 64бита и длину префикса, то в случае /65-/128 нужно хранить префикс большей длины, а учитывая, что самые распространенные архитектуры 32бит или 64бит, то получаем увеличение необходимой памяти в 1,5-2 раза или невозможность коммутации по таким префиксам аппаратно и обработка происходит на CPU.
                    0
                    Вполне разумно звучит.
                +1
                rfc3177
                основная идея в том, что такая схема очень удобна, т.е.
                провайдеру удобно выделять всем абонентам префиксы одинаковой длины, удобно выдать настройки один раз и не менять.
                удобно когда все блоки одинакового размера, у всех провайдеров, а 2^64 — достаточно всем, даже очень крупным предприятиям, с кучей филиалов.
                /48 на провайдера, потому что 48+(8+8)=64 и т.п.
                ещё придумывают разные экспериментальные протоколы, для которых важно предположение, что первые 64 бита — сеть, а следующие 64 — хост.

                ну и последнее, сейчас выдаётся только часть адресного пространства, и если текущая схема каким-либо образом себя дискридитирует, то её можно будет поменять.
                  +1
                  Тут надо смотреть не слева направо а справа налево. Фишка /64 в том, чтобы все (!) клиентские сети были одного размера. То есть, даже если мы поместим в одну ethernet сеть все возможные мак-адреса, то получим только 48 бит занятых в хостовой части. А что касается заканчивающихся адресов — просто посчитайте. Оставшиеся 64 бита — это очень много. Опять же, тут уже писали, что выдаётся сейчас только диапазон начинающийся на двойку, на сколько я помню. Соответственно, если он закончится быстрее планируемого, то дальше можно будет попробовать поменять схему. Впрочем, вряд ли изменения коснутся хостовой части адреса, уж больно много всего завязано сейчас на эти /64 Скорее пересмотрят использование адресов в маленьких сетях точка-точка, или не будут выдавать провайдерам по /32
                    +1
                    Раньше и ipv4 тоже довольно-таки щедро раздавался. Не так, как ipv6, но всё равно щедро.
                    +1
                    Кажется у меня появился шанс понять ipv6, спасибо за статью!
                      +1
                      Пожалуйста. Сам начинал с того что разбирался и делал заметки для себя. Сейчас беру статьи со своего блога, привожу их в хаброчитаемый вид, склеиваю несколько в один материал и готовлю к публикации. Вторая статья цикла будет сегодня вечером, дальше — задержки возрастут.
                      0
                      Автор, объясните, чем мне помогут ::ffff:xxxx:xxxx-адреса. Вы уверяете, что
                      Эти адреса используются для устройств, не поддерживающих IPv6

                      Вот у меня есть железка X, умеющая только ipv4. Что дальше?
                        0
                        На сколько я понимаю, оно не должно и не будет работать. Это просто формальный способ отображения одного множества на другое, чтобы всё было разложено по полочкам в IPv6
                          0
                          В смысле? Вы уверяете это в статье. Я спрашиваю, что и как конкретно.
                          Теперь вы отказываетесь от своих слов.

                          Простите, но ваша статья ужасно сырая и в голове каша.
                          +5
                          Mapped-адреса используются, прежде всего, в dual-stack. Когда создаётся один сокет IPv6 на оба протокола ( IPv4 и IPv6 ), и везде используется IPv6 адреса. Т. е. если через этот сокет пришли данные через IPv4, адрес будет показан всё равно в виде вышеописанного IPv6 mapped-адреса. На канальном уровне разницы не будет вообще. Там будет старый добрый IPv4, разница только в в унификации отображения для пользователя.
                            –1
                            Спасибо — этого мне очень не хватало.
                              +2
                              По сути, чтобы можно было писать сервера, не задумываясь о IPv4: создаёшь сокет «socket(AF_INET6, SOCK_STREAM, 0)» и если через setsockopt не поставить IPV6_V6ONLY, то библиотека сама будет преобразовывать отправку на IPv6 адрес ::ffff:xxxx:xxxx в отправку на IPv4 xx.xx.xx.xx (и в обратную сторону при приёме, естественно, т.е. будут прослушиваться оба порта IPv6:yyyy и IPv4:yyyy).
                              0
                              Это вообще дырка для совместимости с IPv4 сетью, чтобы вообще была теоретическая возможность из IPv6 сети без проблем взаимодействовать с IPv4 сетью через аппаратные шлюзы. Потом когда нибудь это всё уйдет в историю, а пятно останется.
                                +1
                                Вы о каких шлюзах? Mapped-адреса на канальном и сетевом уровне ничем не отличаются от нативного IPv4. Они используются только чтобы представить для пользователя v4 адрес в формате v6. Железо не знает таких адресов, вы, вероятно, путаете с NAT64.
                                  0
                                  Я имею в виду переходник из IPv6 сети в IPv4 для устройств которые вообще не в курсе что есть в мире IPv6 но вынужденные по каким-то причинам работать в IPv6 сетях. Наверно это и есть NAT64. В любом случае для избежания конфликтов должен быть зарезервирован диапазон адресов.
                                +3
                                когда есть только железка IPv4 — это все не имеет смысла.
                                но когда есть железка с IPv6, и с нее надо достучаться до железки с поддержкой только IPv4
                                вот так можно сделать ping 192.168.10.1 через IPv6
                                C:\>ping ::ffff:c0a8:0a01
                                
                                Обмен пакетами с 192.168.10.1 по с 32 байтами данных:
                                Ответ от 192.168.10.1: число байт=32 время=1мс TTL=64
                                Ответ от 192.168.10.1: число байт=32 время=5мс TTL=64
                                Ответ от 192.168.10.1: число байт=32 время=2мс TTL=64
                                Ответ от 192.168.10.1: число байт=32 время=2мс TTL=64
                                
                                Статистика Ping для 192.168.10.1:
                                    Пакетов: отправлено = 4, получено = 4, потеряно = 0
                                    (0% потерь)
                                Приблизительное время приема-передачи в мс:
                                    Минимальное = 1мсек, Максимальное = 5 мсек, Среднее = 2 мсек
                                

                                В данном случае пингуется шлюз-роутер, у которого нет IPv6 (и никогда не будет :( )

                                  +2
                                  Да, но при этом используется на обоих узлах чистый IPv4. Тут не используется IPv6 как протокол! Используется только визуальный формат в виде IPv6, дальше по стеку идёт чистейший IPv4, который вообще не знает о v6, т. к. получает уже преобразованный чистый 32-битный IPv4.
                                  Достучаться с IPv6-only железки до IPv4-only железки через такой адрес невозможно!
                                    0
                                    что в этой статье и указано.
                                +1
                                А можете рассказать про IPv6 и IPSec? Как-то уже спрашивал дали только ссылку, из которой следует что поддерживается это только в Linux. Но насколько? Уже можно пользоваться, или шифрование еще в стадии разработки? Просто когда говорят про IPv6, говорят что у него есть шифрование и это круто. Хочется подробностей.
                                  0
                                  а почему нет ни слова про anycast? они хоть и не выделаются в отдельный префикс, на как один из типов адресов достойны упоминания…
                                    0
                                    Про anycast будет пара слов в следующей статье, но глобально я в нём не очень ориентируюсь. Если у вас есть хорошие материалы — было бы интересно почитать
                                    0
                                    Согласно, RFC4291, у нас, выходит, только одни Loopback адрес ::1?
                                    Получается нет больше 127.0.0.1 — 127.255.255.255 такого диапазона loopback'ов (если конечно не использовать Mapped-адреса: ::ffff:7f00:2)?
                                      +1
                                      Тут как раз ничего странного, меня наоборот всегда интересовало, зачем в IPv4 стооолько адресов для лупбэков. Я как-то не чувствую что лупбэков мало. ;-)
                                        0
                                        127.0.1.1, 127.1.1.1 это кроме «каноничного» 127..0.1 оторые я встречал в реальных конфигах.
                                        Ну с цисками там понятно, в маршрутизации эти лупбек адреса достаточно активно использовались, насколько помню курс и лабы по icnd v2, а в нормальных ОС я честно даже и не знаю, зачем такое делать…
                                          0
                                          Это нужно для локально межпроцесового взаимодействия.
                                          например можно два сервера поднять по разным 127.x.x.x и на одном порту.
                                            –1
                                            Проверил, и действительно: если делать сокету bind к адресу 127.0.0.2, то коннект на адрес 127.0.0.1 не проходит, а на адрес 127.0.0.2 — проходит.
                                        +1
                                        Не раскрыта тема v6-адресов с точками от ipv4.
                                        Например, 2002:d941:d96c:8000:0:5efe:10.0.5.37
                                        Судя по количеству недостающих хекстетов, последние 32 бита записаны в стандарте ipv4
                                        В каких случаях применяется такая запись?
                                          +2
                                          В случаях, когда префикс embedded-адреса равен всему остальному, не считая собственного самого IPv4 адреса, т. е. 128 — 32 = 96 битам.
                                          Но это не обязательно, можно писать и хекстетами.
                                          Просто по умолчанию принято, если префикс embedded-адреса равен /96, то последние 2 хекстета можно записать октетами через точку для наглядности.

                                        Only users with full accounts can post comments. Log in, please.