Как IPv6 помогает роутеры ломать
Предисловие
Проснулся я сегодня с мыслью, что огромное количество инструкций по настройке NAT советуют использовать строку вида:
Многие понимают проблемы этой конструкции, и советуют добавлять:
Но, зачастую, забывают задать таблице FORWARD действие DROP по умолчанию, или добавить правило REJECT в конец таблицы.
На первый взгляд, вроде бы, все кажется нормальным. Однако, это далеко не так. Дело в том, что если не запретить маршрутизировать трафик из WAN-порта в WAN-порт, кто-нибудь из вашей WAN-сети (предположим, что провайдер садит весь подъезд в одну /24) может маршрутизировать трафик через вас, просто прописав ваш IP в качестве шлюза. Все современные SOHO роутеры это учитывают, а вот неопытный администратор, который делает роутер под обычным linux, может не знать или забыть об этом. В подсети моего провайдера таких роутеров не оказалось, и мой план по захвату мира провалился. Однако, статья совсем не об этом.
Магические двоеточия
Но это нужно далеко не всегда, т.к. обычно удобно, что программа слушает один сокет, а получать соединения может по двум протоколам сразу. Практически во всех дистрибутивах, IPv6-сокеты ведут себя именно так, т.е. bindv6only=0.
fe80 и его друг ff02
Если вы не застряли в 90-х, вы гарантированно сталкивались с IPv6, сами того не зная. Абсолютно во всех современных операционных системах по умолчанию включена поддержка IPv6, а это значит, что на каждый (кроме редких исключений) интерфейс автоматически назначается IPv6 Link-Local адрес, который начинается с fe80::. Более того, в некоторых случаях этот адрес получается просто путем кодирования MAC-адреса.
Казалось бы, найти Link-Local адреса должно быть проблематично, они же все-таки длинные и страшные, но тут нам на помощь приходит мультикаст-диапазон ff02::.
Есть такой классный адрес: ff02::1. Если его попинговать (обязательно с указанием интерфейса, т.к. это Link Local адрес), то откликнутся все компьютеры в сети:
Как мы видим, откликнулось 11 устройств. Кстати, этот адрес очень удобно использовать, если у вас, например, сервер настроен на получение адреса через DHCP, а DHCP упал, или если вы напрямую подключились к порту сервера, а DHCP поднимать не хочется. Вам остается просто зайти по fe80-адресу по ssh.
Если попинговать адрес ff02::2, то откликнутся все IPv6-роутеры в сети. К сожалению, в моем случае таких не было.
Сканируем роутеры
По IPv4 все эти порты закрыты.
Как мы видим, у многих роутеров открыт Telnet, веб-интерфейс и DNS извне по IPv6.
Что же это значит? Все просто — разработчики прошивки роутера просто-напросто забыли про IPv6.
На многих из них были стандартные пароли admin/admin.
На большинстве этих роутеров ip6tables (iptables для IPv6) просто отсутствовал. Разработчики должны были либо вообще отключить поддержку IPv6 в ядре, либо убедиться, что http и telnet демоны слушают 0.0.0.0, а не :: но, по какой-то причине не стали этого делать.
А что, если…?
Если бы на роутере был каким-то образом настроен IPv6, и, соответственно, включена маршрутизация IPv6 пакетов (net.ipv6.conf.all.forwarding=1), а ip6tables либо вообще не настроен, либо настроен неправильно, то можно было бы точно так же, как в случае с IPv4, маршрутизировать пакеты через этот роутер.
Заключение
Некоторым компаниям я уже отправил письма об этих уязвимостях, а некоторым еще не успел. В любом случае, письма будут отправлены всем.
Используйте IPv6, не забывайте о нем.
Ff02 2 что за адрес
Если вы считаете, что её стоило бы доработать как можно быстрее, пожалуйста, скажите об этом.
IPv6 — протокол сетевого уровня, который постепенно приходит на смену IPv4, основному протоколу сетевого уровня в Интернете в настоящий момент.
Содержание
[править] Адресация в IPv6
[править] Типы адресов
На интерфейсе IPv6:
[править] Unicast адреса
[править] Unspecified
[править] Link local
[править] Global Unicast
[править] Anycast адреса
IPv6 определяет новый тип адреса, называемых anycast. Anycast адрес определяет список узлов или устройств. Пакет, посланный к такому адресу, доставляется на ближайший интерфейс. Anycast адреса синтаксически неотличимы от адресов Global unicast, потому что Anycast адреса выделяются из адресного пространства Global unicast.
[править] Multicast адреса
Multicast адреса идентифицируют группу интерфейсов, которые обычно принадлежат различным устройствам. Пакет, отправленный на такой адрес, будет доставлен всем интерфейсам в группе. Интерфейс может принадлежать любому количеству multicast групп.
Multicast адреса не должны использоваться как адрес отправителя в пакетах IPv6.
Маршрутизаторы не должны передавать любой multicast пакет за границы, указанные в поле scop в multicast адресе получателя.
Хосты не должны отправлять пакеты с multicast адресом с полем scop равным 0. Если такой пакет получен, то он должен быть отброшен (без оповещений).
[править] Формат multicast адреса
У multicast адреса такой формат:
[править] Предопределенные multicast адреса
Multicast адреса описанные в этом разделе предопределены (RFC4291). Идентификаторы группы (group ID) этих адресов определены для конкретных границ распространения адресов.
Использование перечисленных идентификаторов групп с другими значениями границ распространения, с флагом T=0, не разрешено.
[править] Зарезервированные
Зарезервированные multicast адреса — перечисленные адреса зарезервированы и не должны использоваться в качестве адреса какой-либо multicast группы
FF00:0:0:0:0:0:0:0 FF01:0:0:0:0:0:0:0 FF02:0:0:0:0:0:0:0 FF03:0:0:0:0:0:0:0 FF04:0:0:0:0:0:0:0 FF05:0:0:0:0:0:0:0 FF06:0:0:0:0:0:0:0 FF07:0:0:0:0:0:0:0 FF08:0:0:0:0:0:0:0 FF09:0:0:0:0:0:0:0 FF0A:0:0:0:0:0:0:0 FF0B:0:0:0:0:0:0:0 FF0C:0:0:0:0:0:0:0 FF0D:0:0:0:0:0:0:0 FF0E:0:0:0:0:0:0:0 FF0F:0:0:0:0:0:0:0
[править] All Nodes
All Nodes адреса — идентифицируют группу всех IPv6 хостов, с границей 1 (interface-local) или 2 (link-local):
[править] All Routers
All Routers адреса — идентифицируют группу всех IPv6 маршрутизаторов, с границей 1 (interface-local), 2 (link-local) или 5 (site-local):
FF01:0:0:0:0:0:0:2 FF02:0:0:0:0:0:0:2 FF05:0:0:0:0:0:0:2
[править] Solicited-node multicast
Solicited-node multicast адрес вычисляется из unicast и anycast адресов хоста. У всех адресов одинаковый префикс FF02::1:FF00:0/104. К указанному префиксу добавляются 24 low-order бита адреса (unicast или anycast), в результате solicited-node multicast адрес может быть в диапазоне от FF02:0:0:0:0:1:FF00:0000 до FF02:0:0:0:0:1:FFFF:FFFF.
Хост должен вычислить и присоединиться (на соответствующем интерфейсе) ко всем solicited-node multicast адресам, полученных из всех unicast и anycast адресов, которые настроены на интерфейсах хоста (вручную или автоматически).
Solicited-node multicast адреса используются протоколом обнаружения соседей — Neighbor Discovery (ND или NDP).
[править] Обязательные адреса
[править] Обязательные адреса для хоста
Хост должен распознавать следующие адреса, как адреса которые его идентифицируют:
[править] Обязательные адреса для маршрутизатора
Маршрутизатор должен распознавать все адреса, которые должен распознавать хост, плюс следующие, как адреса которые его идентифицируют:
[править] Специальные адреса
Некоторые адреса (например, перечисленные в rfc5156 и списке IANA) имеют специальное назначение и их применение должно быть обосновано.
[править] Протокол обнаружения соседей (Neighbor Discovery)
Протокол обнаружения соседей (Neighbor Discovery, ND) — протокол, с помощью которого IPv6 хосты разделяющие линк могут обнаружить друг друга, определить адрес канального уровня другого хоста (вместо ARP, который использовался в IPv4), обнаружить маршрутизаторы, поддерживать информацию о доступности путей к другим активным соседям.
[править] Задачи протокола
Протокол ND описан в RFC2461. Этот протокол решает ряд проблем относящихся к взаимодействию между хостами разделяющими линк. Он определяет механизмы для решения каждой из перечисленных задач:
[править] Типы сообщений
Neighbor Discovery определяет пять разных типов ICMP пакетов:
[править] DNS и IPv6
С 6 февраля 2008 года некоторые (6 из 13) корневые серверы DNS стали доступны по IPv6.
IPv6 на коммутаторах доступа SNR
Введение
Сегодня мы решили затронуть тему настройки IPv6 на коммутаторах доступа SNR. Не станем писать банальностей, вроде «IPv4-адреса заканчиваются», но вспомним Республику Беларусь, где уже около года действует закон об обязательном предоставлении абонентам IPv6-адресов. Обратимся к статистике Google, которая фиксирует рост доли IPv6 в мировом сетевом трафике с 5,5% в январе 2015 до 32% в октябре 2020. Согласитесь, не взрывной, но уверенный рост. Предоставление IPv6-адресов также может стать конкурентным преимуществом для операторов связи, это можно использовать в целях маркетинга.
Статистика Google по использованию IPv6 в мировом сетевом трафике
Краткий обзор IPv6
Ключевые отличия от IPv4
Заголовок IPv6
Сравним заголовки IPv4 и IPv6-пакетов, используя картинки прямо из RFC:
Заголовок пакета IPv4
Заголовок пакета IPv6
Можно заметить, что в новой версии протокола заголовок заметно упростился за счет использования меньшего количества полей. Разработчики посчитали, что на современном оборудовании часть из них просто не нужна. Например, нет смысла считать контрольную сумму, если это уже сделано на канальном уровне и будет сделано на транспортном. Т.к. IPv6-заголовок имеет фиксированную длину 40 байт, то и в поле IHL (Internet Header Length) больше нет смысла и т.д. Добавлено совершенно новое поле ‘IPv6 Flow Label’, служащее для упрощения маршрутизации пакетов одного потока (RFC 6437).
Neighbor Discovery Protocol вместо ARP
В IPv6 произошел полный отказ от протокола ARP, его функции взял на себя NDP. Он, в свою очередь, является частью протокола ICMPv6. Для определения MAC-адреса хоста протокол ARP использует ARP-Request и ARP-Reply сообщения, рассылаемые бродкастом. Подобным образом действует NDP через Neighbor Solicitation (NS) и Neighbor Advertisement сообщения, но делает это мультикастом. Давайте рассмотрим этот процесс подробнее в анализаторе трафика Wireshark:
Типы IPv6 адресов
Рассмотрим подробнее Link-Local Unicast Address. Такие адреса всегда начинаются на fe80, остальная часть генерируется автоматически, обычно на основе MAC-адреса. Должны быть уникальными только в пределах одной канальной среды, т.к. не маршрутизируются. Любой IPv6-хост в сети обязан иметь Link-Local Unicast адрес. Используется для обмена некоторыми типами сообщений в таких протоколах, как ICMPv6, DHCPv6, OSPFv3 и т.д. Является next-hop адресом для протоколов динамической маршрутизации и используется для указания шлюза по умолчанию для хостов.
Методы динамической конфигурации IPv6-адреса
SLAAC. Получая RA-сообщение с активным A-флагом, клиент сам формирует себе IPv6-адрес. Первые 64 бита берутся из поля «Prefix information» остальные формируются либо методом EUI-64, либо случайным образом. Заметьте, что DHCPv6-сервер тут вообще не используется.
Stateless DHCPv6. Минус метода SLAAC в том, что мы имеем только свой IPv6-адрес и адрес шлюза по умолчанию. Но если мы хотим автоматически получать и информацию о DNS серверах и другую информацию? Тогда в RA-сообщениях, помимо A-флага, также будет активным O-флаг. Получая такое сообщение хост также будет формировать свой IPv6-адрес сам, но еще обратится по специальному мультикастовому адресу ff02:1:2 к ближайшему DHCPv6-серверу за дополнительными реквизитами.
Stateful DHCPv6. Это, по-сути, классический метод получения IPv6-адреса динамическим способом, к которому мы привыкли в IPv4. Сервер выделяет адреса из пулов, может ориентироваться при этом на опции 18 (interface-id), 37 (remote-id) и 38 (subscriber-id). Чтобы использовать Stateful DHCPv6, мы должны анонсировать в RA-сообщениях только M-флаг.
Prefix Delegation. При данном методе мы имеем дело с двумя маршрутизаторами. Абонентский (CPE) является запрашивающим и отправляет DHCPv6 Solicit-сообщение делегирующему. Последний отправляет ответ в виде делегированного префикса. Обычно его длина /56, это является рекомендацией RFC 6177. CPE сам добавляет к префиксу недостающие 8 бит и в Advertise-сообщении анонсирует стандартный /64 префикс. Рассмотрим этот процесс в Wireshark. Запрашивающий маршрутизатор отправляет делегирующему DHCPv6 Solicit-сообщение с опцией 25, которая сигнализирует о желании использовать Prefix Delegation. Сервер отвечает Advertise-сообщением с опцией 26, где содержится делегируемый префикс с его длиной. При этом CPE, в зависимости от настроек, анонсирует либо A, либо A+O флаги. Следовательно, клиент генерирует себе IPv6-адрес сам, на основе префикса.
Основные настройки IPv6 на коммутаторах SNR
Разобравшись с теорией, можно переходить к практике. Рассмотрим базовые настройки IPv6 на коммутаторах доступа SNR.
Хочется отметить, что все управляемые коммутаторы SNR, от FastEthernet моделей, таких как SNR-S2985G-24TC, до гигабитных коммутаторов с 10Г аплинками ( SNR-S2989G-24TX), поддерживают одинаковый функционал и имеют одинаковые настройки в части IPv6.
Назначить IPv6-адрес управления
Назначить адрес L3-интерфейсу можно несколькими методами. Полностью указать его с длиной префикса, использовать метод EUI-64 или использовать DHCPv6-клиент. Последний способ требует предварительно внесения в конфигурацию строки ‘service dhcpv6’. Рассмотрим все три способа на трех VLAN-интерфейсах:
Switch(config)#service dhcpv6
Switch(config)#int vlan1
Switch(config-if-vlan1)#ipv6 address 2001:db8:100:1::1/64
Switch(config-if-vlan1)#int vlan2
Switch(config-if-vlan2)#ipv6 address 2001:db8:100:2::/64 eui-64
Switch(config-if-vlan1)#int vlan3
Switch(config-if-vlan2)#ipv6 dhcp-client enable
Switch#sh ipv6 interface brief
Vlan1 [up]
2001:db8:100:1::1/64
fe80::faf0:82ff:fe78:5ba/64
Vlan2 [up]
2001:db8:100:2:faf0:82ff:fe78:5ba/64
fe80::faf0:82ff:fe78:5ba/64
Vlan3 [up]
2001:db8:100:3::100/64
fe80::faf0:82ff:fe78:5ba/64
Loopback [up]
::1/128
Задать статическую IPv6 neighbor-запись
Полностью аналогично статической ARP-записи и производится из-под VLAN-интерфейса.
Switch(config)#int vlan1
Switch(config-if-vlan1)#ipv6 neighbor 2001:db8:100:1::10 f0-de-f1-19-d5-eb interface e1/0/2
Switch#sh ipv6 neighbors
IPv6 neighbour unicast items: 4, valid: 3, matched: 3, incomplete: 0, delayed: 0, manage items: 0
IPv6 Address Hardware Addr Interface Port State Age-time(sec)
2001:db8:100:1::3 38-63-bb-71-d3-00 Vlan1 Ethernet1/0/8 reachable 1168
2001:db8:100:1::10 f0-de-f1-19-d5-eb Vlan1 Ethernet1/0/2 permanent
fe80::f1ed:8839:4a8:13fc 38-63-bb-71-d3-00 Vlan1 Ethernet1/0/8 reachable 1192
Настроить DHCPv6 Relay
Switch(config)#service dhcpv6
Switch(config)#int vlan10
Switch(config-if-vlan10)#ipv6 dhcp relay destination 2001:db8:100:1::1
Security RA и его использование
Если RA-сообщения будет посылать IPv6-хост злоумышленника, то может выйти так, что клиентский ПК будет использовать его link-local адрес, как шлюз по умолчанию. Также злоумышленник может анонсировать неверный IPv6-префикс и его длину. Защититься от этого поможет функционал Security RA. Включим настройку глобально и запретим на абонентских портах RA-сообщения:
Switch(config)#ipv6 security-ra enable
Switch(config)#int e1/0/1-24
Switch(config-if-port-range)#ipv6 security-ra enable
Такие сообщения теперь могут приходить только с аплинков e1/0/25-28. Проверим конфигурацию Security RA:
Switch#sh ipv6 security-ra
IPv6 security RA information:
Global IPv6 Security RA State: enabled
Ethernet1/0/1
IPv6 Security RA State: Yes
Ethernet1/0/2
IPv6 Security RA State: Yes
.
Важно отметить, что механизмы защиты Security RA и SAVI являются взаимоисключающими.
SAVI и DHCPv6 Snooping
SAVI (Source Address Validation Improvement) включает в себя ND Snooping, DHCPv6 Snooping и RA Snooping. Он позволяет защищаться от нелегитимных DHCPv6-серверов и источников RA-сообщений с помощью знакомых нам доверенных портов. Выдаваемые IPv6-адреса и префиксы, привязываются к MAC-адресам и портам в биндинг-таблице. Мы также можем ограничить максимальное количество адресов на порт. Присутствует возможность создавать статические SAVI-записи, с указанием IP-адреса, MAC-адреса и номера интерфейса.
Прежде, чем использовать IPv6-адрес, устройство должно задействовать механизм Duplicate Address Detection (DAD). На специальный мультикастовый адрес посылается ICMPv6-NS сообщение с проверкой, не занят ли кем-то еще в сети этот адрес. Если никто не ответил положительно, то адрес свободен. Настройка savi ipv6 имеет три опции и работает с DAD-NS и DHCPv6-сообщениями. ‘DHCP-ONLY’ отслеживает DHCPv6-пакеты, а DAD NS-пакеты только с link-local адресом. ‘SLAAC-ONLY’ отслеживает DAD NS-пакеты со всеми типами адресов. DHCP-SLAAC отслеживает все DHCPv6 и DAD NS-пакеты.
Настройка savi check binding имеет два режима. Simple mode удаляет записи из таблицы, когда порт находится в состоянии DOWN, а время аренды IPv6-адреса истекло. Probe mode дополнительно посылает NS-пакет перед этим для дополнительной проверки состояния клиента. Если NA-пакет не получен в ответ, запись удаляется.
Включим SAVI, аналог IPv6 source guard, на порту e1/0/3 и ограничим максимальное количество привязанных IPv6-адресов на нем 10 штуками. Заносить в биндинг таблицу будем как адреса сформированные dhcp-методом, так и slaac. Порт e1/0/25 назначим доверенным для DHCPv6 и RA-сообщений.
Switch(config)#savi enable
Switch(config)#savi ipv6 dhcp-slaac enable
Switch(config)#savi check binding probe mode
Switch(config)#ipv6 dhcp snooping vlan 10
Switch(config)#int e1/0/3
Switch(config-if-ethernet1/0/3)#switchport access vlan 10
Switch(config-if-ethernet1/0/3)#savi ipv6 check source ip-address mac-address
Switch(config-if-ethernet1/0/3)#savi ipv6 binding num 10
Switch(config)#int e1/0/25
Switch(config-if-ethernet1/0/25)#switchport mode trunk
Switch(config-if-ethernet1/0/25)#ipv6 nd snooping trust
Switch(config-if-ethernet1/0/25)#ipv6 dhcp snooping trust
Switch#sh savi ipv6 check source binding
Static binding count: 0
Dynamic binding count: 4
Binding count: 4
CPS (Control Packet Snooping)
CPS работает совместно с SAVI и анализирует IPv6-пакеты на предмет префикса. Если он не соответствует тому, что задан в CPS, выдаваемый DHCPv6-сервером адрес не попадет в SAVI биндинг-таблицу. Рассмотрим порядок его настройки. Пропишем разрешенный префикс для global-unicast адреса, а затем префикс fe80::/64 под который будут подпадать все link-local адреса:
Switch(config)#ipv6 cps prefix 2001:db8:100:1::/64 vlan 100
Switch(config)#ipv6 cps prefix fe80::/64 vlan 100
Switch(config)#ipv6 cps prefix check enable
Теперь если DHCPv6-сервер во VLAN 100 отдаст на DHCP-SOLICIT-запрос адрес с отличным от 2001:db8:100:1::/64 префиксом, такой адрес не попадет в SAVI биндинг-таблицу.
ND Security
ND Security позволяет влиять на автоматическое изучение neighbor-записей и контролировать их, является полным аналогом ARP Security. Три рассматриваемые далее команды можно применять как глобально, так и из-под VLAN-интерфейса. Тогда они будут применяться только в этом VLAN. Рассмотрим пример использования ND Security. На данный момент имеем в neighbor-таблице две записи, связанные с тестовым ПК1.
Switch#sh ipv6 neighbors
IPv6 neighbour unicast items: 3, valid: 2, matched: 2, incomplete: 0, delayed: 0, manage items: 0
IPv6 Address Hardware Addr Interface Port State Age-time(sec)
2001:db8:100:1::3 38-63-bb-71-d3-00 Vlan1 Ethernet1/0/1 reachable 1136
fe80::f1ed:8839:4a8:13fc 38-63-bb-71-d3-00 Vlan1 Ethernet1/0/1 reachable 1150
IPv6 neighbour table: 2 entries
Теперь рассмотрим команду ‘ipv6 nd-security updateprotect’. Как понятно из названия, она блокирует обновление MAC-адресов в neighbor-записях. Если после ее применения изменить MAC-адрес на тестовом ПК, то его запись в neighbor-таблице не обновится.
На данный момент обе записи в таблице динамические. Сконвертируем их в статические командой ‘ipv6 nd-security convert’. Записи стали статическими и попали в конфигурацию:
Switch(config)#ipv6 nd-security convert
Switch(config)#sh ipv6 neighbors
IPv6 neighbour unicast items: 3, valid: 2, matched: 2, incomplete: 0, delayed: 0, manage items: 0
IPv6 Address Hardware Addr Interface Port State Age-time(sec)
2001:db8:100:1::3 38-63-bb-71-d3-00 Vlan1 Ethernet1/0/1 permanent
fe80::f1ed:8839:4a8:13fc 38-63-bb-71-d3-00 Vlan1 Ethernet1/0/1 permanent
IPv6 neighbour table: 2 entries
Switch(config)#sh run int vlan1
!
interface Vlan1
ipv6 address 2001:db8:100:1::1/64
ipv6 neighbor fe80::f2de:f1ff:fe19:d5eb f0-de-f1-19-d5-eb interface Ethernet1/0/2
ipv6 neighbor 2001:db8:100:1::4 f0-de-f1-19-d5-eb interface Ethernet1/0/2
!
Наконец, запретим автоматическое изучение новых neighbor-записей командой ipv6 nd-security learnprotect‘. ’
Заключение
Практика IPv6 — домашняя сеть
Abstract: Рассказ про некоторые возможности IPv6 на примере конфигурации сложной домашней IPv6-сети. Включает в себя описания мультикаста, подробности настройки и отладки router advertisement, stateless DHCP и т.д. Описано для linux-системы. Помимо самой конфигурации мы внимательно обсудим некоторые понятия IPv6 в теоретическом плане, а так же некоторые приёмы при работе с IPv6.
Зачем IPv6?
Вполне понятный вопрос: почему я ношусь с IPv6 сейчас, когда от него сейчас нет практически никакой пользы?
Сейчас с IPv6 можно возиться совершенно безопасно, без каких-либо негативных последствий. Можно мирно разбираться в граблях и особенностях, иметь его неработающим месяцами и nobody cares. Я не планирую в свои старшие годы становиться зашоренным коболистом-консерватором, который всю жизнь писал кобол и больше ничего, и все новинки для него «чушь и ерунда». А вот мой досточтимый воображаемый конкурент, когда IPv6 станет продакт-реальностью, будет либо мне не конкурентом, либо мучительно и в состоянии дистресса разбираться с DAD, RA, temporary dynamic addresses и прочими странными вещами, которым посвящено 30+ RFC. А что IPv6 станет основным протоколом ещё при моей жизни — это очевидно, так как альтернатив нет (даже если бы они были, их внедрение — это количество усилий бОльшее, чем завершение внедрения IPv6, то есть любая альтернатива всегда будет отставать). И что адреса таки заканчиваются видно, по тому, как процесс управления ими перешёл во вторую стадию — стадию вторичного рынка. Когда свободные резервы спекуляций и хомячаяния адресов закончится, начнётся этап суровой консолидации — то есть выкидывание всего неважного с адресов, перенос всех «на один адрес» и т.д. Примерно в это время IPv6 начнёт использоваться для реальной работы.
Впрочем, рассказ не про будущее IPv6, а про практику работы с ним. В Санкт-Петербурге есть такой провайдер — Tierа. И я их домашний пользователь. Это один из немногих провайдеров, или, может быть, единственный в городе, кто предоставляет IPv6 домашним пользователям. Пользователю выделяется один IPv6 адрес (для маршрутизатора или компьютера), плюс /64 сетка для всего остального (то есть в четыре миллиарда раз больше адресов, чем всего IPv4 адресов быть может — и всё это в одни руки). Я попробую не просто описать «как настроить IPv6», но разобрать базовые понятия протокола на практических примерах с теоретическими вставками.
У провайдера сеть 2a00:11d8:1201:32b0::/64 маршрутизируется через 2a00:11d8:1201:0:962b:18:e716:fb97 (то есть через мой компьютер). Заметим, это всё, что я получил. Никаких шлюзов и т.д. — тут начинается магия IPv6, и самое интересное. «Оно работает само».
Начнём с простого: настройка 2a00:11d8:1201:0:962b:18:e716:fb97 на eth2 для компьютера. Для удобства чтения все конфиги и имена файлов я оставлю на последнюю секцию.
Мы прописываем ipv6 адрес на интерфейсе eth2… И чудо, он начинает работать. Почему? Каким образом компьютер узнал, куда надо слать пакеты дальше? И почему /128 является валидной сетью для ipv6? Ведь /128 означает сеть размером в 1 ip-адрес и не более. Там не может быть шлюза!
Для того, чтобы понять, что происходит, нам надо взглянуть на конфигурацию сети (я вырежу всё лишнее, чтобы не пугать выводом):
# ip address show eth2 (обычно сокращают до ip a s eth2 )
Упс. А почему у нас на интерфейсе два адреса? Мы же прописывали один? Наш адрес называется ‘scope global’, но есть ещё и ‘scope link’…
Часть первая: scope
В процессе проектирования IPv6 вопрос ‘scope’ много и тщательно обсуждался, потому что исходное деление IPv4, даже с последующими дополнениями, явно не соответствовало потребностям реальных конфигураций. Например, если у вас объединяются две организации, в каждой из которых используется сеть 10.0.0.0/8, то вас ждёт множество «приятных» сюрпризов. В IPv6 решили с самого начала сделать множество градаций видимости, что позволило бы более комфортно осуществлять дальнейшие манипуляции.
Из всего этого на практике я видел использование только host/interface, link/local и global. В свете /64 и пусть никто не уйдёт обиженным, специально возиться с site-local адресами будет только параноик.
Второй важной особенностью IPv6 является официальное (на всех уровнях спецификаций) признание того, что у интерфейса может быть несколько IP-адресов. Этот вопрос в IPv4 был крайне запутан и часто приводил к ужасным последствиям (например, запрос получали на один интерфейс, а отвечали на него через другой, но с адресом первого интерфейса).
Так как в отличие от IPv4 у IPv6 может быть несколько адресов на интефрейсе, то компьютеру не нужно выбирать «какой адрес взять». Он может брать несколько адресов. В случае IPv4 сваливание на link-local адрес происходило в режиме «последней надежды», то есть по большому таймауту.
А в IPv6 мы можем легко и просто с самого первого момента, как интерфейс поднялся, сделать ему link local (и уже после этого думать о том, какие там global адреса есть).
Более того, в IPv6 есть специальная технология автоматической генерации link-local адреса, которая гарантирует отсутствие дублей. Она использует MAC-адрес компьютера для генерации второй (младшей) половинки адреса. Поскольку MAC-адреса уникальны хотя бы в пределах сегмента (иначе L2 сломан и всё прочее автоматически не работает), то использование MAC-адреса даёт нам 100% уверенность в том, что наш IPv6 адрес уникален.
Принцип довольно простой:
MAC-адрес eth2 — это 00:18:e7:16:fb:97, а локальный адрес ipv6 — F80:000218:e7ff:fe16:fb97. Да-да, именно так, как выделено жирным. Зачем было в середину всобачивать ff:fe — не знаю. Сам алгоритм называется modified EUI-64. Сам этот алгоритм очень мотивирован и полон деталей. С позиции системного администратора — пофигу. Адрес есть и есть. Интересным может быть, наверное, обратный алгоритм — из link-local узнать MAC и не более.
Итак, у нас на интерфейсе два адреса. Мы даже знаем, как появились они оба (один автоматически при подъёме интерфейса, второй прописали мы). Мы даже знаем, как система поняла, что адрес глобальный — он из «global» диапазона.
Но каким образом система узнала про то, кто его шлюз по умолчанию? И как вообще может жить /128?
Часть вторая, промежуточная: мультикасту мультикаст мультикастно мультикастит
Посмотрим на таблицу маршрутизации:
Что мы тут видим? Первое — говорит нам, что наш IPv6 адрес — это адрес нашего интерфейса eth2. Второе говорит, что у нас есть link-local сегмент в eth2. У обоих источник — это kernel.
А вот третье — это интрига. Это шлюз по умолчанию, который говорит, что весь трафик надо отправлять на fe80::768e:f8ff:fe93:21f0 на интерфейсе eth2, и источником информации о нём является некое «ra», а ещё сказано, что оно протухает через 1779 секунд.
Что? Где? Куда? Кто? За что? Почему? Зачем? Кто виноват?
Но перед ответом на эти вопросы нам придётся познакомиться с ещё одной важной вещью — multicast. В IPv4 muticast был этакой технологией «не от мира сего». Есть, но редко используется в строго ограниченных случаях. В IPv6 эта технология — центральная часть всего и вся. IPv6 не сможет работать без мультикаста. И без понимания этого многие вещи в IPv6 будут казаться странными или ломаться в неожиданных местах.
Кратко о типах трафика, возможно кто-то пропустил эту информацию, когда изучал IPv4:
Так вот, в IPv6 НЕТ БРОДКАСТОВ. Вообще. Вместо них есть мультикаст. И некоторые из мультикаст-адресов являются ключевыми для работы IPv6.
В практическом смысле это означает, что мы можем отправить бродкаст пинг всем узлам, или всем маршрутизаторам. Правда, нам для этого придётся указать имя интерфейса, в отношении которого мы интересуемся cоседями.
Мультикаст-групп (группой называют все узлы, которые слушают данный мультикаст-адрес) много. Среди них — специальная группа FF02::6A с названием «All-Snoopers». Именно этой группе и рассылаются routing advertisements. Когда мы хотим их получать — мы вступаем в соответствующую группу. Точнее не мы, а наш компьютер.
Часть третья: routing advertisements
В IPv6 придумали такую замечательную вещь — когда маршрутизатор рассылает всем желающим информацию о том, что он маршрутизатор. Рассылает периодически.
В отношении этого вопроса есть целый (всего один, что удивительно) RFC: tools.ietf.org/html/rfc4286, но нас интересует из всего этого простая вещь: маршрутизатор рассылает информацию о том, что он маршрутизатор. И, может быть, чуть-чуть ещё информации о том, что в сети происходит.
Вот откуда наш компьютер узнал маршрут. Некий маршрутизатор сказал ему «я маршрутизатор». И мы ему поверили. Почему мы выбрали именно его среди всех окружающих маршруштизаторов (см ответ на пинг на FF02::2 выше) мы обсудим чуть дальше. Пока что скажем, что этот «настоящий» маршрутизатор правильно себя анонсировал.
Таким образом, происходит следующая вещь:
У нас адрес 2a00:11d8:1201:0:962b:18:e716:fb97/128, и ещё есть link-local. Мы слышим мультикаст от роутера, верим ему, и добавляем в таблицу маршрутизации нужный нам адрес как default. С этого момента мы точно знаем, что адрес в сети. Таким образом, отправка трафика в интернет больше не проблема. Мы генерируем пакет с src=2a00:11d8:1201:0:962b:18:e716:fb97 и отправляем его на шлюз по умолчанию, который в нашем случае — fe80::768e:f8ff:fe93:21f0. Другими словами, мы отправляем трафик не своему «шлюзу» в сети, а совсем другому узлу совсем по другому маршруту. Вполне нормальная вещь как для IPv6, так и для IPv4, правда, для IPv4 это некая супер-крутая конфигурация, а для IPv6 — часть бытовой повседневности.
Въедливый читатель может спросить несколько вопросов: что значит «написано на интерфейсе»? И что значит «neighbor discovery»?
Вопросы справедливые. Для начала попробуем выяснить, какие узлы у нас есть в сети из подсети 2a00:11d8:1201::/64
Для того, чтобы посмотреть router advertisement на интерфейсе нам поднадобится программа radvdump из пакета radvd. Она позволяет печатать анонсы, проходящие на интерфейсах, в человеческом виде. Заметим, сам пакет radvd нам ещё пригодится (так как его демон — radvd позволяет настроить анонсирование со своих интерфейсах).
Итак, посмотрим, что аносирует нам Tiera:
radvdump eth2 (и подождать прилично, ибо анонсы не очень часто рассылаются)
Таким образом всё просто — адрес мы указали, маршрутизатор нам «себя» прислал, ядро маршрут обновило. Вуаля, у нас IPv6 на компьютере заработал.
Белый IPv6-адрес для каждого в домашней сети
Получить IPv6 адрес для компьютера — этого маловато будет. Хочется так, чтобы каждое мобильное устройство сидело не за позорным NAT’ом, а голой задницей с белым адресом в Интернете. Желательно ещё при этом так, чтобы злые NSA/google не могли по хвостику моего адреса (в котором закодирован MAC) отслеживать мои перемещения между разными IPv6-сетями (хотя в условиях установленного play services эта параноидальность выглядит наивной и беззащитной).
Но, в любом случае, у нас задача раздать интернет дальше.
Так как fb97 уже является адресом моего компьютера, настройка машрутизации плёвое дело:
… и у нас через пол-часика полностью отваливается IPv6 на компьютере? Почему? Кто виноват?
Оказывается, линукс не слушает routing advertisement, если сам является маршрутизатором. Что, в общем случае, правильно, потому что если два маршрутизатора будут объявлять себя маршрутизаторами и слушать маршруты друг друга, то мы быстро получим простейшую петлю из двух зацикленных друг на друга железных болванов.
Однако, в нашем случае мы всё-таки хотим слушать RA. Для этого нам надо включить RA силком.
Заметим, важно, что мы слушаем RA не всюду, а только на одном интерфейсе, с которого ожидаем анонсы.
Теперь маршрутизация работает, маршрут получается автоматически, и можно на каждом мобильном устройстве вручную прописать IPv6 адрес и вручную указать IPv6 шлюз, и вручную прописать IPv6 DNS, и вручную… э… слишком много вручную.
Если мне выдали настройки автоматом, то я так же хочу раздавать их дальше автоматом. Благо, dhcpd отлично справляется с аналогичной задачей для IPv4.
Прелесть IPv6 в том, что мы можем решить эту задачу (раздачу сетевых настроек) без каких-либо специальных сервисов и в так называемом stateless режиме. Главная особенность stateless режима состоит в том, что никто не должен напрягаться и что-то сохранять, помнить и т.д. Проблемы с DHCP в IPv4 чаще всего вызывались тем, что один и тот же адрес выдавали двум разным устройствам. А происходило это из-за того, что злой админ стирал/забывал базу данных уже выданных аренд. А ещё, если железок много и они забывают «отдать аренду», то адреса заканчиваются. Другими словами, stateful — это дополнительные требования и проблемы.
Для решения тривиальной задачи «раздать адреса» в IPv6 придумали stateless режим, который основывается на routing advertisement. Клиентскую часть мы уже видели, теперь осталось реализовать серверную, дабы накормить IPv6 планшетик.
Настройка анонсов маршрутизации (radvd)
Для настройки анонсов используется специальная программа-демон — radvd. С утилитой из её комплекта (radvdump) мы познакомились чуть выше. Прелесть утилиты в том, что она выводит не просто полученные данные, а готовый конфиг radvd для рассылки аналогичных анонсов.
Итак, настраиваем radvd:
Главное тут — префикс и указание на AdvAutonomous.
Запускаем демона, берём ближайший ноутбук (обычная бытовая убунта с обычным бытовым network-manager’ом), рррраз, и получаем…
Откуда у нас столько ipv6 мы поговорим в следующем разделе, а пока что отметим, что адреса сконфигурировались автоматически. И маршруты у нас такие:
Надеюсь, читатель уже вполне понимает, что происходит. Однако… Чего-то не хватает. У нас нет dns-resolver’а. Точнее есть, но выданный dhcpd по IPv4. А у нас пятиминутка любви к IPv6, так то ресолвер нам тоже нужен IPv6.
Тяжело расчехляя aptitude ставим dhcpv6 и прописываем опции nameserver Как бы не так!
К счастью, IPv6 очень долго продумывался и совершенствовался. Так что мы можем решить проблему без участия DHCP-сервера. Для этого нам надо добавить к анонсу маршрута ещё указание на адреса DNS-серверов.
RDNSS в RA
Описывается вся эта примудрость в RFC 6106. По сути — у нас есть возможность указать адрес рекурсивного DNS-сервера (то есть «обычного ресолвера») в анонсе, распространяемом маршрутизатором.
По большому счёту это всё, что мы хотим от DHCP, так что DHCP там тут не нужен. Компьютеры сами делают себе адреса непротиворечивым образом (то есть для исключения коллизий), знают адреса DNS-серверов. Интернетом можно пользоваться.
Для этого мы дописываем в конфиг radvd соответствующую опцию:
(полный конфиг — см. в конце статьи).
Пробуем подключиться снова — и, ура, всё работает.
google.com выбран был не случайно. Сервисы гугля (в немалой степени youtube) — это едва ли не основной источник IPv6 трафика в настоящий момент. Второй источник — торренты, где можно увидеть аж 5-10% пиров в IPv6 варианте.
На этом рассказ можно было закончить, если бы не ещё одна важная деталь — что за третий IPv6-адрес на интерфейсе ноутбука? И что это за temporary dynamic?
Privacy extension
Как я уже упомянул выше, автоматическое конфигурирование IPv6-адреса на основе MAC-адреса сетевого адаптера хорошо всем, кроме того, что создаёт практически идеальное средство для отслеживания пользователей в сети. Вы можете брать любые браузеры и операционные системы, использовать любых провайдеров (использующих IPv6, так что это всё пишется с прицелом на будущее) — но у вас будет один и тот же MAC-адрес, и любой гугуль, NSA или просто спамер смогут вас отслеживать по младшим битам вашего IPv6 адреса. Старшие будут меняться в зависимости от провайдера, а младшие сохраняться как есть.
Для решения этой проблемы были придуманы специальные расширения для IPv6, называющиеся privacy extensions (RFC 4941). Как любое RFC, его чтение — это обычно признак отчаяния, так что по сути этот стандарт описывает как с помощью шаманства и md5 генерировать случайные автоконфигурируемые адреса.
Хост, в нашем случае обычная убунта на обычном ноутбуке, генерирует штатным образом IPv6 адрес из анонса маршрутизатора. После этого она придумывает себе другой адрес, проверяет, что этот адрес не является зарезервированным (например, нам так повезло, и md5 хеш сгенерировал нам все нули — вместо того, чтобы трубить об этом на всех углах, этот изумительный md5 хеш будет выкинут и вместо него будет взят следующий), и, главное, проверяет, что такого адреса в сети нет. Для этого используется штатный механизм DAD (см ниже). Если всё ок, то на интерфейс назначается новосгенерированный случайный адрес, и именно он используется для общения с узлами Интернета. Хотя наш ноутбук с тем же успехом ответит на пинг и по основному адресу.
Этот адрес периодически меняется и он же меняется при подключении к другим IPv6-сетям (и много вы таких знаете в городе. вздох). В любом случае, даже если мы намертво обсыпаны куками и отпечатками всех браузеров, всё-таки маленький кусочек сохраняемой приватности — это лучше, чем не сохраняемый кусочек.
Duplicate Address Detection
Последняя практически важная фича IPv6 — это DAD. Во времена IPv4 на вопрос «а что делать, если адрес, назначаемый на хост, уже кем-то используется в сети» отвечали «а вы не используйте адреса повторно и всё будет хорошо».
На самом деле все вендоры реализовывали свою версию защиты от повторяющегося адреса, но работало это плохо. В частности, линукс пишет о конфликте IPv4 адресов в dmesg, Windows — в syslog… Event… Короче, забыл. В собственную версию журнала и показывает жёлтенко-тревожненький попапик в трее, мол, бида-бида. Однако, это не мешает использовать дублирующийся адрес, если он назначен статикой, и приводит к головоломным проблемам в районе ARP и времени его протухания (выглядит это так: с одного компьютера по сети по заданному адресу отвечает сервер, а с другого, по тому же адресу, допустим, залётный ноутбук, и они ролями периодически меняются).
Многие DHCP-сервера (циски, например), даже имели специальную опцию «проверять пингом» перед выдачей адреса.
Но всё это были доморощенные костыли для подпирания «а вы не нажимайте, больно и не будет».
Конфиги
Эту часть большинство пропустит не читая, ну, такова судьба конфигов — быть писанными, но не читанными.
Используется ли IPv6?
У меня обычный домашний компьютер. Чуть-чуть raid, LVM XFS, BTRFS, LUCKS, свой почтовый и веб-сервера, dns-сервер и т.д. Я подключен к обычному домашнему провайдеру с IPv6.
Вот статистика использования интернета за четыре дня. Собиралась она простым способом:
Если серьёзно, то столь значительные достижения IPv6 (только представьте себе — почти гигабайт трафика в день) большей частью объясняются ютубом и прочими сервисами гугла. Ещё небольшую долю IPv6 принёс пиринг, причём там львиная доля людей — это всякие туннели и teredo (то есть ненастоящие IPv6, использующиеся от безысходности).
С другой стороны, этот показатель почти в три раза больше моего прошлого замера (полтора года назад), когда доля IPv6 едва-едва переваливала за полтора процента.














