У меня есть два сетевых интерфейса на ПК с Linux, и мне нужно вручную настроить интерфейс, который будет использовать определенный процесс.
В программе (софтфон Twinkle) подобной опции нет, поэтому я считаю, что ее нужно настраивать извне.
Как мне это сделать?
Редактировать:Я не пытаюсь привязать серверный процесс к определенному интерфейсу, а скорее заставить клиентскую программу связываться с сервером, используя определенный интерфейс.
решение1
вы можете заменить код во время выполнения, используя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
похожие хаки и инструменты:
решение2
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 не контролирует маршрут, который использует процесс. Он будет использовать первый маршрут.
И поскольку он всегда использует один и тот же маршрут, по умолчанию будет использоваться интерфейс, зарегистрированный для маршрута (что нам не нужно).
решение3
На основании ответа @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
...чтобы удалить все, что есть.
решение4
Я не думаю, что возможно заставить процесс использовать определенный интерфейс.
Однако я думаю, что вы могли бы поиграться с ipchain/iptables и заставить определенный порт, который прослушивает ваш процесс, получать пакеты только через определенный интерфейс.
Полезное РУКОВОДСТВО: http://tldp.org/HOWTO/IPCHAINS-HOWTO.html