Ping не работает с интерфейсом tap, подключенным к интерфейсу моста с ip в той же подсети, что и у моста с внешней

Мое требование состоит в том, чтобы создать несколько интерфейсов крана, каждый с IP-адресом в одной подсети.

Я попробовал это, создав мост

               br0 (192.168.1.199)
     ___________|_____________________________________
     |                    |       |      |      |     |
   eth0                  tap0    tap1   tap2   tap3   tap4
                (192.168.1.150)  (.151) (.152) (.153) (.154)

Мне нужно, чтобы весь интерфейс крана был доступен с внешнего компьютера. Когда я пинг с tap0 на внешний компьютер, скажем, 192.168.1.200

ping -I tap0 192.168.1.200 -- the ping is not going through. 

Но когда я пинг с 192.168.1.200 до 192.168.1.150 (tap0), он работает, но я получаю MAC-адрес моста (br0)

У меня две проблемы:

  1. Как проверить связь с интерфейсом к внешнему
  2. Как получить MAC-адрес интерфейса правого касания при пинге извне.

1 ответ

Эта задача кажется проблемой XY, но я постараюсь уточнить, что с ней не так и предоставить решение.

  1. Когда вы назначаете IP-адрес на интерфейсе, ядро ​​автоматически создает маршрут с прямым подключением в главной таблице маршрутизации (что вы видите в ip route list) и специальные маршруты (local а также broadcast в local Таблица; что вы видите в ip route list table local).

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

  3. В результате выбор конкретного маршрута зависит от порядка назначения адресов и некоторых других факторов. Чтобы проверить это, вы можете использовать ip route get 192.168.1.200 команда. Когда вы попытаетесь воссоздать интерфейс моста, скорее всего, вы потеряете соединение полностью, потому что путь к 192.168.1.0/24 подсеть будет указывать через один из интерфейсов крана.

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

  5. Более правильный способ заставить эту конфигурацию работать - это назначение адресов на интерфейсах крана с /32 длина префикса. Это работает, как и ожидалось, большую часть времени.

  6. В ядре Linux IP-адреса не связаны жестко с интерфейсом. Небольшая демонстрация: если у вашего хоста есть два сетевых адаптера с различным адресом, и вы физически отсоединяете кабель от одного из них, вы сможете пропинговать IP-адрес на отключенном сетевом адаптере через работающий сетевой адаптер извне.

  7. Выбор интерфейса для связи с внешними хостами определяется конфигурацией маршрутизации при указании IP-адреса в -I вариант пинга. В нем просто указывается адрес источника исходящих пакетов, но не указывается выходной интерфейс. MAC-адрес заполняется на последних шагах отправки пакетов. Вы можете проверить фактический маршрут с ip route get команда:

gw:~# ip r ls table local
broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1 
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1 
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1 
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1 
broadcast 192.168.1.0 dev br0 proto kernel scope link src 192.168.1.199 
local 192.168.1.150 dev tap0 proto kernel scope host src 192.168.1.150 
local 192.168.1.151 dev tap1 proto kernel scope host src 192.168.1.151 
local 192.168.1.152 dev tap2 proto kernel scope host src 192.168.1.152 
local 192.168.1.153 dev tap3 proto kernel scope host src 192.168.1.153 
local 192.168.1.154 dev tap4 proto kernel scope host src 192.168.1.154 
local 192.168.1.199 dev br0 proto kernel scope host src 192.168.1.199 
broadcast 192.168.1.255 dev br0 proto kernel scope link src 192.168.1.199 

gw:~# ip -4 r ls
192.168.1.0/24 dev br0 proto kernel scope link src 192.168.1.199 

gw:~# ip r g 192.168.1.200
192.168.1.200 dev br0 src 192.168.1.199 uid 0 
    cache 

gw:~# ip r g 192.168.1.200 from 192.168.1.150
192.168.1.200 from 192.168.1.150 dev br0 uid 0 
    cache
  1. Но когда вы указываете имя интерфейса в -I Опция ping, будет использоваться необработанный сокет. В этом случае выходной интерфейс жестко определен, и этап маршрутизации пропускается. Но, как описано в другом ответе, ядро ​​будет пытаться отправить пакет через указанный интерфейс (неактивное нажатие). Очевидно, что это не удается.

  2. Итак, у нас есть хороший пример проблемы XY. Я думаю, что автор темы хотел проверить мост с эмуляцией отдельных хостов. Одним из простых способов сделать это является использование сетевых пространств имен.

Маленький пример

Краткий пример для IP-адреса 192.168.1.150,

  • Создайте пространство имен сети, которое будет эмулировать виртуальный хост:
ip netns add VM150
  • Создайте пару интерфейсов ve th. Переместите одноранговый интерфейс в пространство имен сети. Оставшийся вете интерфейс подключен к br0 интерфейс как мостовой порт.
ip link add name vethVM150 type veth peer vethIntVM150
ip link set dev vethIntVM150 netns VM150
ip link set dev vethVM150 master br0
ip link set dev evthVM150 up
  • Настройте сеть внутри пространства имен сети VM150. А затем пинговать 192.168.1.200 хост от него:
ip netns exec VM150 bash
ip netns identify
output> VM150
ip link set up dev lo
ip link set up dev vethIntVM150
ip address 192.168.1.150/24 dev vethIntVM150
ping 192.168.1.200
...
  • Проверьте конфигурацию с помощью утилит tcpdump и bridge (запустите на другой консоли хоста; лучше используйте GNU screen или tmux). Вы увидите другой mac-адрес в заголовках Ethernet.
tcpdump -ni eth0 -e
15:38:54.084416 0a:28:39:f0:04:ad > 0c:d6:26:25:f9:00, ethertype IPv4 (0x0800), length 98: 192.168.1.150 > 192.168.1.200: ICMP echo request, id 2037, seq 72, length 64
15:38:54.088262 0c:d6:26:25:f9:00 > 0a:28:39:f0:04:ad, ethertype IPv4 (0x0800), length 98: 192.168.1.200 > 192.168.1.150: ICMP echo reply, id 2037, seq 72, length 64
15:38:54.403666 0c:d6:26:c2:70:00 > 0c:d6:26:25:f9:00, ethertype IPv4 (0x0800), length 98: 192.168.1.199 > 192.168.1.200: ICMP echo request, id 2043, seq 15, length 64
15:38:54.407580 0c:d6:26:25:f9:00 > 0c:d6:26:c2:70:00, ethertype IPv4 (0x0800), length 98: 192.168.1.200 > 192.168.1.199: ICMP echo reply, id 2043, seq 15, length 64
15:38:55.085501 0a:28:39:f0:04:ad > 0c:d6:26:25:f9:00, ethertype IPv4 (0x0800), length 98: 192.168.1.150 > 192.168.1.200: ICMP echo request, id 2037, seq 73, length 64
15:38:55.087252 0c:d6:26:25:f9:00 > 0a:28:39:f0:04:ad, ethertype IPv4 (0x0800), length 98: 192.168.1.200 > 192.168.1.150: ICMP echo reply, id 2037, seq 73, length 64
15:38:55.405129 0c:d6:26:c2:70:00 > 0c:d6:26:25:f9:00, ethertype IPv4 (0x0800), length 98: 192.168.1.199 > 192.168.1.200: ICMP echo request, id 2043, seq 16, length 64
15:38:55.407533 0c:d6:26:25:f9:00 > 0c:d6:26:c2:70:00, ethertype IPv4 (0x0800), length 98: 192.168.1.200 > 192.168.1.199: ICMP echo reply, id 2043, seq 16, length 64
15:38:56.087472 0a:28:39:f0:04:ad > 0c:d6:26:25:f9:00, ethertype IPv4 (0x0800), length 98: 192.168.1.150 > 192.168.1.200: ICMP echo request, id 2037, seq 74, length 64
15:38:56.091242 0c:d6:26:25:f9:00 > 0a:28:39:f0:04:ad, ethertype IPv4 (0x0800), length 98: 192.168.1.200 > 192.168.1.150: ICMP echo reply, id 2037, seq 74, length 64
  • Проверка на 192.168.1.200 хост довольно прост - достаточно проверить таблицу ARP
host:~# ip n ls dev eth0
192.168.1.150 lladdr 0a:28:39:f0:04:ad REACHABLE
192.168.1.199 lladdr 0c:d6:26:c2:70:00 REACHABLE

По вопросу 1:

ping -I tap0

говорит ping отправить пакет ping на tap0. Это будет обходить мост и действительно отправлять только по указанному "физическому" интерфейсу. Таким образом, по сути, вы не пингуете "из" интерфейса крана, вы пингуете "его".

Если вы хотите пропинговать "из" интерфейса крана, вам нужно подключить к нему что-нибудь (например, OpenVPN) и отправить пинг с другого конца виртуального кабеля, к которому подключен интерфейс крана.

По вопросу 2: Вы можете попробовать что-то вроде

arp -i br0 -Ds 192.168.1.150 tap0 pub

и т.п.

Другие вопросы по тегам