Два мережевих інтерфейси та два IP-адреси в одній підмережі в Linux


22

Нещодавно я зіткнувся з ситуацією, коли мені були потрібні два IP-адреси в одній підмережі, призначені одному хосту Linux, щоб ми могли запустити два SSL / TLS-сайти. Першим моїм підходом було використання псевдоніму IP, наприклад, використання eth0: 0, eth0: 1 і т. Д., Але наші адміністратори мережі мають досить суворі налаштування щодо безпеки, що розчарувало цю ідею:

  1. Вони використовують прослуховування DHCP і зазвичай не дозволяють статичні IP-адреси. Статична адресація здійснюється за допомогою статичних записів DHCP, тому та сама MAC-адреса завжди отримує однакове призначення IP-адреси. Цю функцію можна відключити за кожен комутаційний порт, якщо ви запитаєте, і у вас є причина для цього (на щастя, у мене хороші стосунки з хлопцями мережі, і це не важко зробити).
  2. Оскільки відключення DHCP на комутаційному порталі було вимкнено, вони повинні були встановити правило про комутатор, згідно з яким у MAC-адреси X дозволено мати IP-адресу Y. На жаль, це побічно вплинуло також і на те, що MAC-адреса X ТОЛЬКО дозволяється мати IP-адреса Y. Псевдонім IP вимагав, щоб MAC-адресу X було призначено два IP-адреси, тому це не спрацювало.

Можливо, у конфігурації комутатора було вирішено ці проблеми, але намагаючись зберегти добрі стосунки з адміністраторами мережі, я намагався знайти інший шлях. Наявність двох мережевих інтерфейсів здавалося наступним логічним кроком. На щастя, ця система Linux є віртуальною машиною, тому мені вдалося легко додати другий мережевий інтерфейс (без перезавантаження, я можу додати - досить круто). Кілька натискань клавіш пізніше у мене було запущено і запущено два мережеві інтерфейси, і обидва витягнули IP-адреси з DHCP.

Але тоді виникла проблема: мережеві адміністратори могли бачити (на комутаторі) запис ARP для обох інтерфейсів, але лише перший мережевий інтерфейс, який я вивів, відповів би на ping або будь-який трафік TCP або UDP.

Після багатьох копань та ривок, ось що я придумав. Це, здається, працює, але також здається, що багато працювати над тим, що здається, що це повинно бути простим. Якісь альтернативні ідеї там?


Крок 1. Увімкніть фільтрацію ARP на всіх інтерфейсах:

# sysctl -w net.ipv4.conf.all.arp_filter=1
# echo "net.ipv4.conf.all.arp_filter = 1" >> /etc/sysctl.conf

З файлової мережі / ip-sysctl.txt у документах ядра Linux:

arp_filter - BOOLEAN
    1 - Allows you to have multiple network interfaces on the same
    subnet, and have the ARPs for each interface be answered
    based on whether or not the kernel would route a packet from
    the ARP'd IP out that interface (therefore you must use source
    based routing for this to work). In other words it allows control
    of which cards (usually 1) will respond to an arp request.

    0 - (default) The kernel can respond to arp requests with addresses
    from other interfaces. This may seem wrong but it usually makes
    sense, because it increases the chance of successful communication.
    IP addresses are owned by the complete host on Linux, not by
    particular interfaces. Only for more complex setups like load-
    balancing, does this behaviour cause problems.

    arp_filter for the interface will be enabled if at least one of
    conf/{all,interface}/arp_filter is set to TRUE,
    it will be disabled otherwise

Крок 2: Реалізація маршрутизації на основі джерела

Я в основному просто дотримувався вказівок з http://lartc.org/howto/lartc.rpdb.multiple-links.html , хоча ця сторінка була написана з іншою метою (маючи справу з двома провайдерами).

Припустимо, що підмережа - 10.0.0.0/24, шлюз - 10.0.0.1, IP-адреса для eth0 - 10.0.0.100, а IP-адреса для eth1 - 10.0.0.101.

Визначте дві нові таблиці маршрутизації під назвою eth0 та eth1 в / etc / iproute2 / rt_tables:

... top of file omitted ...
1    eth0
2    eth1

Визначте маршрути для цих двох таблиць:

# ip route add default via 10.0.0.1 table eth0
# ip route add default via 10.0.0.1 table eth1
# ip route add 10.0.0.0/24 dev eth0 src 10.0.0.100 table eth0
# ip route add 10.0.0.0/24 dev eth1 src 10.0.0.101 table eth1

Визначте правила, коли використовувати нові таблиці маршрутизації:

# ip rule add from 10.0.0.100 table eth0
# ip rule add from 10.0.0.101 table eth1

Про головну таблицю маршрутизації вже подбав DHCP (і навіть не ясно, що в цьому випадку це вкрай необхідно), але це в основному прирівнюється до цього:

# ip route add default via 10.0.0.1 dev eth0
# ip route add 130.127.48.0/23 dev eth0 src 10.0.0.100
# ip route add 130.127.48.0/23 dev eth1 src 10.0.0.101

І вуаля! Здається, все працює чудово. Надсилання пінг-файлів на обидва IP-адреси працює чудово. Відправлення пінг-файлів із цієї системи на інші системи та змушення пінг-файлу використовувати певний інтерфейс працює добре ( ping -I eth0 10.0.0.1, ping -I eth1 10.0.0.1). І найголовніше, що весь трафік TCP та UDP до / з будь-якої IP-адреси працює як очікується.


Отже, знову моє запитання: чи є кращий спосіб зробити це? Це здається великою роботою для, здавалося б, простої проблеми.


Оновлення: рішення вище закінчилося неповним. Все працювало нормально, якби трафік залишався в одній підмережі, але зв’язок з іншими підмережами, що використовують другий інтерфейс, не працював належним чином. Замість того, щоб викопати більшу яму, я закінчив розмову з адміністраторами мережі та отримав їх, щоб дозволити декілька IP-адрес для одного інтерфейсу та застосував псевдонім IP (наприклад, eth0 та eth0: 0).


Ключова відмінність, яку слід пам’ятати, це те, що IP не належить до інтерфейсу, він належить машині. Тож правильно в цій установці надсилати будь-який інтерфейс для будь-якого IP-адреси, отже, для цього потрібна певна хитрість не робити.
MikeyB

Я вважаю, що маршрутизація джерела в цьому випадку не потрібна, оскільки фільтрація арп повинна застосовуватися лише тоді, коли комутатор надсилає інтерфейс / повинен знайти його серед своїх портів. Я можу помилятися, але коли машина надсилає дані до комутатора, IP-адреса у вихідному полі (IP-заголовок) не перевіряється, а лише арп, що надсилає пакет.
AndreasM

MikeyB правильний, маршрутизація джерела - єдиний спосіб. Машина може вибрати будь-який вихідний інтерфейс, на який хоче відправляти трафік, доки він знаходиться в одній підмережі. Не має значення, чи справді IP знаходиться на цьому інтерфейсі чи ні.
Патрік

2
AndreasM: Проблема, яка входить, не проблема, це проблеми, що стосуються вихідних пакетів. Без маршрутизації джерела всі вихідні пакети будуть використовувати маршрут за замовчуванням, який пов'язаний з одним або іншим інтерфейсом. Незважаючи на те, що вихідні пакети матимуть правильну IP-адресу джерела, фільтри на комутаторі не дозволять їм виходити, оскільки ця IP-адреса не належить до MAC-адреси цього інтерфейсу. Для комутатора це виглядає так, що клієнт намагається підробити IP іншого клієнта. (Це розумні перемикачі 3 рівня).
Скотт Дакворт

Псевдоніки IP застарілі і злому, не відображають реальності, не кажучи вже про те, що зняття первинних зніме всі псевдоніми. Використовуйте ipз, iproute2щоб додати до одного інтерфейсу більше однієї адреси.
пілона

Відповіді:


8

Так, кращий спосіб - створити належний бізнес-кейс і дозволити їм послабити правила на комутаторах, щоб у вас було декілька IP-адрес на одному NIC.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.