Считанные дни остаются до старта нового потока по курсу «Сетевой инженер» от OTUS. В связи с этим хотим поделиться с вами переводом полезного материала по теме.




Серия статей в блоге, посвященных советам и рекомендациям по устранению неполадок, связанных с пингом IPv6 (ICMPv6 Echo Request/Echo Reply)

Обратите внимание, что я использую Linux (в частности, Fedora 31), однако синтаксис команды ping для других операционных систем, надеюсь, должен быть очень похожим.

Пинг всех узлов IPv6 на канале


Первый и самый простой совет — пропинговать все узлы IPv6 на канале.

IPv6 использует мультикаст-адреса для всех типов связи «один ко многим». Не существует бродкастных (или широковещательных) IPv6-адресов. Это отличает IPv6 от IPv4, где существует несколько типов бродкастных адресов, например, «limited broadcast» адрес 255.255.255.255 [RFC1122].

Однако существует “all-nodes multicast” (общий мультикаст) IPv6-адрес, поэтому мы будем использовать его для пинга всех узлов IPv6 в канале. («Широковещательный» адрес на самом деле является просто специально названным мультиакастным адресом, который является группой многоадресной рассылки, включающей все узлы. Обратите внимание, что, например, бит «группы» или мультикастного адреса включен в бродкастных адресах Ethernet на канальном уровне).

All-nodes multicast IPv6-адрес для канала: ff02::1. ff обозначает мультикастовый IPv6-адрес. Следующий 0 — это часть флага с неустановленными битами.

Далее 2 определяет область мультикастовой группы. В отличие от мультикаст IPv4-адресов, мультикаст IPv6-адреса имеют scope (область видимости). Значение scope указывает часть сети, по которой разрешено пересылать мультикастный пакет. Как только пакет достигает границы указанного scope, пакет должен быть отброшен, независимо от того, является ли его поле счетчика переходов (Hop Count) ненулевым. Конечно, если счетчик переходов достигает нуля до достижения указанной границы мультикастовой группы, он также немедленно сбрасывается. Вот полный список мультикаст scope IPv6.

Наконец, ::1 указывает all-nodes multicast группу.

Об адресе ff02::1 следует заметить, что он неоднозначен. На узле IPv6 с несколькими интерфейсами, такими как маршрутизатор или многосетевой хост, в адресе ff02::1 нет ничего, где бы можно было указать, какому интерфейсу отправлять эхо-запросы ICMPv6 или ожидать получения эхо-ответов ICMPv6, когда они приходят. ff02::1 действителен и может использоваться на любом из интерфейсов и каналов, прикрепленных к многоинтерфейсному узлу.

Поэтому, когда мы пропингуем все узлы IPv6 на канале, нам нужно как-то также сообщить утилите ping для IPv6, какой интерфейс использовать.

Определение интерфейсов — параметр командной строки


Как мы уже видели, all-nodes multicast адрес, который мы хотим использовать — ff02::1 — не предоставляет никакой информации относительно того, на какой интерфейс отправлять и получать пакеты эхо-запроса и эхо-ответа ICMPv6.

Итак, как нам указать интерфейс, который будет использоваться для пространства мультикастовых адресов или юникастовых Link-Local адресов?

Первый и наиболее очевидный способ — предоставить его в качестве параметра для приложения, которое мы используем.

Для утилиты ping мы предоставляем его через опцию -I.

[mark@opy ~]$ ping -w 1 -I enp3s2 ff02::1
ping: Warning: source address might be selected on device other than: enp3s2
PING ff02::1(ff02::1) from :: enp3s2: 56 data bytes
64 bytes from fe80::1d36:1fff:fefd:82be%enp3s2: icmp_seq=1 ttl=64 time=0.438 ms
64 bytes from fe80::f31c:ccff:fe26:a6d9%enp3s2: icmp_seq=1 ttl=64 time=0.589 ms (DUP!)
64 bytes from fe80::7e31:f5ff:fe1b:9fdb%enp3s2: icmp_seq=1 ttl=64 time=5.15 ms (DUP!)
64 bytes from fe80::f7f8:15ff:fe6f:be6e%enp3s2: icmp_seq=1 ttl=64 time=58.0 ms (DUP!)
64 bytes from fe80::877d:4ff:fe1a:b881%enp3s2: icmp_seq=1 ttl=64 time=62.3 ms (DUP!)
64 bytes from fe80::877d:4ff:fe1a:ad79%enp3s2: icmp_seq=1 ttl=64 time=62.8 ms (DUP!)
 
--- ff02::1 ping statistics ---
1 packets transmitted, 1 received, +5 duplicates, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.438/31.544/62.786/29.566 ms
[mark@opy ~]$


С помощью этого all-nodes multicast пинга мы получили ответы от 6 IPv6-узлов. Ответы поступили от узловых Link-Local IPv6-адресов, начиная с префикса fe80::/10.

Чтобы ping не продолжал бесконечно отправлять эхо-запросы ICMPv6 до тех пор, пока мы не прервем его, мы обычно указываем количество пакетов для отправки через опцию -c. Однако это также не позволяет ping принять и отобразить более одного эхо-ответа ICMPv6 при отправке мультикаст эхо-запроса ICMPv6. Вместо этого мы использовали параметр -w, чтобы указать, что ping должен завершаться через 1 секунду, независимо от того, сколько эхо-запросов или эхо-ответов ICMPv6 было отправлено или получено.

Еще одна вещь, на которую следует обратить внимание, это (DUP!) вывод на втором и последующих ответах. Эти пакеты идентифицируются как дубликаты ответа, поскольку они имеют то же значение последовательности ICMP, что и отдельные эхо-запросы ICMPv6, которые были отправлены в первую очередь. Они появляются, потому что мультикаст эхо-запрос ICMPv6 приводит к нескольким индивидуальным юникаст ответам. Количество дубликатов также указывается в сводке статистики.

Определение интерфейсов — Zone ID


Еще один способ предоставления интерфейса для использования — это часть параметра адреса IPv6.

Мы можем наблюдать пример этого в выводе ping, где адреса отвечающих IPv6-узлов также имеют суффикс %enp3s2, например:

64 bytes from fe80::1d36:1fff:fefd:82be%enp3s2: icmp_seq=1 ttl=64 time=0.438 ms


Этот способ задания интерфейсов формально описан в [RFC4007], «Архитектура с заданными адресами IPv6». Хотя обычно они называются интерфейсом операционной системы, они на самом деле определяют нечто более общее — «зона» или «область действия».

Причина наличия более общих зон или scope зон состоит в том, что, как упоминается в [RFC4007], узел IPv6 может иметь несколько различных интерфейсов IPv6, подключенных к одному и тому же каналу. Эти интерфейсы являются членами одной зоны.

Должно быть возможно сгруппировать несколько интерфейсов в пределах зоны под операционной системой; В настоящее время я не знаю, возможно ли это под Linux и как это сделать.

Используя суффикс %<zone_id>, мы можем удалить параметр командной строки -I ping.

[mark@opy ~]$ ping -w 1 ff02::1%enp3s2
PING ff02::1%enp3s2(ff02::1%enp3s2) 56 data bytes
64 bytes from fe80::2392:6213:a15b:66ff%enp3s2: icmp_seq=1 ttl=64 time=0.106 ms
64 bytes from fe80::1d36:1fff:fefd:82be%enp3s2: icmp_seq=1 ttl=64 time=0.453 ms (DUP!)
64 bytes from fe80::f31c:ccff:fe26:a6d9%enp3s2: icmp_seq=1 ttl=64 time=0.606 ms (DUP!)
64 bytes from fe80::7e31:f5ff:fe1b:9fdb%enp3s2: icmp_seq=1 ttl=64 time=6.23 ms (DUP!)
64 bytes from fe80::f7f8:15ff:fe6f:be6e%enp3s2: icmp_seq=1 ttl=64 time=157 ms (DUP!)
64 bytes from fe80::877d:4ff:fe1a:ad79%enp3s2: icmp_seq=1 ttl=64 time=159 ms (DUP!)
64 bytes from fe80::877d:4ff:fe1a:b881%enp3s2: icmp_seq=1 ttl=64 time=161 ms (DUP!)
64 bytes from fe80::23d:e8ff:feec:958c%enp3s2: icmp_seq=1 ttl=64 time=179 ms (DUP!)
 
--- ff02::1%enp3s2 ping statistics ---
1 packets transmitted, 1 received, +7 duplicates, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.106/82.858/179.216/81.281 ms
 
[mark@opy ~]$



Ответы Link-Local адресов


От этого all-nodes multicast пинга мы получили в общей сложности 6 уникальных ответов.

Эти ответы поступили от юникаст Link-Local адресов узлов IPv6. Например, вот первый ответ:

64 bytes from fe80::2392:6213:a15b:66ff%enp3s2: icmp_seq=1 ttl=64 time=0.106 ms


Юникаст Link-Local IPv6-адреса требуются на всех интерфейсах с поддержкой IPv6 [RFC4291], «Архитектура адресации IP версии 6». Причина этого заключается в том, что узел IPv6 всегда автоматически имеет юникастовый IPv6-адрес, который он может использовать, по крайней мере, для связи с другими узлами по своим напрямую подключенным каналам. Это включает в себя связь с приложениями других хостов через Link-Local адреса хостов.

Это упрощает разработку и реализацию протоколов, таких как IPv6 Neighbor Discovery и OSPFv3. Это также позволяет приложениям конечных пользователей на хостах обмениваться данными по каналу, не требуя на канале какой-либо другой поддерживающей инфраструктуры IPv6. Для прямой связи подключенных хостов IPv6 не требуется маршрутизатор IPv6 или сервер DHCPv6 в соединении.

Адреса Link-Local начинаются с 10-битного префикса fe80, за которым следуют 54 нулевых бита, а затем 64-битный идентификатор интерфейса (IID). В приведенном выше первом ответе 2392:6213:a15b:66ff — это 64-битный IID.

Looped Multicast


По умолчанию мультикастовые пакеты возвращаются внутренне на узел, который их отправляет. Это происходит для обоих IPv6 и IPv4 адресаций.

Причиной этого дефолтного поведения является то, что при отправке мультикаст пакетов может также быть слушающее локальное мультикастовое приложение, работающее на самом отправляющем хосте, также как и где-то в сети. Это локальное приложение также должны получать мультикаст пакеты.

Мы можем видеть этот мультикастовый локальный цикл в нашем ping выводе:

[mark@opy ~]$ ping -w 1 ff02::1%enp3s2
PING ff02::1%enp3s2(ff02::1%enp3s2) 56 data bytes
64 bytes from fe80::2392:6213:a15b:66ff%enp3s2: icmp_seq=1 ttl=64 time=0.106 ms
64 bytes from fe80::1d36:1fff:fefd:82be%enp3s2: icmp_seq=1 ttl=64 time=0.453 ms (DUP!)
...


Первый и самый быстрый ответ (0,106 мс по сравнению с 0,453 мс) происходит от Link-Local адреса, настроенного на самом интерфейсе enp3s2.

[mark@opy ~]$ ip addr show dev enp3s2 | grep fe80
    inet6 fe80::2392:6213:a15b:66ff/64 scope link noprefixroute 
[mark@opy ~]$


Утилита ping предоставляет способ подавления локальной обратной связи мультикастовой рассылки с помощью параметра -L. Если мы отправляем пинг all-nodes multicast с этим флагом, то ответы ограничиваются удаленными узлами. Мы не получаем ответ от Link-Local адреса интерфейса отправителя.

[mark@opy ~]$ ping -L -w 1 ff02::1%enp3s2
PING ff02::1%enp3s2(ff02::1%enp3s2) 56 data bytes
64 bytes from fe80::1d36:1fff:fefd:82be%enp3s2: icmp_seq=1 ttl=64 time=0.383 ms
 
64 bytes from fe80::f31c:ccff:fe26:a6d9%enp3s2: icmp_seq=1 ttl=64 time=0.467 ms (DUP!)
...


Пинг Link-Local Адреса


Как вы можете догадаться, юникастовые Link-Local адреса сами по себе также не предоставляют достаточно информации, чтобы указать, какой интерфейс использовать для их достижения. Как и в случае all-nodes multicast пинга, нам также необходимо указать интерфейс в качестве параметра командной строки ping или zone ID с адресом при пинге Link-Local адресов.

На этот раз мы можем использовать -c, чтобы ограничить количество пакетов и ответов, отправляемых и получаемых ping, поскольку мы выполняем юникастный пинг.

[mark@opy ~]$ ping -c 1 fe80::f31c:ccff:fe26:a6d9%enp3s2
 
PING fe80::f31c:ccff:fe26:a6d9%enp3s2(fe80::fad1:11ff:feb7:3704%enp3s2) 56 data bytes
64 bytes from fe80::f31c:ccff:fe26:a6d9%enp3s2: icmp_seq=1 ttl=64 time=0.395 ms
 
--- fe80::f31c:ccff:fe26:a6d9%enp3s2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.395/0.395/0.395/0.000 ms
[mark@opy ~]$


Пинговать (все) другие IPv6-адреса?


В этой статье мы увидели, как пропинговать все IPv6-узлы на канале, используя all-nodes multicast IPv6-адрес ff02::1. Мы также видели, как указать, какой интерфейс использовать с all-nodes multicast IPv6-адресом, поскольку сам по себе адрес не может предоставить эту информацию. Мы использовали либо параметр командной строки ping, либо указали интерфейс через суффикс %<zone_id>.

Затем мы узнали об юникастовых Link-Local адресах, которые являются адресами, используемыми для ответов на all-nodes multicast эхо-запросы ICMPv6.

Мы также видели, как мультикаст пакеты возвращаются в отправляющий узел по умолчанию и как отключить это для утилиты ping.

Наконец, мы пропинговали единичный Link-Local адрес, используя суффикс %<zone_id>, так как Link-Local адреса сами по себе также не предоставляют информацию об исходящем интерфейсе.

Так как насчет пинга всех других узлов и получения их глобальных юникаст адресов (GUA) (то есть их общедоступных адресов в Интернете) или их уникальных локальных юникаст адресов (ULA)? Мы рассмотрим это в следующей статье блога.

На этом все.

Узнать подробнее о нашем курсе можно в записи дня открытых дверей.