Привет, сетевые гуру!
У меня есть сервер Linux (ядро 3.14), который действует как сервер TFTP, NFS и HTTP для фермы устройств бытовой электроники (телеприставки - STB). Устройства используют TFTP для загрузки своих ядер, затем монтируют свои корневые файловые системы с сервера NFS на нашем компьютере и т. Д.
Теперь, по одной эзотерической технической причине, я не собираюсь здесь углубляться (просто поверьте мне :), каждая STB должна быть в своей собственной, физически отдельной LAN. Итак, способ организации сети ATM:
На сервере есть 1 сетевая карта, которая используется для доступа к остальному миру. Он также имеет по 1 сетевой карте для каждой обслуживаемой приставки - и каждая из них подключена к небольшому маршрутизатору, к которому приставка + некоторые другие устройства подключены и образуют локальную сеть.
В настоящее время подключено 3 STB, а локальные сети - 172.16.50.0/24, 172.16.51.0/24 и 172.16.52.0/24. Все работает хорошо.
Однако: тот факт, что у нас есть 3 разных LAN, означает, что к одному и тому же серверу должен быть доступ как 172.16.50.1 из STB1, 172.16.51.1 из STB2 и 172.16.52.1 из STB3 - и это означает, что у нас немного другая среда на каждой STB и каждый раз, когда мы, скажем, загружаем новую RootFS для использования на STB, нам нужно вручную отредактировать некоторый файл конфигурации и указать правильный IP-адрес, к которому должен быть доступ к серверу с этой конкретной STB. Не очень удобно и подвержено ошибкам!
Это заставило меня задуматься: а что, если мы просто настроим все три локальные сети на одинаковые 172.16.50.0/24? С точки зрения STB (и остальных устройств в локальной сети) все должно быть в порядке, но как насчет точки зрения сервера?
Может ли сервер Linux иметь N разных интерфейсов Ethernet, настроенных с одним и тем же статическим IP-адресом, но каждый из которых подключен к физически отдельной локальной сети?
Да, это возможно, используя замечательную функцию под названием network namespaces
(видеть man ip-netns(8)
). По сути, он дает вам несколько различных сетевых стеков, каждый со своим собственным набором интерфейсов, маршрутов и т. Д.
Вам нужно будет создать пространство имен для каждого из ваших STB, а затем можно будет запускать необходимые службы отдельно в каждом пространстве имен.
Для пространств имен вам нужно будет действовать следующим образом:
Создайте пространство имен с именем net1
:
ip netns add net1
Назначьте свой интерфейс ethX
в новое пространство имен и настройте свой IP-адрес 172.16.50.1:
ip link set dev ethX netns net1
ip netns exec net1 ip link set dev ethX up
ip netns exec net1 ip address add 172.16.50.1/24 dev ethX
IP-адрес 172.16.50.1 теперь не отображается из вашего пространства имен по умолчанию. Простой ping 172.16.50.1
не работает, сначала нужно переключиться на net1
пространство имен и выполните там команду:
ip netns exec net1 <command>
Таким образом, теперь вы можете запускать каждую службу в каждом из ваших пространств имен.
Если вы любите приключения, вы можете даже попытаться каким-то образом перенаправить все запросы от ваших STB на центральную службу. Для этого вам понадобится туннель из каждого пространства имен в пространство имен по умолчанию (см. ip link help veth
) и немного магии iptables ...
Технически можно, но конфигурация будет красочной. Это будет кладж, и для удовлетворения ваших требований каждый STB должен иметь уникальный IP-адрес, будучи изолированным на собственном проводе. Конфигурация на клиентах не меняется. Вот конфиг на сервере:
ifconfig eth0 10.0.50.1 netmask 255.0.0.0
route del -net 10.0.0.0 netmask 255.0.0.0 dev eth0
route add 10.0.50.2 dev eth0
ifconfig eth1 10.0.50.1 netmask 255.0.0.0
route del -net 10.0.0.0 netmask 255.0.0.0 dev eth1
route add 10.0.50.3 dev eth1
# ...
Это должно привести к тому, что в таблице маршрутизации будет только один IP-адрес для каждого интерфейса. Они находятся на отдельных проводах, поэтому перекрестные помехи отсутствуют. Каждое из этих устройств будет думать, что они находятся на 2 узлах 10.0.0.0/8.
Когда сервер хочет связаться с 10.0.50.2, он просматривает таблицу ARP, а затем таблицу маршрутизации. Если таблица ARP пуста, таблица маршрутизации сообщает ей об отправке запроса ARP на соответствующий интерфейс, поэтому они ДОЛЖНЫ иметь уникальные IP-адреса, иначе сервер сможет разговаривать только с последним добавленным маршрутом.
Вы можете настроить DHCP-сервер на назначение IP-адресов на основе аппаратных адресов или запускать отдельный динамический диапазон DHCP для каждого интерфейса. DHCP-сервер может передавать что угодно, но 10.0.50.3 на канале eth0 недоступен.
Вы не можете использовать один и тот же IP-адрес на нескольких интерфейсах. Он просто не будет работать должным образом (обычно он будет работать только на последнем интерфейсе, которому был назначен IP).
Вам необходимо поместить интерфейсы Ethernet в мост и назначить IP-адрес самому мосту.
По сути, все порты Ethernet в этом мосту будут работать как коммутаторы.
В качестве альтернативы вы можете удалить все карты Ethernet для каждого STB и просто добавить коммутатор (который более масштабируем, чем добавление новых карт Ethernet на ваш сервер).
Но поскольку существует требование, чтобы каждая STB находилась в собственном широковещательном домене, я боюсь, что вам нужно придерживаться своих текущих настроек.
Или, чтобы упростить хотя бы часть серверного оборудования в вашей настройке, откажитесь от нескольких карт Ethernet и просто добавьте управляемый коммутатор и используйте VLAN для имитации «нескольких карт Ethernet» с использованием только одной физической карты Ethernet.