Почему два соединенных мостом veth не могут пинговать друг друга?

Попробуйте подключить системный диск (файл системного диска )к надежной системе Linux, где у вас есть права root . Затем вы можете исследовать passwd, group, sudoersи все другие соответствующие файлы, и/или вы можете использовать chrootдля входа в неисправную систему.

2
24.06.2021, 15:30
1 ответ

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

Нет смысла проводить этот тест на одиночном сетевом стеке. Чтобы заставить его работать таким образом, требуется много настроек, и конечный результат вообще не будет отражать конфигурацию, аналогичную намеченной цели, и не будет полезен для разработки такого проекта.

Самый простой и правильный способ сделать это в Linux — использовать сетевые пространства имен (или контейнеры )

.

Используйте настройки OP, затем интерфейсы перемещаются в два пространства имен (, созданных с помощьюip netns add). Поскольку это приводит к потере конфигурации интерфейсов, повторно -добавьте то, чего не хватает. Так как root пользователь, после настройки OP (за вычетом назначенных адресов, которые все равно будут потеряны):

ip netns add system1
ip netns add system2

ip link set dev veth0 netns system1
ip link set dev veth1 netns system2

ip -n system1 link set lo up # this is optional for this problem
ip -n system2 link set lo up # this is optional for this problem
ip -n system1 address add 10.0.0.1/24 dev veth0
ip -n system2 address add 10.0.0.2/24 dev veth1
ip -n system1 link set dev veth0 up
ip -n system2 link set dev veth1 up

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

.
ip netns exec system1 ping 10.0.0.2

Примечание :Всю эту конкретную настройку (только с двумя одноранговыми узлами )можно закоротить без моста, первоначально создав интерфейсы, подобные этому:ip link add name veth0 type veth peer name veth1. Мост не является частью проблемы, но он, безусловно, необходим, как только необходимо смоделировать 3-ю одноранговую систему.


Бонус для любознательных :ответьте на вопрос письмом

Цель :— заставить хост пинговать сам себя по сети, а не по интерфейсу lo. Опять же, как предупреждение, даже если это сработает, результат не может быть использован ни для чего полезного, в том числе для моделирования нескольких систем.

Таким образом, это делается с начальной настройкой OP без сетевого пространства имен.

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

  • система должна принимать пакет с исходным IP-адресом, принадлежащим ей самой , а не отбрасывать его

    sysctl -w net.ipv4.conf.veth0.accept_local=1
    sysctl -w net.ipv4.conf.veth1.accept_local=1
    
  • один и тот же пакет виден дважды, один раз при отправке, один раз при получении обратно, и для этого требуются разные (маршруты на основе политики )для двух случаев.

    Система должна отличать случай, когда пакет создается локально и отправляется через veth0, от случая, когда этот пакет затем принимается от veth1по сети. Для этого требуются две разные таблицы маршрутизации, выбранные двумя разными правилами маршрутизации политики. В обратном направлении это дало бы в общей сложности 4 правила и 4 таблицы. На самом деле локальная таблица маршрутизации уже включает половину из этих (для полученных пакетов :, предназначенных для хоста ), поэтому специальное правило и таблица маршрутизации нужны только локально отправленным пакетам.

    Правила политики:

    ip rule add priority 11 iif lo from 10.0.0.1 lookup 1001
    ip rule add priority 21 iif lo from 10.0.0.2 lookup 2001
    

    Специальное iif loозначает локально инициированный трафик (, на самом деле это не получение от интерфейса lo).

    И связанные таблицы маршрутизации, каждая со своим единственным маршрутом:

    ip route add 10.0.0.2 dev veth0 table 1001
    ip route add 10.0.0.1 dev veth1 table 2001
    
  • локальная таблица маршрутизации мешает

    Пока имеем:

    # ip rule
    0:      from all lookup local
    11:     from 10.0.0.1 iif lo lookup 1001
    21:     from 10.0.0.2 iif lo lookup 2001
    32766:  from all lookup main
    32767:  from all lookup default
    
    # ip route show table local to root 10.0.0.0/24
    local 10.0.0.1 dev veth0 proto kernel scope host src 10.0.0.1 
    local 10.0.0.2 dev veth1 proto kernel scope host src 10.0.0.2 
    broadcast 10.0.0.255 dev veth0 proto kernel scope link src 10.0.0.1 
    broadcast 10.0.0.255 dev veth1 proto kernel scope link src 10.0.0.2 
    

    Локальная таблица имеет правило с наименьшим значением приоритета и используется первой. Две первые записи соответствуют первым и переопределяют дополнительные правила (prio 11 и 21 )и маршруты, сохраняя пакет локальным (, т.е. :, используя интерфейс lo).

    Можно было бы удалить эти записи, но тогда, как написано выше, они действительно нужны, но только после добавления правил политики. Кроме того, изменение адресов на интерфейсах заставит ядро ​​рано или поздно добавить их обратно.

    Таким образом, вместо этого можно переместить правило from all lookup localк более высокому значению приоритета, оставив добавленные правила с приоритетом 11 и 21 пройденными первыми, чтобы сначала получить специальные маршруты:

    ip rule add priority 50 lookup local 
    ip rule del priority 0
    

Можно проверить маршруты, которые будут следовать за одиночным пингом и его ответом:

Начальный пакет

  • либо принудительно через veth0при использованииping -I veth0 10.0.0.2:

    # ip route get oif veth0 to 10.0.0.2
    10.0.0.2 dev veth0 src 10.0.0.1 uid 0 
        cache 
    
  • или исходный IP-адрес привязан к 10.0.0.1 при использованииping -I 10.0.0.1 10.0.0.2:

    # ip route get from 10.0.0.1 to 10.0.0.2
    10.0.0.2 from 10.0.0.1 dev veth0 table 1001 uid 0 
        cache 
    

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

Этот пакет (проходит по мосту (см. предостережение об ARP ниже )и )теперь получен на другой стороне поveth1:

# ip route get from 10.0.0.1 iif veth1 to 10.0.0.2
local 10.0.0.2 from 10.0.0.1 dev lo table local 
    cache <local> iif veth1 

Ответ отправляется обратно с адресом источника 10.0.0.2 получателю 10.0.0.1:

# ip route get from 10.0.0.2 to 10.0.0.1
10.0.0.1 from 10.0.0.2 dev veth1 table 2001 uid 0 
    cache 

и ответ (проходит через мост и )полученveth0:

# ip route get from 10.0.0.2 iif veth0 to 10.0.0.1
local 10.0.0.1 from 10.0.0.2 dev lo table local 
    cache <local> iif veth0 

Ожидается успешное завершение раунда проверки связи.

Запросы ARP сделаны и разрешены:

# ip neigh
10.0.0.1 dev veth1 lladdr f2:2a:75:82:17:d3 DELAY
10.0.0.2 dev veth0 lladdr 42:91:a1:a6:64:45 REACHABLE
10.0.0.1 dev br0 lladdr f2:2a:75:82:17:d3 STALE

Как видно, собственный интерфейс моста br0,несмотря на отсутствие настроенного адреса, он также участвует в ARP и маршрутизации просто благодаря своему присутствию в одном и том же сетевом стеке из-за реализации в Linux слабой модели хоста . Выше 42:91:a1:a6:64:45было от br0(, унаследованного отveth1p). Из-за этого первые несколько эхо-запросов могут быть первоначально маршрутизированы как veth0->br0(+ ответы как veth1->veth0)вместо veth0->veth1(+ veth1->veth0)и вернуться к некоторым через несколько секунд к правильному потоку после истечения срока действия предварительно изученных записей ARP.

br0можно предотвратить участие в маршрутизации различными способами, в том числе:

  • сarp_ignore:

    sysctl -w net.ipv4.conf.br0.arp_ignore=1
    
  • или активировавrp_filter(для Strict Reverse Path Forwarding)на нем, чтобы он также не отвечал ARP:

    sysctl -w net.ipv4.conf.br0.rp_filter=1
    
  • или изоляция собственного интерфейса моста от портов моста, если система Linux поддерживает фильтрацию VLAN моста:

    ip link set dev br0 type bridge vlan_filtering 1
    bridge vlan del vid 1 dev br0 self
    

    Это отключает собственный интерфейс моста от связи с его собственными портами моста в конфигурации по умолчанию, тем самым перекрывая «утечку» стека локальной сети через него. (Кроме того, при захвате с помощью tcpdump -i br0 -pс опцией -pне устанавливать беспорядочный режим в этом случае больше не будет получать трафик ).

Опять же, этот незначительный сбой не произойдет в реальном случае, поскольку мост будет находиться в другом месте (, например, :реальном коммутаторе, другой виртуальной машине или другом сетевом пространстве имен/контейнере ).

0
24.10.2021, 16:25

Теги

Похожие вопросы