Мое требование - создать несколько интерфейсов, каждый с 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)
У меня две проблемы:
Эта задача выглядит как проблема 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
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
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
...
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
host довольно прост - достаточно проверить таблицу ARPhost:~# 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
и т.п.