5

Описание

Это похоже на этот вопрос, но отличается:

У компьютера Linux есть две сетевые карты. eth0 статически назначается с IP. eth1 предоставляется персоналом в данной области, который может иметь один и тот же IP или другой IP. План состоит в том, чтобы eth0 и eth1 находились в другой сети и никогда не обменивались и не пересекали какие-либо пакеты. А мое Linux-приложение только слушает и принимает соединение по eth0 и eth1 и начинает отправку пакетов при получении, но никогда не пытается инициировать какую-либо активность.

Вопрос

Могут ли два сетевых адаптера иметь IP в одной подсети: 192.168.1.4 и 192.168.1.5? Как вы можете видеть, eth0 и eth1 назначены в одной подсети (255.255.255.0), но они не подключены и не должны быть подключены.

В этом случае, когда приложение прослушивает порт eth0 55555 , принимает соединение и возвращает пакет обратно, знает ли нижележащий уровень, что оно должно вернуться к eth0? Или он попытается использовать eth1 поскольку ОС считает, что он находится в той же подсети? Что мне нужно сделать с таблицей маршрутизации, чтобы убедиться, что она не считает, что эти два сетевых адаптера находятся в одной подсети?

Стоит ли в этом случае избегать не только похожих IP-адресов, но и одной и той же подсети?

Обновить

Что если PC0 и PC1 имеют одинаковый IP?

PC0 (1.100) <-------> [eth0 (1.4)  My System eth1 (1.5)]<-------PC1(1.100)

Мое приложение должно прослушивать порт 55555 на eth0 и eth1, и запрос поступает через eth1, может ли ОС знать, что ответить, пройти через eth1? Эта конфигурация вызовет проблему?

Бизнес-пример: я строю эту встроенную систему и заранее определяю IP для eth0 и PC0 (PC0 также может быть DHCP). Но у моего клиента уже есть сеть с правой стороны. Что если у них есть устройство, конфликтующее с PC0 или eht0? Даже если DHCP-сервер установлен на eth0, невозможно исключить IP-адреса с правой стороны при назначении IP-адреса для PC0. Если это создает проблемы, у меня есть много решений. Но я хотел бы услышать мнение коллег, является ли это проблемой.

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

1 ответ1

5

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

По всей вероятности, сеть назначения содержится в маршруте по умолчанию - 0.0.0.0/0, через шлюз по умолчанию.

Не веришь мне?
Давайте рассмотрим:

[root@localhost ~]# ip address show label eth* | grep -v 'link\|val'
  2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
      inet 192.168.1.4/24 brd 192.168.1.255 scope global eth0
  3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
      inet 192.168.1.5/24 brd 192.168.1.255 scope global eth1

Два интерфейса, eth0 и eth1, с IP-адресами и маской, как в вашем вопросе.

Полная настройка запуска:

[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
  DEVICE="eth0"
  NM_CONTROLLED="no"
  ONBOOT="yes"
  TYPE=Ethernet
  DEFROUTE=yes
  IPV4_FAILURE_FATAL=yes
  IPV6INIT=no
  Name="eth0"
  BOOTPROTO=none
  IPADDR=192.168.1.4
  NETMASK=255.255.255.0
  GATEWAY=192.168.1.1

[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth1
  DEVICE="eth1"
  NM_CONTROLLED="no"
  ONBOOT="yes"
  TYPE=Ethernet
  DEFROUTE=yes
  IPV4_FAILURE_FATAL=yes
  IPV6INIT=no
  Name="eth1"
  BOOTPROTO=none
  IPADDR=192.168.1.5
  NETMASK=255.255.255.0
  GATEWAY=192.168.1.2

Обратите внимание, что для каждого адреса установлены разные адреса шлюза - .1 и .2.
Теперь давайте посмотрим на таблицу маршрутизации:

[root@localhost ~]# ip route list
  default via 192.168.1.2 dev eth0 
  192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.4 
  192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.5 

Похоже, был выбран только один маршрут по умолчанию - из eth0 по любой причине (я не знаю, но я предполагаю, потому что это NIC с меньшим номером), но с использованием шлюза .2. Возможно, потому что это было последнее заявление шлюза? Черт, если я знаю.

Давайте посмотрим, что ядро считает подходящим маршрутом для данного публичного адреса назначения, полученного из любого локального IP-адреса:

[root@localhost ~]# ip route get to 8.8.8.8 from 192.168.1.4
  8.8.8.8 from 192.168.1.4 via 192.168.1.2 dev eth0 
      cache 

[root@localhost ~]# ip route get to 8.8.8.8 from 192.168.1.5
  8.8.8.8 from 192.168.1.5 via 192.168.1.2 dev eth0 
      cache 

Как и следовало ожидать от «default ... dev eth0», пакеты, предназначенные для публичного IP-адреса, будут выходить из eth0.
Обратите внимание, что не имеет значения, какой IP-адрес источника.

Давайте проверим, чтобы быть уверенным, хотя!
Мы будем прослушивать и eth0, и eth1, пока пингуем с любого интерфейса и с любого адреса источника.
Сначала выполните пинг с использованием IP-адреса eth0 в качестве источника (.4):

[root@localhost ~]# tcpdump -ni eth0 'icmp' & tcpdump -ni eth1 'icmp' & ping -nc 3 -I 192.168.1.4 8.8.8.8 2>&1 > /dev/null ; sleep 4 ; pkill tcpdump
  [1] 2603
  [2] 2604
  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
  23:30:30.347429 IP 8.8.8.8 > 192.168.1.4: ICMP echo reply, id 2605, seq 1, length 64
  23:30:31.331631 IP 192.168.1.4 > 8.8.8.8: ICMP echo request, id 2605, seq 2, length 64
  23:30:31.350134 IP 8.8.8.8 > 192.168.1.4: ICMP echo reply, id 2605, seq 2, length 64
  23:30:32.333378 IP 192.168.1.4 > 8.8.8.8: ICMP echo request, id 2605, seq 3, length 64
  23:30:32.350145 IP 8.8.8.8 > 192.168.1.4: ICMP echo reply, id 2605, seq 3, length 64

  5 packets captured
  5 packets received by filter
  0 packets dropped by kernel

  0 packets captured
  0 packets received by filter
  0 packets dropped by kernel
  [1]-  Done                    tcpdump -ni eth0 'icmp'
  [2]+  Done                    tcpdump -ni eth1 'icmp'

Выглядит хорошо - в соответствии с нашей таблицей маршрутизации!
На eth1 (второе резюме) ничего не видно, как мы ожидали.
Теперь давайте пропингуем из источника .5 (принадлежащий eth1):

[root@localhost ~]# tcpdump -ni eth0 'icmp' & tcpdump -ni eth1 'icmp' & ping -nc 3 -I 192.168.1.5 8.8.8.8 2>&1 > /dev/null ; sleep 4 ; pkill tcpdump
  [1] 2609
  [2] 2610
  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
  23:32:31.284113 IP 8.8.8.8 > 192.168.1.5: ICMP echo reply, id 2611, seq 1, length 64
  23:32:32.269281 IP 192.168.1.5 > 8.8.8.8: ICMP echo request, id 2611, seq 2, length 64
  23:32:32.284493 IP 8.8.8.8 > 192.168.1.5: ICMP echo reply, id 2611, seq 2, length 64
  23:32:33.270735 IP 192.168.1.5 > 8.8.8.8: ICMP echo request, id 2611, seq 3, length 64
  23:32:33.286849 IP 8.8.8.8 > 192.168.1.5: ICMP echo reply, id 2611, seq 3, length 64

  5 packets captured
  5 packets received by filter
  0 packets dropped by kernel

  0 packets captured
  0 packets received by filter
  0 packets dropped by kernel
  [1]-  Done                    tcpdump -ni eth0 'icmp'
  [2]+  Done                    tcpdump -ni eth1 'icmp'

Посмотрите, как, хотя адрес источника пингов был установлен на IP-адрес eth1, пакеты оставили eth0?
Но !, мы можем указать ping из исходного интерфейса, а не из исходного адреса.
Указание eth0 работает так, как вы ожидаете (успех), но что-то интересное произойдет, если мы установим eth1 в качестве источника:

[root@localhost ~]# tcpdump -ni eth0 'icmp' & tcpdump -ni eth1 'icmp' & ping -nc 3 -I eth1 8.8.8.8 2>&1 > /dev/null ; sleep 4 ; pkill tcpdump
  [1] 2751
  [2] 2752
  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

... Что дает ?
ХОРОШО, мы только нюхаем ICMP трафик. Поскольку вне eth1 не существует никакого маршрута по умолчанию (или более конкретного маршрута к 8.8.8.8), предполагается, что пункт назначения существует в том же широковещательном домене.
Это означает, что он пытается получить MAC-адрес получателя, прежде чем он может даже создать пакет для отправки. Если он не может получить MAC-адрес, он не отправляет пакет:

[root@localhost ~]# tcpdump -eni eth1 'icmp or arp' & ping -nc 3 -I eth1 8.8.8.8 2>&1 > /dev/null ; sleep 10 ; pkill tcpdump 
  [5] 2759
  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
  00:00:26.075685 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
  00:00:26.075685 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
  00:00:27.075945 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
  00:00:27.075945 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
  00:00:27.075945 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
  00:00:28.077935 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
  00:00:28.077935 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
  00:00:28.077935 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28

(DNS-сервер Google, вероятно, не находится в вашей локальной сети, равно как и на моем.)

Хорошо, хорошо, хорошо.
Что теперь, если мы заменим маршрут по умолчанию с выхода eth0 на выход eth1?
Мы должны ожидать, что наша ситуация с подключением будет отражена, верно? :

[root@localhost ~]# ip ro
  default via 192.168.1.2 dev eth0 
  192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.4 
  192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.5 

[root@localhost ~]# ping -nc 3 -I eth0 8.8.8.8
  PING 8.8.8.8 (8.8.8.8) from 192.168.1.4 eth0: 56(84) bytes of data.
  64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=17.5 ms
  64 bytes from 8.8.8.8: icmp_seq=2 ttl=54 time=15.9 ms
  64 bytes from 8.8.8.8: icmp_seq=3 ttl=54 time=15.5 ms
  --- 8.8.8.8 ping statistics ---
  3 packets transmitted, 3 received, 0% packet loss, time 2002ms
  rtt min/avg/max/mdev = 15.547/16.331/17.526/0.864 ms

[root@localhost ~]# ping -nc 3 -I eth1 8.8.8.8
  PING 8.8.8.8 (8.8.8.8) from 192.168.1.5 eth1: 56(84) bytes of data.
  From 192.168.1.5 icmp_seq=1 Destination Host Unreachable
  From 192.168.1.5 icmp_seq=2 Destination Host Unreachable
  From 192.168.1.5 icmp_seq=3 Destination Host Unreachable
  --- 8.8.8.8 ping statistics ---
  3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 1999ms
  pipe 3

[root@localhost ~]# ip route replace default via 192.168.1.1 dev eth1 

[root@localhost ~]# ip ro
  default via 192.168.1.1 dev eth1 
  192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.4 
  192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.5 

[root@localhost ~]# ping -nc 3 -I eth0 8.8.8.8
  PING 8.8.8.8 (8.8.8.8) from 192.168.1.4 eth0: 56(84) bytes of data.
  From 192.168.1.4 icmp_seq=1 Destination Host Unreachable
  From 192.168.1.4 icmp_seq=2 Destination Host Unreachable
  From 192.168.1.4 icmp_seq=3 Destination Host Unreachable
  --- 8.8.8.8 ping statistics ---
  3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 1999ms
  pipe 3

[root@localhost ~]# ping -nc 3 -I eth1 8.8.8.8
  PING 8.8.8.8 (8.8.8.8) from 192.168.1.5 eth1: 56(84) bytes of data.
  64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=14.7 ms
  64 bytes from 8.8.8.8: icmp_seq=2 ttl=54 time=18.8 ms
  64 bytes from 8.8.8.8: icmp_seq=3 ttl=54 time=21.0 ms
  --- 8.8.8.8 ping statistics ---
  3 packets transmitted, 3 received, 0% packet loss, time 2003ms
  rtt min/avg/max/mdev = 14.760/18.216/21.010/2.596 ms

И так оно и есть! Теперь eth0 не может достичь ничего, кроме eth1.

Предполагая, что вы хотите, чтобы оба интерфейса "просто работали", давайте пойдем по пути безумия, которое балансирует нагрузку ...:

[root@localhost ~]# ip route delete default

[root@localhost ~]# ip route add default scope global nexthop via 192.168.1.2 dev eth0 weight 1 nexthop via 192.168.1.1 dev eth1 weight 1

[root@localhost ~]# ip ro
  default 
          nexthop via 192.168.1.2  dev eth0 weight 1
          nexthop via 192.168.1.1  dev eth1 weight 1
  192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.4 
  192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.5 

Но работает ли это?

[root@localhost ~]# ping -nc 3 -I eth0 8.8.8.8
  PING 8.8.8.8 (8.8.8.8) from 192.168.1.4 eth0: 56(84) bytes of data.
  64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=17.9 ms
  64 bytes from 8.8.8.8: icmp_seq=2 ttl=54 time=16.2 ms
  64 bytes from 8.8.8.8: icmp_seq=3 ttl=54 time=17.4 ms
  --- 8.8.8.8 ping statistics ---
  3 packets transmitted, 3 received, 0% packet loss, time 2003ms
  rtt min/avg/max/mdev = 16.281/17.238/17.986/0.727 ms

[root@localhost ~]# ping -nc 3 -I eth1 8.8.8.8
  PING 8.8.8.8 (8.8.8.8) from 192.168.1.5 eth1: 56(84) bytes of data.
  64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=16.6 ms
  64 bytes from 8.8.8.8: icmp_seq=2 ttl=54 time=17.3 ms
  64 bytes from 8.8.8.8: icmp_seq=3 ttl=54 time=26.0 ms
  --- 8.8.8.8 ping statistics ---
  3 packets transmitted, 3 received, 0% packet loss, time 2003ms
  rtt min/avg/max/mdev = 16.612/20.025/26.091/4.300 ms

Huzzah!

... Хотя, даже я немного удивлен.
Ваш собственный пробег может варьироваться. Я бы посоветовал против этого безумия.

В моем тестировании дела идут не так, как надо при попытке добраться до пунктов назначения в локальной подсети.
Это связано с тем, что при обычном использовании системы (т. Е. Без явного указания интерфейса выхода) выбирается один интерфейс.
Например, если я пингую несуществующий хост (.17) в подсети, запросы ARP отправляются только по eth0.
Таким образом , в теории , если хозяин существовал от eth1, будет ARP даже работать?
Скорее всего нет:

[root@localhost ~]# ping 192.168.1.17
  PING 192.168.1.17 (192.168.1.17) 56(84) bytes of data.
  From 192.168.1.4 icmp_seq=1 Destination Host Unreachable
  From 192.168.1.4 icmp_seq=2 Destination Host Unreachable
  From 192.168.1.4 icmp_seq=3 Destination Host Unreachable
  ...

[root@localhost ~]# tcpdump -eni eth0 'arp'
  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
  00:25:29.167575 08:00:27:f6:8f:c2 > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.17 tell 192.168.1.4, length 28
  00:25:30.168001 08:00:27:f6:8f:c2 > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.17 tell 192.168.1.4, length 28
  00:25:31.169967 08:00:27:f6:8f:c2 > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.17 tell 192.168.1.4, length 28
  ...

[root@localhost ~]# tcpdump -eni eth1 'arp'
  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes



  ^C
  0 packets captured
  0 packets received by filter
  0 packets dropped by kernel

Приветствия.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .