Прив’яжіть програму Unix до конкретного мережевого інтерфейсу


40

Питання: Як запустити програму, гарантуючи, що її доступ до мережі обмежений через певний мережевий інтерфейс?

Випадок: я хочу отримати доступ до двох машин, що мають однаковий IP (192.168.1.1), але доступних через два різні мережеві інтерфейси (eth1 та eth2).

Приклад:

net-bind -D eth1 -exec {Program 192.168.1.1}
net-bind -D eth2 -exec {Program 192.168.1.1}

Сказане вище - це наближення того, що я хотів би, натхненний апаратним зв'язуванням, зробленим через primusrun та optirun .

Завдання: Як пропонується у відповідному потоці , використовувані інтерфейси вибирає не програма, а ядро ​​(звідси синтаксис попереднього зв’язування у наведеному вище прикладі).

Я знайшов відповідні рішення, які є незадовільними. Вони ґрунтуються на прив'язуванні мережевих інтерфейсів через специфічний для користувача мережевий чорний список; тобто запуск процесу як користувач, який може отримати доступ лише до одного певного мережевого інтерфейсу.


Ви маєте на увазі, що ваш апарат підключений до двох різних мереж, обох 192.168.1.0? Як виглядає ваша таблиця маршрутизації? Якщо ви хочете обмежити інтерфейси, видимі в процесі, найлегшим рішенням будуть групи, більш важкі контейнери.
lgeorget

Так, дві різні мережі, обидві в одному і тому ж діапазоні IP. Я не впевнений, що я не хочу обмежувати видимі інтерфейси, просто диктую, який з них використовувати як за замовчуванням? :)
Skeen

3
Те, що ви запитуєте, важко з однієї вагомої причини: мати дві мережі, пов’язані між собою за допомогою одного і того ж IP домену, це як ліфт у будівлі з двома поверхами з однаковим номером. Діапазон IP - це те, що ідентифікує домен, а не вихідний інтерфейс. Тим не менш, повинен бути спосіб обійти ваш недосконалий дизайн мережі за допомогою iptables.
lgeorget

Я підключаю свою систему до двох різних локальних інфраструктур, оскільки такі інфраструктури ніколи не були розроблені для взаємодії, а отже, дизайн мережі є недоліком у цьому плані.
Skeen

1
Мій аргумент щодо NATs полягав у тому, що цілі простори адрес зазвичай приховані за NAT, і коли я з'єдную дві NAT'ted інфраструктури, відбувається зіткнення. - Я не в змозі змінювати інфраструктуру. - Я намагався використовувати простори мереж імен з парами віртуальних мережевих інтерфейсів (один у просторі імен, один у кореневому просторі імен), з'єднавши простір імен кореня у фізичний інтерфейс, та запустивши програми у просторі мереж імен. - Це, здається, працює, але я не отримую доступу за межами кореневого простору імен (тобто немає доступу поза межами самої машини).
Скін

Відповіді:


35

Для Linux на це вже відповіли Superuser - Як використовувати різні мережеві інтерфейси для різних процесів? .

Найпопулярніша відповідь використовує LD_PRELOADхитрість змінити прив’язку до мережі для програми, але сучасні ядра підтримують набагато більш гнучку функцію під назвою "простори мережних імен", яка відкривається через ipпрограму. Ця відповідь показує, як це використовувати. З власних експериментів я зробив наступне (як корінь):

# Add a new namespace called test_ns
ip netns add test_ns

# Set test to use eth0, after this point eth0 is not usable by programs
# outside the namespace
ip link set eth0 netns test_ns

# Bring up eth0 inside test_ns
ip netns exec test_ns ip link set eth0 up

# Use dhcp to get an ipv4 address for eth0
ip netns exec test_ns dhclient eth0

# Ping google from inside the namespace
ip netns exec test_ns ping www.google.co.uk

Також можна певною мірою керувати просторами мереж імен за допомогою команд unshareі nsenter. Це дозволяє також створювати окремі пробіли для PID, користувачів та точок монтування. Для отримання додаткової інформації див:


"після цього пункт eth0 не може бути використаний програмами поза простором імен" - Отже, я перериваю з'єднання для всіх інших проблем у цьому?
Скін

1
@Skeen, так, імовірно, ви б натиснути інтерфейс, який жодна інша програма не використовує у просторі імен, а ваш основний використовується нормально.
Graeme

1
@Graerne; Обидва інтерфейси активно використовуються; Я не можу дозволити собі знімати інтерфейси.
Скін

і що з шлюзом за замовчуванням? wvdialнаприклад, здається, що це взагалі не встановлюється ... тому його потрібно визначити в самому просторі імен
Flash Thunder

Чи можете ви включити інструкції, як скасувати це? Ти просто ip netns remove test_nsповернешся до нормального? Або вам потрібно зробити щось особливе?
Multihunter

17

Я приймаю відповідь Греме; це просто подальше пояснення для пояснення змін, які я вніс на його пропозицію вирішити свою проблему.

Замість того, щоб прив'язувати фізичний інтерфейс всередині простору імен, я створив пару віртуальних мережевих інтерфейсів з одним кінцем у просторі мереж імен та одним у корені. Потім пакети направляються через цю віртуальну мережу з простору імен, до кореневого простору імен, а потім до фізичного інтерфейсу. - Як такий, я можу запускати всі мої звичайні передачі даних, а крім того, запускаю процеси, які можуть отримати доступ лише до певного інтерфейсу.

# Create the eth0 network namespace
ip netns add eth0_ns

# Create the virtual network pair
ip link add v_eth0a type veth peer name v_eth0b

# Move v_eth0a to the eth0_ns namespace, the virtual pair is now split
# between two network namespaces.
ip link set v_eth0a netns eth0_ns

# Configure the ends of the virtual network pairs
ip netns exec eth0_ns ifconfig v_eth0a up {{NAMESPACE_IP}} netmask {{NAMESPACE_NETMASK}}
ifconfig v_eth0b up {{ROOT_NS_IP}} netmask {{ROOT_NS_NETMASK}}

# Setup routing from namespace to root
ip netns exec eth0_ns route add default gw {{ROOT_NS_IP}} dev v_eth0a

# Setup IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s {{ROUTE_SOURCE}}/24 -o {{NETWORK_INTERFACE}} -j SNAT --to-source {{ROUTE_TARGET}}

Після встановлення інтерфейсів для eth0 та eth1, з відповідними просторами імен eth0_ns та eth1_ns, програми можуть виконуватися на зазначеному інтерфейсі через;

ip netns exec eth0_ns fish
ip netns exec eth1_ns fish

4
Молодці! Я думаю, ви також можете створити мостовий пристрій та з'єднати простір імен за замовчуванням та віртуальну пару з одним із фізичних пристроїв. Це виглядає рівнозначно.
Graeme

1
Я намагався з'єднати віртуальний та фізичний пристрій; Я не зміг вийти на зовнішню мережу за допомогою цього рішення.
Скін

2
Я це зробив, але тільки з нового простору імен. Я думаю, що питання, яке у мене виникло, було пов'язане з мережевим менеджером, я не з'ясував це, хоч би я оновив свою відповідь.
Graeme

У мене те саме питання, але я не зміг використати це рішення. Що саме потрібно ввести {{ROUTE_SOURCE}} та {{ROUTE_TARGET}} на останньому кроці?
litov

@Graeme, принаймні , на Ubuntu я був в змозі отримати підключення назад в обох імен, а також глобальний простір імен шляхом розміщення dhclient <bridge>на тут .
Кріс Хант

4

Рішення I: Попередня завантаження певної бібліотеки

  • App-Route-Jail : використовуйте ld_preload, щоб змусити шлюз інтерфейсу (відмінна ідея, але вимагають можливості root або позначок) використання детально описано нижче.

  • Proxybound : використовуйте ld_preload, щоб примусити проксі до певної програми (для цього використовується проксі замість інтерфейсу)

  • Примусовий зв'язок : має багато функцій, але витоки прив'язки (не надійні)

  • Bind-Interface-IP : занадто прості та герметичні з'єднання (не надійно)

  • Bind-IP : занадто прості і герметичні з'єднання (не надійно)

Рішення II: Простір користувачів Linux

  • Класичний користувацький простір linux ip-netns : відмінне рішення, але вимагають root та інтерфейс можуть існувати лише в одному просторі користувача

  • Firejail : Firejail може змусити програму використовувати певну мережу, але сумісність обмежена (наприклад, вона не сумісна з інтерфейсами tun). firejail не потребує корінняfirejail --dns=8.8.8.8 --noprofile --net=eth0 --ip=192.168.1.1 app-command

  • Firejail з мережами : Firejail може змусити програму використовувати певний користувальницький простір, який був створений окремо;firejail --dns=8.8.8.8 --noprofile --netns=nameOfyourNS app-command

  • Firejail з маскарадом і мостом : Firejail може змусити програму використовувати специфічний інтерфейс з iptables маскарадом , це чудово і не вимагає root, але це вимагає ip_forward і може означати вплив на безпекуfirejail --net=br0 firefox

Рішення III: iptables Linux

Iptables можуть бути використані для цієї мети, але для цього потрібен ip_forward і може означати вплив безпеки, якщо його неправильно налаштовано, приклад 1 , приклад 2 , приклад 3 , приклад 4

Примітки щодо рішень (I, II та III):

Дротяник

Якщо ви використовуєте VPN (особливо провідний захист) і хочете застосувати це рішення до інтерфейсу провідного захисту ( проводка з користувальницьким простором ), ви можете дотримуватися пов'язаних інструкцій для створення користувальницького простору, що містить інтерфейс wg (і таким чином обмежується інтерфейсом vpn ) також це може поєднуватися з тим, firejail --netns=containerщоб мати можливість використовувати користувальницький простір без root.

Як знайти шлюз інтерфейсу

Існує багато рішень, щоб знайти шлюз. Ось кілька команд, які дозволяють знайти використаний шлюз

$ route
$ route -n
$ ip rule list
$ ip route show
$ netstat -rn
$ cat /etc/network/interfaces
$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
$ traceroute www.google.com
$ ip route show 0.0.0.0/0 dev eth0

Як користуватися App-Route-Jail

  • Побудувати додаток-маршрут-в'язницю
git clone https://github.com/Intika-Linux-Network/App-Route-Jail.git
cd Approute-Utils
chown 755 make.sh
./make.sh
  • Додавання маршруту до майбутніх позначених пакетів (для в'язного додатка) у цьому прикладі 192.168.1.1використовується як вимушений шлюз, це правило маршруту не вплине на інші програми, цю маніпуляцію потрібно робити лише один раз при завантаженні системи, наприклад, якщо ви хочете використовувати цей розчин щодня
ip rule add fwmark 10 table 100
ip route add default via 192.168.1.1 table 100
  • Запустіть програму, яку ви хочете ув’язнити
MARK=10 LD_PRELOAD=./mark.so firefox
  • Тестування wan IP-адреси
MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.