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)
У меня две проблемы:
- Как проверить связь с интерфейсом к внешнему
- Как получить MAC-адрес интерфейса правого касания при пинге извне.
1 ответ
Эта задача кажется проблемой XY, но я постараюсь уточнить, что с ней не так и предоставить решение.
Когда вы назначаете IP-адрес на интерфейсе, ядро автоматически создает маршрут с прямым подключением в главной таблице маршрутизации (что вы видите в
ip route list
) и специальные маршруты (local
а такжеbroadcast
вlocal
Таблица; что вы видите вip route list table local
).Когда вы назначаете перекрывающиеся или одинаковые адресные пространства на нескольких интерфейсах, вы получите несколько идентичных маршрутов в таблицах маршрутизации. Очевидно, это не очень хорошая вещь.
В результате выбор конкретного маршрута зависит от порядка назначения адресов и некоторых других факторов. Чтобы проверить это, вы можете использовать
ip route get 192.168.1.200
команда. Когда вы попытаетесь воссоздать интерфейс моста, скорее всего, вы потеряете соединение полностью, потому что путь к192.168.1.0/24
подсеть будет указывать через один из интерфейсов крана.Эта конфигурация будет работать только в одном случае: когда адрес на интерфейсе моста назначен раньше, чем на других интерфейсах с той же подсетью, но нет гарантии. Итак, основной результат: не назначайте адреса из одной подсети на несколько интерфейсов, если вы не до конца понимаете, как это будет работать.
Более правильный способ заставить эту конфигурацию работать - это назначение адресов на интерфейсах крана с
/32
длина префикса. Это работает, как и ожидалось, большую часть времени.В ядре Linux IP-адреса не связаны жестко с интерфейсом. Небольшая демонстрация: если у вашего хоста есть два сетевых адаптера с различным адресом, и вы физически отсоединяете кабель от одного из них, вы сможете пропинговать IP-адрес на отключенном сетевом адаптере через работающий сетевой адаптер извне.
Выбор интерфейса для связи с внешними хостами определяется конфигурацией маршрутизации при указании 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
Но когда вы указываете имя интерфейса в
-I
Опция ping, будет использоваться необработанный сокет. В этом случае выходной интерфейс жестко определен, и этап маршрутизации пропускается. Но, как описано в другом ответе, ядро будет пытаться отправить пакет через указанный интерфейс (неактивное нажатие). Очевидно, что это не удается.Итак, у нас есть хороший пример проблемы 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
и т.п.