Основы IPv6

Предисловие

Пост является кратким конспектом Wiki, Technet’a, FreeBSD’шного handbook’a, Serverfault’a, множества RFC и документов IANA, а также курсов от Специалист.Ру для сотрудников Яндекса.

Пост можно рассматривать как копилку ссылок по актуальной на 2012 год спецификации IPv6. Однако он никак не описывает возможные способы установки IPv6 соединения с интернетом и не привязан к какой-либо определённой ОС.
Учтите, что прочтение данной хабрастатьи займёт у вас не более получаса, однако крайне рекомендуется ознакомиться со всеми приведёнными в статье ссылками… Последнее может занять несколько недель.

Prerequisites
Хоть статья и называется «Основы IPv6» она всё-таки подразумевает наличие базовых знаний о IP сетях и хотя бы небольшой практический опыт работы с IPv6, в противном случае хабрастатья будет даваться очень не легко.
Так же рекомендуется к прочтению документ Implementing IPv6 Addressing and Basic Connectivity от Cisco.
Ещё стоит заметить, что приведённые на википедию ссылки зачастую более примечательны разделом References нежели своим содержанием.

IPv6 Адреса

Анатомия IPv6 адресов
В первой версии этого хабрапоста тут было много текста, но с того момента на википедии выросла отличная статья: IPv6 Address.

Маски подсетей
Маски теперь задаются только /prefix’ами (CIDR), классовой адресации и стандартной decimal dotted нотации в IPv6 нет. Так же теперь первый и последний адрес сети не являются зарезервированными под идентификатор сети и broadcast соответственно.

Выделение IPv6 адресов
Как и в случае с IPv4, IPv6’ые адреса выделяются через целую иерархию организаций:
RIR(/12-/23) -> NIR(??) -> LIR(/19-/32) -> ISP(/48-/56) -> LAN(=>/64)
ISP уже выделяют адреса сетям как хотят. Однако и тут есть Best-Practice от IPv6 Task Force: Guidelines for ISPs on IPv6 Assignment to Customers.
В общем пожелания по выделению IPv6 адресов описаны в RFC5375 IPv6 Unicast Address Assignment Considerations
Также интересная деталь: Таблицы маршрутизации в IPv6 планировали изначально делать как можно более «агригабельными», что подразумевало отсутствие Provider-Independent (PI) адресов. Однако крупные копрорации (видимо желающие делать BGP-failover) в 2009 году всё-таки «продавили» RIPE, так что получить PI-адреса в IPv6 теперь реально.

Типы адресов и их префиксы
Об IPv6 адресации подробно рассказано в RFC4291. Далее я опишу самые распространённые типы IPv6 адресов, их назначения и префиксы.

::/128 — Unspecified — не должен принадлежать ни одной ноде в сети;
::/0 — Default route;
::1/128 — Loopback;

fe80::/10 — Link-Local — адреса уникальные на линке. Создание IPv6 link-local адреса из префикса fe80:: и MAC адреса сетевой карты, как и многое другое описано в презентации от Microsoft и в документе Introduction to IP Version 6, также процедура создания модифицированного EUI-64 идентификатора на пальцах разъяснена в Приложении А RFC4291);
fec0::/10 — Site-Local — устарели судя по RFC3879;
fc00::/7 — Unique Site-Local— пришли на замену Site-Local в RFC4193. В данный момент разбит на две части: fc00::/8 и fd00::/8. Уникальные в пределах организации, е роутящиеся в интернет адреса. Однако могут роутиться внутри site’a и между site’ами;
ff00::/8 — Multicast — о мультикасте подробнее расскажу чуть ниже. Полный список мультикаст адресов можно посмотреть тут: IANA IPv6 Multicast Addresses;
::0000/96 — IPv4-Compatible IPv6 Addressустарели;
::ffff/96 — IPv4-Mapped IPv6 Address — Адреса предназначенные в основногм для Socket API. Более подробно их назначение описано в RFC4038. рочтение этого RFC будет полезно программистам которые собираются писать Dual-Stack приложения;

Все «не специальные» адреса относятся к:
Global Unicast — глобальные адреса, уникальные во всем интернете. Пока, впрочем, судя по этому документу, доступно только глобальное пространство 2000::/3 (Адреса от 2000:: до 3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff)

Виды трафика
Unicast — Старый добрый юникаст;
Multicast — Мультикаст теперь необходимое расширение, а не опциональное как в IPv4. IGMP был заменён на MLD. А процедура получения глобального мультикаст префикса стала тривиальной — теперь при получении /64 префикса провайдер автоматически получает 4.2 миллиарда глобальных мультикаст групп. Процедура подробно описана в RFC3306, а также дополнена внедрением адреса RP прямо в IPv6 адрес в RFC3956. Получение глобального мультикаст префикса для IPv4 и IPv6 описано в RFC6308. Стоит также заметить, что в IPv4 Multicast link-layer префикс был 01:00:5e, в IPv6 он стал 33:33:ff (посмотреть список групп для интерфейсов во FreeBSD можно через ifmcstat или же через ip maddr в Linux);
Anycast — Такой же anycast как и в IPv4. Этот тип адреса обычно анонсируется протоколом динамической маршрутизации (например BGP), сразу из нескольких мест. Это обеспечивает оптимальный, с точки зрения протокола маршрутизации, роутинг;
Broadcast — в IPv6 broadcast’а не существует. В место него можно использовать All Nodes Address. Пакеты посланные на него будут рассылаться только на хосты с настроенным IPv6 адресом (при включеном MLD snooping’е); Также часть протоколов раньше использовавших Broadcast в IPv6-версии всёже обзавелись собственной multicast группой;

Address Scope
В IPv6 появилось такое понятие как Scope , он же Zone ID терминологии Microsoft. На самом деле оно было и в IPv4, однако не было задано явно: сети 10/8, 172.16/12 и 192.168/16 яркие тому примеры.
В случае Unicast/Anycast адресов приминимо следующее:
У каждого IPv6 enabled интерфейса есть свой Link-local адрес. Его scope, внезапно, local. Эти адреса уникальны в пределах линка, но не обязаны быть актуальными в пределах одного хоста. Так, например, VLAN созданный на интерфейсе будет иметь такой же link-local адрес, что и родительский интерфейс (так как без использования IPv6 Privacy Extensions он будет генериться из тогоже Link Layer адреса). Для того, чтобы явно указать интерфейс которому принадлежит IPv6 адрес нужно или указывать в ручную интерфейс для исходящих пакетов или использовать специальный суффикс при записи адреса: %ИндексИнтерфейса в Windows (fe80::2b0:d0ff:fee9:4143%3) или %ИмяИнтерфейса в *BSD/Linux (fe80::2b0:d0ff:fee9:4143%em0).
В случае Multicast адресов scope указан в последних четырёх битах вторго октета IPv6 адреса: ff0s:: и может быть interface-local, link-local, admin-local, site-local, organization-local или же global.
Дополнительно стоит ознакомиться с RFC4007 IPv6 Scoped Address Architecture

Жизненный цикл IPv6 адреса
Возможны следующие state’ы IPv6 адреса на протяжении его жизненного цикла:
086f45b60d689ed6a45a0f8fdaacf658[1]
Tentative — Адрес ещё проверяется на уникальность;
Valid — Траффик на этот адрес будет получатся хостом, делится на 2 подсостояния:
Prefered state — Основное состояние, неограниченное использование адреса;
Deprecated state — Адрес ещё можно использовать для старых соединений, но нельзя создавать новые соединения;

Invalid — Адрес нельзя использовать для получения/отправки пакетов.

IPv6 Пакет
Заголовок IPv6 пакета
Значительные изменения в формате заголовка пакета
Фиксированный размер заголовка;
Отсутствует Checksum заголовка, соответственно, его не надо проверять, а также пересчитывать для каждого пакета при изменении TTL Hop Limit. Так как checksum больше нет, то вся ответственность за целостность информации должна лежать на протоколе более низкого уровня, так например у Ethernet фреймов есть свой честный CRC32. Так же у UDP пакетов наличие checksum теперь обязательно и UDP/IPv6 пакеты с Checksum 0000 будут просто отбрасываться принимающим хостом;
Сам TTL теперь именуется Hop Limit (скорее всего потому, что раньше одним из условий у роутера было уменьшать TTL на один каждую секунду прибывания пакета в очереди, поэтому и TIME-to-live). В связи с последним трендом с повсеместным введением MPLS/TE стоит заметить, что при прохождении IP-пакета через MPLS облако его TTL/HopLimit может не и меняется;
Роутеры теперь не занимаются фрагментацией пакетов. Хосты должны сами проводить Path MTU discovery и разбивать пакеты. Минимальный MTU теперь равен 1280.
Были добавлены Метки потоков, служат для разгрузки роутеров, более точной приоритезации трафика и балансировки. Более подробно можно почитать в RFC6437 — IPv6 Flow Label Specification. До сих пор ходят баталии об использовании этого поля IPv6 заголовка на практике. Эпик-треды можно почитать в RFC6294 — Survey of Proposed Use Cases for the IPv6 Flow Label, RFC6436 — Rationale for Update to the IPv6 Flow Label Specification и RFC6438 — Using the IPv6 Flow Label for Equal Cost Multipath Routing and Link Aggregation in Tunnels. Единственная операционная система(из протестированных нами) которая на выставляет по умолчению flow label’ы это FreeBSD;
Изначально(в obsoleted RFC1883) поле Traffic Class называлось Priority и занимало 4 бита, а flow label был 24 бита. В RFC2460 они стали 8 и 20 бит соответственно. Если кому интересна никрофилия можно почитать остальные Historical notes на вики;
Поддержка IPSec теперь является обязательной;

Extension Headers
Заголовок пакета теперь фиксированной длинны и заметно упрощённый, однако благодаря Extension Header’ам обеспечивается гибкость большая нежели у IPv4 Options, которые благодаря ограничению на размер в 40 байт были вообще не юзабельны. Подробно структура IPv6 пакета описана в RFC2460, тут я опишу лишь самое основное.
Каждый пакет содержит восьми битное поле называемое Next Header, в нём содержится идентификатор следующего заголовка. Extension Headers могут идти сразу после заголовка IPv6 (между заголовком и payload’ом IPv6 пакета) и включают в себя дополнительную информацию сетевого уровня. На данный момент имеются следующие типы Extension Header’ов:
Hop-by-Hop Options — любой роутер на пути следования пакета должен просматривать только IPv6 заголовок, все остальные заголовки предназначены эксклюзивно для получателя пакета. Однако Hop-By-Hop заголовок является исключением — его просматривают все роутеры и если он есть, то должен идти сразу за IPv6 заголовком.
Routing — RFC5095 отменяет Type 0 Routing Headers, которые содержат в своём определении DoS уязвимость (ещё серьёзнее нежели source routing в IPv4). Подробнее тема безопасности в IPv6 обсуждается в RFC4942 и в презентации Security Implications of IPv6.
Fragment — Заголовок фрагментированного пакета. Как я уже упоминал, роутеры больше не занимаются фрагментацией, так что отправитель сам должен позаботится об оптимальном размере пакета, иначе получит Packet too big от одного из роутеров на пути. Кстати, MTU для работы IPv6 не должен быть менее 1280.
Destination Options — Опции предназначенные только получателю.

Так же в имеются заголовки IPSec аунтефикации и шифрования:
Authentication — RFC4302
Encapsulating Security Payload — RFC4303

IPv6 Протоколы
ICMPv6
ICMP в IPv6 был заменён на ICMPv6. О ICMPv6 можно прочитать в RFC4443 Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification.
Сам по себе ICMPv6 довольно прост, однако на его основе сделано множество довольно не тривиальных протоколов, о которых мы поговорим чуть ниже.

MLD
ICMP в IPv6 был заменён на ICMPv6. О ICMPv6 можно прочитать в RFC4443 Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification.
Сам по себе ICMPv6 довольно прост, однако на его основе сделано множество довольно не тривиальных протоколов, о которых мы поговорим чуть ниже.

MLD
Multicast Listener Discovery — протокол на основе ICMPv6. Аналог IGMP для IPv6. Подробнее в RFC3810 — Multicast Listener Discovery Version 2 (MLDv2) for IPv6.

NDP
Описание Neighbor Discovery Protocol, заменившего протокол ARP, доступно в RFC4861. Теперь это не отдельный протокол, а надстройка над ICMPv6 добавляющая несколько новых типов сообщений.
Основное предназначение NDP — производить мапинг между link-layer и IPv6 адресами, однако это лишь небольшая часть функциональности.

Что ещё умеет NDP:
Neigbour Unreachability Detection, позволяющая определить доступность хоста одним из двух методов:
С помощью протокола более высокого уровня;
С помощью unicast solicitation, на который хост должен ответить Neighbor Advertisement сообщением;
Duplicate Address Detection
Отсылка и обработка redirect’ов
Определение пааметров линка (например MTU)
Определение сервисов в сети (например DNS: RFC6106 IPv6 Router Advertisement Options for DNS Configuration)
Stateless автоконфигурация (об этом чуть ниже)

Также есть криптографически защищённый аналог NDP — SEcure Neighbor Discovery (SEND) описаный в RFC3971. SEND, в свою очередь, использует Cryptographically Generated Address описанные рядом в RFC3972.

Автоконфигурация
Zeroconf

Как уже было упомянуто выше, хосты умеют автоматически генерировать себе IPv6 link-local адрес из адреса канального уровня. Так что без какой либо настройки любой IPv6-enabled хост подключённый к сети выдаёт сам себе адрес сетевого уровня.
В IPv4 эта технология использует зарезервированный IPv4 диапазон 169.254/16. Подробно технология описана в RFC3927 Dynamic Configuration of IPv4 Link-Local Addresses (Заметьте, что этот RFC вышел после IPv6’ого 2462).

Stateful

В IPv4 автоконфигурация возможна только с использованием DHCP сервера. В IPv6 эту возможность оставили: можно конфигурировать сеть с помощью DHCPv6 сервера и клиента. Однако, поддержка со стороны вендоров DHCPv6 пока не блещет, так например, dhclient во FreeBSD из коробки не умеет IPv6.

Stateless

Кроме stateful-конфигурации в IPv6 имеется также stateless автоконфигурация, которая позволяет хостам автоматически получать IPv6 адреса в сети без DHCP сервера через использование NDP. Роутеру достаточно задать префикс который он будет анонсировать через Router Advertisement всей остальной сети. Хосты будут получать RA и формровать на основе префикса и своего link-layer адреса IPv6 адрес.
Пара замечаний:
Stateless определение адреса возможно только при наличии роутера/ротеров рассылающего RA;
Каждый роутер имеет приоритет: high/medium/low. Операционная система должна его учитывать при выборе default route;
RFC6106 — IPv6 Router Advertisement Options for DNS Configuration объясняет как встраивать адреса DNS-серверов прямо в RA, что позволяет избавиться от использования DHCPv6 для этого дела. Однако это поддерживается не всеми вендорами;
Генерировать IPv6 адрес используя свой link-layer не очень безопасно с точки зрения privacy. Ваши перемещения по миру а иногда и модель оборудования будет доступна всему интернету. Решение проблемы было описано в RFC4941 — Privacy Extensions for Stateless Address Autoconfiguration in IPv6. Все современные операционные системы поддерживают Privacy Extensions;

Комбинированая

Могут использоваться одновременно оба вида автоконфигурации, например stateless для получения IPv6 префикса и stateful для получения адресов DNS-серверов и/или других параметров, которые нельзя передать с помощью Router Advertisement.

DNS
Этому моменту в документации по IPv6 уделено достаточно мало внимания, однако судя по количеству RFC на эту тему, изменения колоссальны.
Для полноценной поддержки IPv6 в DNS систему было введено множество изменений (RFC3152, RFC3226, RFC3363) и всё равно остаётся некоторое количество нерешённых проблем — RFC4472.
Некоторое время даже существовало два стандарта для описания IPv6 адресов в DNS: A6 и AAAA, плюсы и минусы каждого из них описаны в RFC3364. Если вкратце, то A6 предоставляет большую гибкость и меньшую зависимость зоны от префикса, а AAAA являются лишь частным случаем A6 с длинной префикса 0. A6 в последствии был переведён в статус Experimental в RFC3363 — Representing Internet Protocol version 6 (IPv6) Addresses in the Domain Name System (DNS)
Для минимальной поддержки IPv6 требуется только одна AAAA запись. Также может потребоваться наличие PTR записи. Обратные DNS записи для IPv6 выглядят ужасающе. Так, например, обратка для адреса 4321:0:1:2:3:4:567:89ab будет выглядеть как b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.IP6.ARPA.. Это зрелище не для слабонервных, однако, это скорее всего сподвигнет людей к автоматической генерации обраток. Для ручной генерации я бы рекомендовал sipcalc с ключом -r или что-либо аналогичное.

Прочее
Протоколы более высокого уровня
Часть протоколов, использующих адрес сетевого уровня в своей работе требовали внесения в них определённых изменением для того, чтобы начать работать по IPv6. Ярким примером такого протокола является FTP.

Тунелирование IPv6 трафика поверх IPv4 сетей
Тут совсем вскользь про некоторые возможные технологии:
Статические point-to-point MCT/GRE тунели;
6to4. Использует 2002::/16 диапазон. Есть ещё его разновидность для customer devices у которых с «той» стороны нет выделенного сервера для деинкапсуляции пакетов: они шлют инкапсулированые пакеты на anycast адрес 192.88.99.1 который анонсируется со множества 6to4 шлюзов с помощью протоколов динамической маршрутизации;
Teredo/Miredo. Работает не со всеми видами NAT’ов;
ISATAP — Intra-Site Automatic Tunnel Addressing Protocol. Обычно завязано на использовании DNS (Через резолв isatap.example.com);

Mobile IPv6
Про него не знаю нечего, так что просто оставлю это здесь: Mobile IP.

IPv6 адрес как хранилище информации
Согласитесь 128бит — это огромный простор для фантазии. Существует множество технологий которые пытаются использовать эти самые 128бит. От кодирования туда IPv4 адреса и криптографических сигнатур до определения растояний между нодами (тут кстати даже мы думали в этом направлении, но пока присмтриваемся к ALTO: Application-Layer Traffic Optimization (ALTO) Problem Statement).

Socket API
Хабратопик описывает IPv6 с точки зрения NOC / системного администратора, но не с точки зрения программиста. Если кому-то интересны особенности программирования под IPv6, то рекомендую обратиться к RFC3493 — Basic Socket Interface Extensions for IPv6 и книжке IPv6 Network Programming

Послесловие
Не смотря на все мои попытки всё структурировать статья получилась довольно сумбурной. Возможно это из-за её сугубо теоретической направленности, возможно из-за того что сам ещё не всё устаканил у себя в голове. В любом случае, я надеюсь, она будет служить хорошей памяткой и катологом ссылок по IPv6, как для меня, так и для всего хабрасообщества.
Однако, возможно, перед тем как зарываться с головой в RFC и tcpdump’ы можно сначала почитать книжки, например, IPv6 Essentials от O’Reilly должна сильно помочь усвоению материала описанного в этой статье.