Como usar interfaces de rede diferentes para diferentes processos?

54

Eu tenho duas interfaces de rede em um PC Linux e preciso definir manualmente a interface que um determinado processo usará.

O programa (Twinkle softphone) não tem uma opção semelhante, por isso acredito que deve ser definido externamente.

Como posso fazer isso?

Edit: Eu não estou tentando fazer um processo de servidor vincular a uma interface específica, mas sim fazer um programa cliente contatar um servidor usando uma interface específica.

    
por Andrea Spadaccini 03.02.2011 / 12:08

6 respostas

45

você pode substituir o código em tempo de execução pelo uso de LD_PRELOAD (@windows você pode usar uma técnica similar chamada desvios , bastante extravagantes). O que isto faz é informar ao vinculador dinâmico para primeiro carregar todas as libs no processo que você quer rodar e depois adicionar um pouco mais sobre ele. você normalmente usa assim:

% LD_PRELOAD=./mylib.so ls

e com isso você muda o que o ls faz.

para o seu problema eu tentaria link , que você pode usar como:

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

aqui está como você o constrói:

% 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

um tutorial mais longo é link

hacks e ferramentas semelhantes:

por 03.02.2011 / 12:58
30

ip netns pode fazer isso.

TL; DR: Crie namespaces de rede, associe interfaces a eles e execute "ip netns exec NAME cmd ..."

Basta verificar se sua distro suporta ip netns ... (Backtrack 5r3 não, enquanto Kali faz;))

EM MAIS DETALHES:

#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

Por que isso é melhor do que ligar o ip via LD_PRELOAD? Porque LD_PRELOAD não controla a rota que o processo usa. Ele usará a primeira rota.

E como sempre usa a mesma rota, o padrão será a interface registrada na rota (o que não é o que queremos)

    
por 06.05.2014 / 18:23
3

Eu não acho que seja possível forçar um processo a usar uma determinada interface.

No entanto, acho que você pode brincar com o ipchain / iptables e forçar que uma determinada porta em que seu processo esteja escutando só receba pacotes através de uma interface específica.

HOWTO Útil: link

    
por 03.02.2011 / 12:54
1

Normalmente, se um programa não tem opção para configurar a interface de escuta, ele está escutando em TODAS as interfaces. (Você pode verificar isso com lsof -i ).

A criação de regras de firewall do iptables que eliminam o tráfego de entrada apontado para suas portas em interfaces nas quais você não quer que seja visível é a maneira mais fácil de fazer.

    
por 03.02.2011 / 13:35
1

Baseado no @olivervbk, a resposta abaixo é minha!

Execute todos os comandos como "root".

Use o comando ...

ip a

... para descobrir o nome da interface de rede que você deseja usar.

Execute os comandos abaixo como o modelo ...

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] - Substitua pelo nome da interface de rede escolhida.
  • [YOUR_USER] - Substitua por seu nome de usuário.
  • [APP_NAME] - nome do aplicativo que será executado no namespace "[INTERFACE_NAME] _ns". Por exemplo: "firefox".

OBSERVAÇÃO I: Os sinalizadores "-b -u" no comando "sudo" permitem que o aplicativo seja executado usando o usuário (não "root") e, em segundo plano, liberando o terminal. O fragmento 2> /dev/null 1> /dev/null & é para impedir que as impressões de "[APP_NAME]" sejam impressas no terminal.
NOTA II: Os valores de ip "10.1.1.10" e "10.1.1.1" são arbitrários.
NOTA III: Para trabalhar para mim, tive que executar o comando dhcpcd [INTERFACE_NAME] .

Para remover o namespace use ...

ip netns del [INTERFACE_NAME]_ns

... ou ...

ip -all netns delete

... para remover qualquer um que exista.

    
por 09.08.2017 / 23:42
-1

Por que você quer que um programa use uma interface diferente daquela conectada ao servidor para falar com esse servidor? E se o sistema não estiver usando a interface conectada a um servidor para conversar com esse servidor, é um problema de nível de sistema (tabela de roteamento) e não tem nada a ver com qual processo acontece para querer falar com esse servidor.

Servidores diferentes em redes IP possuem endereços IP diferentes. O kernel deve saber qual interface usar para alcançar um determinado endereço IP com base na tabela de roteamento. Se você estiver tentando falar com dois servidores diferentes que tenham o mesmo endereço IP, o sistema ficará confuso (porque, entre outras coisas, indexará as conexões internamente pelo endereço de destino). Você pode fazer isso funcionar, mas é uma correção no nível do sistema que envolve colocar um servidor em uma rede lógica separada que só é conectada à máquina por meio do software NAT.

Portanto, se eles tiverem endereços IP diferentes, use rotas para selecionar a interface correta. Se eles tiverem o mesmo endereço IP, você precisará usar o NAT para que eles pareçam ter endereços IP diferentes no sistema.

    
por 15.08.2011 / 07:20