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


59

У мене на комп'ютері Linux два мережеві інтерфейси, і мені потрібно вручну встановити інтерфейс, який використовуватиме даний процес.

У програми (програмного забезпечення Twinkle) немає подібного варіанту, тому я вважаю, що її потрібно встановити зовні.

Як я можу це зробити?

Редагувати: Я не намагаюся змусити серверний процес прив'язуватися до певного інтерфейсу, а скоріше змусити клієнтську програму зв’язатися із сервером за допомогою певного інтерфейсу.


клієнти також використовують bind / connect, перегляньте документацію bind.c.txt про те, як змусити ircII (програму irc-клієнта) до заданого ip: 'Приклад в bash для використання вашого віртуального IP-адреси як вихідної адреси адреси для ircII: BIND_ADDR = "ваш-вирт-ф" LD_PRELOAD = / bind.so ircII.
Акіра

Тут я знайшов інший підхід, я сподіваюся, що це корисно (я сподіваюся, що описана маршрутизація політики ядра ввімкнена за замовчуванням сьогодні): kindlund.wordpress.com/2007/11/19/…
Савас Радевич,

Відповіді:


48

ви можете замінити код під час виконання за допомогою LD_PRELOAD (@Windows ви можете використовувати аналогічну техніку, звану об'їзди , досить фантазії). що потрібно зробити, це повідомити динамічний лінкер, щоб спочатку завантажити всі ваги в процес, який ви хочете запустити, а потім додати ще трохи на нього. ви зазвичай використовуєте його так:

% LD_PRELOAD=./mylib.so ls

і тим самим ви змінюєте те, що lsробить.

для вашої проблеми я б спробував http://www.ryde.net/code/bind.c.txt , який ви можете використовувати, як:

% BIND_ADDR="ip_of_ethX" LD_PRELOAD=./bind.so twinkle

ось як ви будуєте його:

% wget http://www.ryde.net/code/bind.c.txt -O bind.c
% gcc -nostartfiles -fpic -shared bind.c -o bind.so -ldl -D_GNU_SOURCE

більш тривалий посібник - http://daniel-lange.com/archives/53-Binding-applications-to-a-specific-IP.html

подібні хаки та інструменти:


7
Нічого собі, що за чорт. +1
sinni800

1
Привіт, це здається справді приємним трюком, але це не працює для мене. У мене є два 3G-модеми, які при підключенні відкривають два інтерфейси (ppp0 та ppp1). Якщо я спробую примусити один з двох IP-адрес, я завжди закінчую роботу з тим самим інтерфейсом (я бачу це, тому що у мене є два екземпляри дротів, по одному для кожного інтерфейсу). Я також видалив відбитки налагодження з bind.c, і я дійсно бачу, що "перевантажена" бібліотека завантажена, тому я не знаю, чому вона не працює.
Андреа Спадаччини

3
LD_PRELOAD ігнорується, якщо ваш ефективний UID не такий, як ваш реальний UID.
matthias krull

force_bindПроект Каталін М. Boie підтримує ipv6
BurnsBA

Працює чудово, але для успішної компіляції потрібно додати #include <arpa / inet.h>.
анно

31

ip netns може це зробити.

TL; DR: Створіть простори мережних імен, пов’яжіть з ними інтерфейси та запустіть "ip netns exec NAME cmd ..."

Просто перевірте, чи підтримує ваш дистрибутив ip netns ... (Backtrack 5r3 не робить, тоді як Kali так;))

БІЛЬШЕ ДЕТАЛІ:

#create netns
ip netns add myNamespace
#link iface to netns
ip link set eth0 netns myNamespace
#set ip address in namespace
ip netns exec myNamespace ifconfig eth0 192.168.0.10/24 up
#set loopback (may be needed by process run in this namespace)
ip netns exec myNamespace ifconfig lo 127.0.0.1/8 up
#set route in namespace
ip netns exec myNamespace route add default gw 192.168.0.1
#force firefox to run inside namespace (using eth0 as outgoing interface and the route)
ip netns exec myNamespace firefox

Чому це краще, ніж зв’язувати ip через LD_PRELOAD? Оскільки LD_PRELOAD не контролює маршрут, який використовуються процеси. Він використовуватиме перший маршрут.

А оскільки він завжди використовує той самий маршрут, він буде за замовчуванням інтерфейсом, зареєстрованим на маршруті. (Що не те, що ми хочемо)


2
Спробуйте додати більше деталей до своєї відповіді.
Ченгат Ренджу Чандран

4
не робіть цього на віддаленому сервері, якщо eth0 - інтерфейс загальнодоступної мережі ..
ygrek

1
останній рядок повинний бутиip netns exec myNamespace firefox
meuh

1
Використовуйте "sudo ip netns del <namespace-name>", щоб при необхідності видалити простір імен!
Едуардо Лусіо

1
@EduardoLucio слід виконати його так: sudo ip netns exec myNamespace su -u someUser -c firefox
olivervbk

2

Я не думаю, що неможливо змусити процес використовувати певний інтерфейс.

Однак я думаю, що ви, можливо, зможете пограти з ipchain / iptables і змусити певний порт, який ваш процес слухає, отримає лише пакети, що надходять через певний інтерфейс.

Корисне HOWTO: http://tldp.org/HOWTO/IPCHAINS-HOWTO.html


2
Дві вищі голосові докази доводять інше.
Пол Гір

2

На основі @olivervbk відповідь нижче моя!

Виконайте всі команди як "root".

Використовуйте команду ...

ip a

... щоб дізнатись назву мережевого інтерфейсу, який ви хочете використовувати.

Запустіть команди нижче як шаблон ...

ip netns add [INTERFACE_NAME]_ns
ip link set dev [INTERFACE_NAME] netns [INTERFACE_NAME]_ns
ip netns exec [INTERFACE_NAME]_ns ifconfig [INTERFACE_NAME] 10.1.1.10/24 up
ip netns exec [INTERFACE_NAME]_ns ifconfig lo 127.0.0.1/8 up
ip netns exec [INTERFACE_NAME]_ns route add default gw 10.1.1.1
ip netns exec [INTERFACE_NAME]_ns dhcpcd [INTERFACE_NAME]
ip netns exec [INTERFACE_NAME]_ns sudo -b -u [YOUR_USER] [APP_NAME] 2> /dev/null 1> /dev/null &
  • [INTERFACE_NAME] - замініть ім'я вибраного мережевого інтерфейсу.
  • [YOUR_USER] - замініть своє ім’я користувача.
  • [APP_NAME] - назва програми, яка буде виконуватися в просторі імен "[INTERFACE_NAME] _ns". Напр .: "firefox".

ПРИМІТКА I: Прапорці "-b -u" у команді "sudo" дозволяють програмі запускатись із використанням вашого користувача (а не "root") та у фоновому режимі вивільняючи термінал. 2> /dev/null 1> /dev/null &Фрагмент коду, щоб запобігти виходи з «[APP_NAME]» друкується на терміналі.
ПРИМІТКА II: Значення ip "10.1.1.10" та "10.1.1.1" є довільними.
ПРИМІТКА III. Щоб працювати для мене, мені довелося виконати dhcpcd [INTERFACE_NAME]команду.

Для видалення простору імен використовуйте ...

ip netns del [INTERFACE_NAME]_ns

... або ...

ip -all netns delete

... видалити все, що існує.


1

Зазвичай, якщо програма не має можливості налаштування інтерфейсу прослуховування, вона прослуховує на ВСІХ інтерфейсах. (Ви можете підтвердити це за допомогою lsof -i).

Створення правил брандмауера iptables, які відкидають вхідний трафік, спрямований на порти на інтерфейсах, на яких ви не хочете, щоб його було видно, - це найпростіша річ.


1

Альтернатива I:

Використання ld_preload для примушування шлюзу інтерфейсу https://github.com/Intika-Linux-Network/App-Route-Jail

Примушуйте програму використовувати певний мережевий інтерфейс

Нам потрібно знайти, який шлюз використовує мережевий інтерфейс, а потім примусити цей шлюз до нашої в'язничної програми та, таким чином, змусити програму прив’язатись до певного мережевого інтерфейсу

  • Як знайти шлюз інтерфейсу (існує багато рішень, щоб знайти шлюз. Ось декілька команд, які дозволяють знайти використаний шлюз)
$ 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

За шлюз додатків

  • Побудувати додаток-маршрут-в'язницю
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

Альтернатива II:

Firejail https://firejail.wordpress.com/ може змусити програму використовувати певну мережу, але сумісність обмежена.

firejail --dns=8.8.8.8 --net=eth0 --ip=192.168.1.1

Зауважте, що позначення неможливо для звичайних користувачів, ви повинні запустити як root.
jornane

-2

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

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

Тому якщо вони мають різні IP-адреси, використовуйте маршрути, щоб вибрати правильний інтерфейс. Якщо вони мають однакову IP-адресу, вам потрібно використовувати NAT, щоб вони мали різні IP-адреси в системі.


3
По-перше, між клієнтом та сервером може бути кілька дійсних маршрутів, але з різними характеристиками, що підходять для різних типів трафіку; наприклад, UMTS (Cellular Data) може коштувати грошей, але має більший діапазон, ніж WiFi, але обидва є повільнішими, ніж з'єднання з волокном. Якщо постачальники верхніх потоків здійснюють фільтрацію джерел (або NAT), у вас немає іншого вибору, як надсилати «правильний» інтерфейс. По-друге, вплив маршрутизації не є єдиною причиною вибору адреси джерела. Навіть коли обидві адреси знаходяться на одному інтерфейсі, може бути корисним керувати тим, що пов'язано при ініціюванні з'єднань, як сервер

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