¿Cómo usar diferentes interfaces de red para diferentes procesos?

59

Tengo dos interfaces de red en una PC con Linux y necesito configurar manualmente la interfaz que utilizará un proceso determinado.

El programa (Twinkle softphone) no tiene una opción similar, por lo que creo que debe configurarse externamente.

¿Cómo puedo hacerlo?

Editar: no estoy tratando de hacer que un proceso del servidor se vincule a una interfaz específica, sino de hacer que un programa cliente se ponga en contacto con un servidor utilizando una interfaz específica.

Andrea Spadaccini
fuente
los clientes también usan bind / connect, mire la documentación bind.c.txt de cómo forzar ircII (un programa irc-client) a una ip dada: 'Ejemplo en bash para usar su IP virtual como su dirección de origen saliente para ircII: BIND_ADDR = "your-virt-ip" LD_PRELOAD =. / Bind.so ircII '
akira
Encontré un enfoque diferente aquí, espero que sea útil (seguro que espero que el enrutamiento de la política del kernel descrito esté habilitado de forma predeterminada en la actualidad): kindlund.wordpress.com/2007/11/19/…
Savvas Radevic

Respuestas:

48

puede reemplazar el código en tiempo de ejecución mediante el uso de LD_PRELOAD (@windows puede usar una técnica similar llamada desvíos , bastante elegante). lo que esto hace es informar al vinculador dinámico para que primero cargue todas las bibliotecas en el proceso que desea ejecutar y luego agregue un poco más sobre él. normalmente lo usas así:

% LD_PRELOAD=./mylib.so ls

y con eso cambias lo que lshace.

para su problema, probaría http://www.ryde.net/code/bind.c.txt , que puede usar como:

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

así es como lo construyes:

% 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

un tutorial más extenso es http://daniel-lange.com/archives/53-Binding-applications-to-a-specific-IP.html

trucos y herramientas similares:

akira
fuente
77
Wow, qué diablos. +1
sinni800
1
Hola, este parece un buen truco, pero no me funciona. Tengo dos módems 3G que, cuando están conectados, abren dos interfaces (ppp0 y ppp1). Si intento forzar una de las dos IP, siempre termino saliendo con la misma interfaz (lo veo porque tengo dos instancias de wireshark, una para cada interfaz). También eliminé las impresiones de depuración de bind.c y de hecho veo que la biblioteca "sobrecargada" está cargada, así que no sé por qué no funciona.
Andrea Spadaccini
3
LD_PRELOAD se ignora si su UID efectivo no es el mismo que su UID real.
matthias krull
El force_bindproyecto de Catalin M. Boie es compatible con ipv6
BurnsBA
Funciona muy bien, pero tuvo que agregar #include <arpa / inet.h> para que la compilación tenga éxito.
anno
31

ip netns puede hacer esto.

TL; DR: Cree espacios de nombres de red, asócieles interfaces y luego ejecute "ip netns exec NAME cmd ..."

Solo verifique si su distribución admite ip netns ... (Backtrack 5r3 no, mientras que Kali sí;))

EN MÁS DETALLES:

#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 qué es esto mejor que vincular la ip a través de LD_PRELOAD? Porque LD_PRELOAD no controla la ruta que utilizan los procesos. Utilizará la primera ruta.

Y dado que siempre usa la misma ruta, usará de manera predeterminada la interfaz registrada en la ruta (que no es lo que queremos)

olivervbk
fuente
2
Intenta agregar más detalles a tu respuesta.
Renju Chandran chingath
44
no haga esto en el servidor remoto si eth0 es la interfaz de red pública ..
ygrek
1
la última línea debería serip netns exec myNamespace firefox
meuh
1
Use "sudo ip netns del <namespace-name>" para eliminar el espacio de nombres cuando sea necesario.
Eduardo Lucio
1
@EduardoLucio debería ser posible ejecutarlo como: sudo ip netns exec myNamespace su -u someUser -c firefox
olivervbk
2

No creo que sea posible forzar un proceso para usar una determinada interfaz.

Sin embargo, creo que podría jugar con ipchain / iptables y forzar que un puerto determinado en el que escucha su proceso solo reciba paquetes que ingresen a través de una interfaz particular.

CÓMO útil: http://tldp.org/HOWTO/IPCHAINS-HOWTO.html

thetarro
fuente
2
Las dos publicaciones con mayor voto demuestran lo contrario.
Paul Gear
2

Basado en @olivervbk la respuesta a continuación es mi!

Ejecute todos los comandos como "root".

Usa el comando ...

ip a

... para averiguar el nombre de la interfaz de red que querrá usar.

Ejecute los siguientes comandos como plantilla ...

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]: reemplácelo con el nombre de la interfaz de red elegida.
  • [SU_USUARIO] - Reemplace con su nombre de usuario.
  • [APP_NAME]: nombre de la aplicación que se ejecutará en el espacio de nombres "[INTERFACE_NAME] _ns". Por ejemplo: "firefox".

NOTA I: Los indicadores "-b -u" en el comando "sudo" permiten que la aplicación se ejecute usando su usuario (no "root") y en segundo plano liberando el terminal. El 2> /dev/null 1> /dev/null &fragmento es para evitar que las salidas de "[APP_NAME]" se impriman en el terminal.
NOTA II: Los valores de ip "10.1.1.10" y "10.1.1.1" son arbitrarios.
NOTA III: Para trabajar para mí, tuve que ejecutar el dhcpcd [INTERFACE_NAME]comando.

Para eliminar el espacio de nombres use ...

ip netns del [INTERFACE_NAME]_ns

... o ...

ip -all netns delete

... para eliminar cualquiera que exista.

Eduardo Lucio
fuente
1

Por lo general, si un programa no tiene una opción para configurar la interfaz de escucha, está escuchando en TODAS las interfaces. (Puedes verificar esto con lsof -i).

Lo más fácil es crear reglas de firewall de iptables que eliminen el tráfico entrante apuntado hacia sus puertos en interfaces en las que no desea que sea visible.

LawrenceC
fuente
1

Alternativa I:

Uso de ld_preload para forzar la puerta de enlace de la interfaz https://github.com/Intika-Linux-Network/App-Route-Jail

Forzar a una aplicación a usar una interfaz de red específica

Necesitamos encontrar qué puerta de enlace está utilizando la interfaz de red, luego forzar esa puerta de enlace a nuestra aplicación encarcelada y, por lo tanto, forzar a la aplicación a unirse a una interfaz de red específica

  • Cómo encontrar la puerta de enlace de la interfaz (hay muchas soluciones para encontrar la puerta de enlace, aquí hay algunos comandos que permiten encontrar la puerta de enlace utilizada)
$ 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

Por puerta de enlace de aplicaciones

  • Construir App-Route-Jail
git clone https://github.com/Intika-Linux-Network/App-Route-Jail.git
cd Approute-Utils
chown 755 make.sh
./make.sh
  • Agregar una ruta para los futuros paquetes marcados (para la aplicación encarcelada) en este ejemplo 192.168.1.1se usa como puerta de enlace forzada, esta regla de ruta no afectará a otras aplicaciones, esta manipulación debe hacerse solo una vez en el arranque del sistema, por ejemplo, si desea usa esta solución diariamente
ip rule add fwmark 10 table 100
ip route add default via 192.168.1.1 table 100
  • Inicie la aplicación que desea encarcelar
MARK=10 LD_PRELOAD=./mark.so firefox
  • Probar la dirección IP wan
MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me

Alternativa II:

Firejail https://firejail.wordpress.com/ puede obligar a una aplicación a usar una red específica, pero la compatibilidad es limitada.

firejail --dns=8.8.8.8 --net=eth0 --ip=192.168.1.1
intika
fuente
Tenga en cuenta que la marca no es posible para usuarios normales, debe ejecutarse como root.
jornane
-2

¿Por qué querrías que un programa use una interfaz diferente a la conectada al servidor para hablar con ese servidor? Y si el sistema no está utilizando la interfaz conectada a un servidor para hablar con ese servidor, es un problema de nivel de sistema (tabla de enrutamiento) y no tiene nada que ver con qué proceso quiere hablar con ese servidor.

Diferentes servidores en redes IP tienen diferentes direcciones IP. El kernel debe saber qué interfaz usar para llegar a una dirección IP particular basada en la tabla de enrutamiento. Si está intentando hablar con dos servidores diferentes que tienen la misma dirección IP, el sistema se confundirá (porque, entre otras cosas, solo indexa las conexiones internamente por dirección de destino). Puede hacer que funcione, pero es una solución a nivel de sistema que implica colocar un servidor en una red lógica separada que solo está conectada a la máquina a través del software NAT.

Entonces, si tienen diferentes direcciones IP, use rutas para seleccionar la interfaz correcta. Si tienen la misma dirección IP, debe usar NAT para que parezcan tener diferentes direcciones IP para el sistema.

David Schwartz
fuente
3
En primer lugar, puede haber múltiples rutas válidas entre el cliente y el servidor, pero con diferentes características adecuadas para diferentes tipos de tráfico; por ejemplo, UMTS (datos celulares) puede costar dinero pero tiene un mayor alcance que WiFi, pero ambos son más lentos que una conexión de fibra. Si los proveedores ascendentes filtran la fuente (o NAT), no tiene más remedio que enviar la interfaz 'correcta'. En segundo lugar, influir en el enrutamiento no es la única razón para seleccionar una dirección de origen. Incluso cuando ambas direcciones están en la misma interfaz, puede ser útil controlar cuál está vinculado al iniciar conexiones, como el servidor
Un caso es si tiene IP públicas diferentes y desea iniciar un nuevo proceso en cada una de las conexiones salientes.
Rfraile