Назад | Перейти на главную страницу

Совместное использование одного IP-адреса между двумя сетевыми адаптерами для маршрутизации одного IP-адреса через выделенный сетевой адаптер

У меня есть несколько хостов, подключенных к одному коммутатору, и все они находятся в одной подсети (10.0.0.0/16). Два из этих хостов имеют более быстрые сетевые интерфейсы, поэтому я соединил их вместе, что означает, что эти две машины теперь имеют прямую связь друг с другом без использования коммутатора.

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

Самый простой способ - настроить прямую ссылку на другую подсеть, однако тогда мне нужно будет использовать разные IP-адреса или имена хостов в зависимости от того, какой интерфейс использовать, и поскольку я хотел бы иметь возможность развертывать стандартные конфигурации на всех машинах. (например, монтирование NFS с использованием имен хостов) и не нужно поддерживать пользовательские переопределения IP в /etc/hosts, Я считаю, что это решение было бы слишком простым, если бы неправильно указать имя хоста и отправить трафик через неправильный интерфейс.

Я ищу способ сообщить двум машинам Linux, что даже если eth0 обрабатывает 10.0.0.0/16, когда вы хотите общаться с 10.0.0.5, даже если он находится в подсети eth0, отправляйте пакеты через eth1 вместо.

Я попытался добавить правило маршрутизации хоста с route add -host 10.0.0.5 dev eth1 который отправляет пакет на правильный интерфейс, однако он исходит с неправильного IP-адреса (подсеть прямого канала, а не исходная подсеть).

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

Или есть лучший и более надежный способ добиться этого?

РЕДАКТИРОВАТЬ: Вот дополнительная информация, запрошенная @ A.B:

$ ip -br link
lo               UNKNOWN        00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP> 
eth0             UP             ec:f4:xx:xx:xx:a4 <BROADCAST,MULTICAST,UP,LOWER_UP> 
eth1             UP             ec:f4:xx:xx:xx:a5 <BROADCAST,MULTICAST,UP,LOWER_UP> 

$ ip -br address
lo               UNKNOWN        127.0.0.1/8
eth0             UP             10.0.0.4/16
eth1             UP             10.0.99.4/24

$ ip route
default via 10.0.0.1 dev eth0 proto static 
10.0.0.0/16 dev eth0 proto kernel scope link src 10.0.0.4
10.0.0.5 dev eth1 scope link 
10.0.99.0/24 dev eth1 proto kernel scope link src 10.0.99.4

Настроил прямую ссылку (eth1) в отдельной подсети, а затем попробовал route в моем исходном посте, и вот где все сейчас. Похоже, мне нужно получить src атрибут установлен для моего прямого маршрута.

Поскольку 10.0.99.4 является частью 10.0.0.0/16, этого IP-адреса следует избегать. Иначе будет конфликт с фактическим адресом 10.0.99.4/16, даже на eth0 учитывая, что Linux использует Модель слабого хоста и будет отвечать по умолчанию на запросы ARP для этого IP-адреса также на eth0 для 10.0.99.4, создавая конфликты ARP. Не используйте конфликтующие IP-адреса.

очистка:

ip route flush dev eth1
ip address flush dev eth1

Стандартный метод с приклеиванием IP адресов

Давайте выберем два несвязанных адреса, которые будут использоваться двумя хостами. Они не должны конфликтовать ни с чем другим, используемым в вашей сети, но, поскольку они являются адресами точка-точка / 32, можно делать все, что угодно, они не будут использоваться как часть локальной сети, а будут использоваться только как точка-точка. точки / одноранговые адреса. Я произвольно использую 192.168.100.4/32 и 192.168.101.5/32. Если позже более 2 из этих хостов унаследуют более быстрый коммутатор и будут соединены вместе с помощью этого отдельного коммутатора, это можно немного изменить, и тогда снова будет проще разместить связанные IP-адреса в одном блоке.

конфигурация для хоста 10.0.0.4:

# /32 : no route gets created (beside the hidden *local* routing table)
ip address add 192.168.100.4/32 dev eth1 
# add the peer (point to point) route on the same link
ip route add 192.168.101.5/32 dev eth1

На самом деле две приведенные выше команды имеют ярлык, вы можете заменить их обе этой единственной командой ниже:

ip address add 192.168.100.4 peer 192.168.101.5/32 dev eth1

Теперь сообщите хосту, что для достижения 10.0.0.5/32 (что более конкретно, чем 10.0.0.0/16) существует маршрут, использующий IP-адрес однорангового узла, но предпочитая другой исходный IP-адрес чем то, что было бы выбрано по умолчанию (устаревшие route команда не может этого сделать):

ip route add 10.0.0.5/32 via 192.168.101.5 dev eth1 src 10.0.0.4

С этим вы получите:

# ip route get 10.0.0.5
10.0.0.5 via 192.168.101.5 dev eth1 src 10.0.0.4 uid 0 
    cache 

Есть один небольшой недостаток: IP-трансляции по-прежнему отправляются на eth0 и если Строгая пересылка по обратному пути активен (либо sysctl net.ipv4.conf.eth0.rp_filter или sysctl net.ipv4.conf.all.rp_filter дает 1, а не 0 или 2) эти широковещательные сообщения при отправке одноранговым узлом (например, при запуске на одноранговом хосте 10.0.0.5 что-то подобное echo test | socat udp4-datagram:10.0.255.255:5555,broadcast -) будет проигнорирован, потому что получен сейчас неправильно интерфейс. Поэтому, если вы используете протоколы, основанные на этом, и уже применяете Strict Reverse Path Forwarding, переключите eth0 в свободный режим при необходимости:

sysctl -w net.ipv4.conf.eth0.rp_filter=2

Эквивалентная конфигурация для хоста 10.0.0.5:

ip address add 192.168.101.5 peer 192.168.100.4/32 dev eth1
ip route add 10.0.0.4/32 via 192.168.100.4 dev eth1 src 10.0.0.5
sysctl -w net.ipv4.conf.eth0.rp_filter=2

Например, на подобном Debian если вверх interface файлы конфигурации вы можете использовать pointopoint ключевое слово и несколько up дополнительные команды для любой команды, не имеющей эквивалента конфигурации направления. (sysctl предпочел бы быть вставленным /etc/sysctl.d).

Упрощенный метод без дополнительных (или повторяющихся) IP-адресов

Фактически единственная роль 192.168.100.4 и 192.168.100.5 состоит в том, чтобы разрешить адреса канального уровня, чтобы узнать маршрут для 10.0.0.4 и 10.0.0.5: они используются как своего рода клей, который не играет никакой другой роли. Эти IP-адреса будут полностью невидимы, и ни один IP-пакет никогда не будет использовать 192.168.100.4 или 192.168.100.5 в своем содержимом (за исключением случаев, когда они явно используются), только запросы и ответы ARP будут. Нет необходимости использовать такие клеящие IP-адреса.

Например, хост-провайдер Хетцнер приводит пример:

ip route add 203.0.113.40/32 dev tap0

для достижения IP-адреса на интерфейсе без настройки IP-адреса на этом интерфейсе (при этом этот интерфейс не используется в качестве порта моста). В этом примере одноранговый узел tap0 (которое является устройством tun / tap в режиме Ethernet, подключенным к виртуальной машине на другой стороне) должно отвечать на запросы ARP для разрешения адресов канального уровня.

Но опять же по симметричным причинам ему не нужен IP-адрес, настроенный там, если он уже настроил его в другом месте, чтобы правильно ответить на запрос ARP, выполненный через eth1: это снова часть реализации Linux модели слабого хозяина.

Таким образом, это можно просто использовать для хоста 10.0.0.4, без привлечения какого-либо дополнительного IP-адреса, используя только одну команду:

ip route add 10.0.0.5/32 dev eth1

Или указать источник (чтобы избежать двусмысленности, если на хосте их больше одного):

ip route add 10.0.0.5/32 dev eth1 src 10.0.0.4

И для хоста 10.0.0.5:

ip route add 10.0.0.4/32 dev eth1 src 10.0.0.5

Для приема "медленных" трансляций на eth0 от партнера они по-прежнему требуют:

sysctl -w net.ipv4.conf.eth0.rp_filter=2

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


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