У меня есть Linux-бокс с 9 сетевыми адаптерами, и я хочу, чтобы восемь из них имели уникальные адреса в одной подсети, например:
ifconfig eth1 192.168.123.1 netmask 255.255.0.0
ifconfig eth2 192.168.123.2 netmask 255.255.0.0
ifconfig eth3 192.168.123.3 netmask 255.255.0.0
...
ifconfig eth8 192.168.123.8 netmask 255.255.0.0
Поведение ARP по умолчанию в этом случае крайне контрпродуктивно, поскольку в результате весь трафик для всех IP-адресов проходит исключительно через eth1
, что в значительной степени прямо противоположно тому, что я хочу.
Итак, я порылся и в итоге внес некоторые изменения в sysctl, например:
net.ipv4.conf.all.arp_filter=1
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
Это помешало eth1
выдавать себя за всех остальных, но я все еще не могу пинговать ничего, кроме eth1
адрес успешно. (например, со второго компьютера на том же коммутаторе, только 192.168.123.1
отвечает на пинг)
Я предполагаю, что мне нужно что-то сделать с arptables или iproute или ЧТО-ТО, но я потерялся в море в этом поле.
Бонусные баллы: Решение должно быть совместимо с Linux 2.6.27.27. (В частности, Slax 6.1.2)
Ты нуждаешься в модель сильной конечной системы. Linux в основном построен на модели слабой системы отправки, так что это действительно не лучший выбор ОС для этого приложения.
Вам придется подделывать все, что вам нужно, от ARP до маршрутизации политики и выбора адреса источника. Вам также понадобятся фильтры для предотвращения приема пакетов, если они прибывают на неправильный интерфейс.
Определенно необходимые шаги:
Настройте arp_filter = 1 и arp_ignore = 2 на всех интерфейсах.
Добавьте для каждого интерфейса маршрутизацию исходящего трафика на основе источника. (Интерфейс назначения должен быть выбран на основе адреса источника.)
Добавьте фильтрацию входящего трафика для каждого интерфейса, чтобы автоматически отбрасывать пакеты, полученные на неправильном интерфейсе. (Пакеты с адресом назначения, назначенным другому интерфейсу.)
К сожалению, нет единого мнения о том, достаточно ли этих трех шагов. Модель слабой конечной системы встроена во весь стек TCP / IP Linux, и неясно, что может пойти не так с такими тонкими проблемами, как многоадресная рассылка.
Непонятно, например, как выбрать выходной интерфейс для трансляций. Должен ли он погаснуть всех? Может быть. Каково правильное поведение, если стек получает исходящую широковещательную рассылку с исходным адресом, не назначенным ни одному из интерфейсов?
Опять же, вы выбрали неправильный инструмент для работы.
Скорее всего, вы захотите создать мост с интерфейсами 8/9, а затем назначить этому мосту IP-адрес (пакет bridge-utils, команда 'brctl add').
Таким образом, мост будет действовать как коммутатор и может иметь IP-адрес в вашей подсети.
Похоже, вам нужна тестовая среда, эквивалентная 9 отдельным машинам, и вы полагали, что 9 интерфейсов на одной машине могут это эмулировать. В Linux это просто невозможно сделать через один стек по причинам, описанным Дэвидом Шварцем. БТДТ и есть шрамы. С двумя интерфейсами было достаточно плохо.
Лучшим решением может быть запуск 8 или 9 дискретных виртуальных машин на одном хосте и соединение 8 или 9 интерфейсов с этими виртуальными машинами.
Я бы рекомендовал связать физические интерфейсы, а затем настроить все адреса на едином связанном интерфейсе.
Вам также понадобится поддержка на коммутаторе.
Вот мини-учебник которую вы можете использовать для начала.
Да, это возможно после предложения Дэвида Шварца:
echo -ne 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo -ne 0 > /proc/sys/net/ipv4/conf/eth0/rp_filter
echo -ne 0 > /proc/sys/net/ipv4/conf/eth3/rp_filter
// Для правильной работы, т.е. ARP-ответы от eth1 для генерации, когда и eth0, и eth1 находятся в одной подсети
echo -ne 0 > /proc/sys/net/ipv4/conf/all/arp_filter
echo -ne 2 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo -ne 0 > /proc/sys/net/ipv4/conf/eth0/arp_filter
echo -ne 2 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
echo -ne 0 > /proc/sys/net/ipv4/conf/eth1/arp_filter
echo -ne 2 > /proc/sys/net/ipv4/conf/eth1/arp_ignore
//Create a table called "new_rt_table" and create a routing rule that says any packet with a mark equal to '1' gets routed according to the "new_rt_table"(can name it whatever you want) table. The file /etc/iproute2/rt_tables is the only source of table names on the system. Internally, routing tables have integer identifiers.
echo 1 new_rt_table >> /etc/iproute2/rt_tables
ip rule add from all fwmark 1 table new_rt_table
// настраиваем таблицу new_rt_table для маршрутизации пакетов через eth1
ip route add default dev eth1 table new_rt_table
ip route show table new_rt_table
// помечаем пакеты, чтобы 'ip route' мог маршрутизировать их через eth1
iptables -F -t mangle
iptables -t mangle -I OUTPUT -s <ip addr of eth1> -o eth0 -j MARK --set-mark 1
// включить поддержку нескольких таблиц маршрутизации в конфигурации ядра.
Конфигурация ядра
→ Поддержка сети → Параметры сети
[*] IP: расширенный роутер
[*] IP: политика маршрутизации
CONFIG_IP_ADVANCED_ROUTER
CONFIG_IP_MULTIPLE_TABLES
// вышеуказанные шаги перенаправляют пакеты, предназначенные для вывода из eth0, для правильного выхода из eth1.
Пожалуйста, предложите любые другие методы, если у кого-то это сработает.