Этой статьёй я хочу начать цикл, посвященный IPv6. Я являюсь инструктором академии Cisco, поэтому, если вы в совершенстве знаете материал нового CCNA Routing & Switching, то скорее всего, не найдёте в цикле ничего нового. Речь пойдёт о структуре и особенностях протокола IPv6, а также, применении его на маршрутизаторах Cisco (маршрутизация RIP, OSPF, EIGRP, списки контроля доступа, и др. – как пойдёт). В первой статье мы поговорим о структуре IPv6 пакета, записи адресов, префиксе. Вторая статья цикла доступна здесь. Информация подойдёт для новичков, имеющих, тем не менее, некоторые знания по IPv4 и модели OSI.
Цикл статей основан на материалах моего блога, которые, в свою очередь, основаны на опыте преподавания, работы с оборудованием и вольном переводе и обдумывании официального курса CCNA Routing & Switching.
Итак, начнём. Не буду останавливаться на стандартных рассуждениях о том, что IPv4 адресов мало, о том, что NAT и прокси – это костыли, о том, что костыли пока работают, и никто не хочет переходить на IPv6, вместо этого – сразу к сути.
Адрес протокола IPv6 состоит из 128 бит, то есть, он в 4 раза длиннее 32-битного IPv4 адреса. Подобно IPv4, в этом адресе можно выделить две части: сеть и хост. То есть, не все биты в адресе имеют одинаковое значение. Часть битов слева (сколько именно зависит от префикса) обозначают сеть, остальные биты справа – идентифицируют устройство внутри сети. Часть, ответственная за хранение информации о хосте называется идентификатор интерфейса (interface id). В отличие от предыдущей версии протокола, в IPv6 не применяются маски подсети, так как они получились бы очень длинными, вместо этого используется префикс. который записывается так же через слеш после адреса. Например, префикс /64 означает, что из 128 бит, первые 64 – это сеть, а оставшаяся часть (в данном случае вторые 64) – это хост. Префикс описывает, сколько бит в адресе используется под хранение информации о сети.
Сам адрес записывают не в десятичном, а в шестнадцатеричном виде – так короче. Адрес разбивается на группы по 16 бит (хекстеты) и каждая группа представляется четырьмя шестнадцатеричными цифрами. Хекстеты отделяются друг от друга знаком двоеточия. Таким образом, адрес состоит из 8 хекстетов ([8 хекстетов]*[16 бит в хекстете]=[128 бит] – общая длина адреса).
Пример адреса: 2001:0DB8:AA10:0001:0000:0000:0000:00FB. С таким длинным адресом работать достаточно неудобно, поэтому применяют сокращённую запись.
Для того чтобы сократить данный адрес надо последовательно применить два правила.
В каждом хекстете (группе из 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.
Это правило применяется только после первого. В адрес выбирается одна самая длинная группа, состоящая из полностью нулевых хекстетов, то есть самая длинная последовательность «: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.
Теперь, чтобы закрепить понимание, приведём несколько примеров сокращения адресов. Сокращать будем по правилам в два этапа.
Адрес loopback выглядит в сокращённой записи особенно элегантно ::1. Даже если вы не пользуетесь IPv6, но работаете на одной из современных операционных, систем, у вас наверняка установлен этот протокол. Это легко проверить, пропинговав loopback.
При использовании IPv6 адреса в качестве URL, его необходимо заключать в квадратные скобки, при этом, если необходимо указать в URL-е порт, то его следует писать за пределами скобок – http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]:8080/.
Выделяется несколько типов адресов:
Выше было сказано, что клиенту, как правило, выдаётся огромная сеть (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:… — уже можно.
Цикл статей основан на материалах моего блога, которые, в свою очередь, основаны на опыте преподавания, работы с оборудованием и вольном переводе и обдумывании официального курса 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:… — уже можно.