56

У меня есть два сетевых интерфейса на ПК с Linux, и мне нужно вручную установить интерфейс, который будет использовать данный процесс.

Программа (софтфон Twinkle) не имеет подобной опции, поэтому я считаю, что она должна быть установлена внешне.

Как мне это сделать?

Редактировать: я не пытаюсь привязать процесс сервера к определенному интерфейсу, а хочу, чтобы клиентская программа связывалась с сервером через определенный интерфейс.

7 ответов7

47

Вы можете заменить код во время выполнения с помощью 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

похожие хаки и инструменты:

31

ip netns может сделать это.

TL; DR: создайте сетевые пространства имен, свяжите с ними интерфейсы и запустите «ip netns exec NAME cmd ...»

Просто проверьте, поддерживает ли ваш дистрибутив ip netns ... (Отступить 5r3 нет, а Кали нет;))

ПОДРОБНЕЕ:

#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

Я не думаю, что можно заставить процесс использовать определенный интерфейс.

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

Полезное руководство:http://tldp.org/HOWTO/IPCHAINS-HOWTO.html

1

Исходя из @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 & snippet предотвращает печать выводов «[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, которые отбрасывают входящий трафик, направленный на его порты на интерфейсах, на которых вы не хотите, чтобы он был виден, является самым простым делом.

0

Альтернатива 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

На шлюз приложения

  • Построить 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

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

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

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

Почему вы хотите, чтобы программа использовала интерфейс, отличный от того, который подключен к серверу, для связи с этим сервером? И если система не использует интерфейс, подключенный к серверу, для связи с этим сервером, это проблема системного уровня (таблица маршрутизации), и она не имеет никакого отношения к тому, какой процесс хочет связаться с этим сервером.

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

Поэтому, если у них разные IP-адреса, используйте маршруты, чтобы выбрать правильный интерфейс. Если у них одинаковый IP-адрес, вам нужно использовать NAT, чтобы они имели разные IP-адреса для системы.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .