Почему моя конфигурация IPv6 может достигать одних хостов, но не всех?

Вопрос или проблема

Я пытаюсь настроить IPv6 для одного из моих Linux-машин, но есть вещи, которые я еще не понимаю. Есть одна хитрая вещь: машина должна иметь статический адрес, но также использовать SLAAC. Машина должна работать в двух разных средах: в первой среде есть маршрутизатор, который поддерживает SLAAC, но статический шлюз отсутствует. Во второй среде SLAAC вообще не работает, но вместо этого присутствует статический шлюз. Возможно, это звучит немного страшно (так ли это?), но очень похожая настройка прекрасно работала только на IPv4 до сих пор. Я действительно хочу сохранить это; мой вопрос не столько о очень разных альтернативных подходах.

В первой среде я могу добраться только до некоторых хостов IPv6 (я пока не знаю, как это будет работать во второй среде).

Я использую systemd-networkd для настройки сети, и вот моя конфигурация сетевого интерфейса (некоторые значения анонимизированы):

[Match]
Name=e*

[Network]
Address=2a00:.../64
DNS=...
# IPv4 работает хорошо, но для полноты картины:
Address=185.1.2.3/29
Address=185.1.2.4/29
DHCP=ipv4

[Route]
Gateway=2a00:...:1
Metric=2000

[Route]
Gateway=185.1.2.5
Metric=2000

Это вывод команды ip addr для этого интерфейса (в первой среде), снова анонимизированный:

2: enp5s0:  mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether aa:bb:cc:dd:ee:ff brd ff:ff:ff:ff:ff:ff
    altname enxfoo
    inet 185.1.2.3/29 brd 185.1.2.5 scope global enp5s0
       valid_lft forever preferred_lft forever
    inet 192.168.50.209/24 metric 1024 brd 192.168.50.255 scope global dynamic enp5s0
       valid_lft 83782sec preferred_lft 83782sec
    inet 185.1.2.4/29 brd 185.1.2.5 scope global secondary enp5s0
       valid_lft forever preferred_lft forever
    inet6 2001:.../64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 594sec preferred_lft 594sec
    inet6 2a00:.../64 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80:.../64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever

Таблица маршрутизации выглядит так:

2001:.../64 dev enp5s0 proto ra metric 1024 expires 595sec pref medium
2a00:.../64 dev enp5s0 proto kernel metric 256 pref medium
fe80::/64 dev enp5s0 proto kernel metric 256 pref medium
default nhid 2343432122 via fe80:... dev enp5s0 proto ra metric 1024 expires 595sec pref medium
default via 2a00:...:1 dev enp5s0 proto static metric 2000 pref medium
$ ip nexthop show
id 2343432122 via fe80:... dev enp5s0 scope link proto ra 

Пока все идет хорошо. У меня есть общее понимание этого, но я не эксперт. Для меня кажется, что у нас там установлена статическая настройка, но SLAAC также работал, и динамический маршрут имеет лучший метрический показатель, поэтому это было достаточно хорошо, чтобы попробовать. Однако я могу добраться только до некоторых хостов. Этот работает:

$ ping6 2604:1380:4641:c500::1
PING 2604:1380:4641:c500::1 (2604:1380:4641:c500::1) 56 data bytes
64 bytes from 2604:1380:4641:c500::1: icmp_seq=1 ttl=54 time=126 ms
64 bytes from 2604:1380:4641:c500::1: icmp_seq=2 ttl=54 time=127 ms

А этот не работает:

$ ping6 2a00:1450:4001:830::2003
PING 2a00:1450:4001:830::2003 (2a00:1450:4001:830::2003) 56 data bytes

Я попробовал немного больше, и кажется, что это зависит от начала адреса назначения. Затем я проверил, какие решения маршрутизации применяются в этих двух случаях:

$ ip -6 route get 2604:1380:4641:c500::1
2604:1380:4641:c500::1 from :: via fe80::... dev enp5s0 proto ra src 2001:... metric 1024 pref medium

$ ip -6 route get 2a00:1450:4001:830::2003
2a00:1450:4001:830::2003 from :: via fe80::... dev enp5s0 proto ra src 2a00:... metric 1024 pref medium

Таким образом, для рабочего случая он решил использовать адрес, полученный через SLAAC, в качестве адреса источника. Отлично. Для нерабочего случая он решил использовать статический адрес. Это не может сработать. Пакеты никогда не найдут дорогу обратно. Но почему он это делает? Я вижу, что мой статический адрес начинается с “2a00”, как и адрес назначения. Но является ли это причиной? Каковы именно там правила? Я еще не понимаю этого и пока не смог найти ценные ответы в Интернете. Есть ли простой способ это исправить?

Один из основных принципов выбора исходного адреса IPv6 — “наиболее длинный общий префикс”. Каждый из кандидатов на роль исходного адреса сравнивается с адресом назначения, чтобы определить, сколько идентичных битов они имеют (считая слева, как с префиксами CIDR), и адрес с наиболее длинным общим префиксом выбирается в качестве исходного адреса.

Важно, что только адрес назначения — не адрес шлюза — сравнивается с кандидатами на роль исходных адресов. (Хотя с IPv6 SLAAC также должно быть правило, предпочитающее источники, которые находятся в пределах префикса, рекламируемого этим конкретным шлюзом, но я не помню, реализовано ли это в Linux. Думаю, что нет.)

Попробуйте добавить параметр PreferredSource= к вашим маршрутам (известный как src в iproute2). Он работает одинаково в IPv4 и IPv6 и может использоваться для указания предпочтительного исходного IP-адреса, когда используется этот маршрут.

Ответ или решение

Настройка сетевого соединения с использованием IPv6 может быть довольно сложной задачей, особенно когда необходимо использовать как статическую, так и автоматическую конфигурацию адресов через SLAAC (Stateless Address Autoconfiguration). В вашем случае возникли проблемы с достижением некоторых хостов при работе в первой среде, где поддерживается SLAAC, но отсутствует статический шлюз. Давайте разберемся, почему это может происходить и как можно исправить ситуацию.

Теория

Основной причиной ваших затруднений является выбор исходного адреса IPv6 в зависимости от выбранного маршрута. Согласно правилам выбора исходного адреса в протоколе IPv6, при попытке отправить пакет, система оценивает "длину общей префиксной части" между кандидатами на роль исходного адреса и адресом получателя. Исходный адрес, имеющий наиболее длинную общую префиксную часть с адресом назначения, и будет выбран.

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

Пример

Для наглядности рассмотрим два случая из вашего описания:

  1. Пакет, направленный на 2604:1380:4641:c500::1, использует в качестве исходного адреса адрес 2001:…, полученный через SLAAC, и связь успешно устанавливается.

  2. Пакет, направленный на 2a00:1450:4001:830::2003, выбрал в качестве исходного адрес, начинающийся с 2a00:…, что, как следует из вашего описания, является статическим адресом. Из-за этого возврат пакета оказывается невозможным, и связь не устанавливается.

Применение

Для решения вашей проблемы, необходимо изменить подход к выбору исходного адреса. В Linux вы можете воспользоваться параметром PreferredSource=, который позволяет задать предпочтительный исходный адрес для каждого маршрута.

Пример конфигурации с использованием PreferredSource= может выглядеть следующим образом в вашем конфигурационном файле:

[Route]
Gateway=2a00:...:1
Metric=2000
PreferredSource=2001:...

[Route]
Gateway=185.1.2.5
Metric=2000
PreferredSource=185.1.2.3

Это поможет системе корректно устанавливать исходный адрес для каждого из маршрутов, обеспечивая корректную маршрутизацию пакетов в обе стороны. Таким образом каждый раз, когда будет использован определённый маршрут, система будет знать, какой исходный адрес предпочесть.

Дополнительные рекомендации

  1. Тщательный мониторинг и тестирование: После внесения изменений в конфигурацию сети, убедитесь, что потестировали её в различных сценариях, чтобы удостовериться в устранении проблемы.

  2. Логирование и отладка: Используйте возможности системного логирования для отслеживания работы сети. Это может дать дополнительную информацию о работе системы и помочь в диагностике потенциальных проблем.

  3. Документация и обратная связь: В случае работы в команде обязательно документируйте сделанные изменения и делитесь наблюдениями с коллегами.

  4. Поддержка и обновления: Регулярно обновляйте свои настройки и ПО, следите за рекомендациями по безопасности и улучшениями, вводимыми производителем вашей операционной системы.

Следуя этим шагам, вы сможете настроить вашу сеть так, чтобы она работала стабильно и надежно в обоих заданных вами окружениях.

Оцените материал
Добавить комментарий

Капча загружается...