Pregunta: ¿Cómo inicio un programa mientras me aseguro de que su acceso a la red esté vinculado a través de una interfaz de red específica?
Caso: quiero acceder a dos máquinas distintas con la misma IP (192.168.1.1), pero accesible a través de dos interfaces de red diferentes (eth1 y eth2).
Ejemplo:
net-bind -D eth1 -exec {Program 192.168.1.1}
net-bind -D eth2 -exec {Program 192.168.1.1}
Lo anterior es una aproximación de lo que me gustaría, inspirado en el enlace de hardware realizado a través de primusrun y optirun .
Desafío: como se sugiere en un hilo relacionado , las interfaces utilizadas no son elegidas por el programa, sino por el núcleo (de ahí la sintaxis previa al enlace en el ejemplo anterior).
He encontrado algunas soluciones relacionadas, que no son satisfactorias. Se basan en interfaces de red vinculantes a través de listas negras de red específicas del usuario; es decir, ejecutar el proceso como un usuario que solo puede acceder a una única interfaz de red específica.
fuente
Respuestas:
Para Linux, esto ya se ha respondido en Superusuario: ¿cómo usar diferentes interfaces de red para diferentes procesos? .
La respuesta más popular utiliza un
LD_PRELOAD
truco para cambiar el enlace de red para un programa, pero los núcleos modernos admiten una característica mucho más flexible llamada 'espacios de nombres de red' que se expone a través delip
programa. Esta respuesta muestra cómo usar esto. De mis propios experimentos he hecho lo siguiente (como root):También es posible administrar espacios de nombres de red hasta cierto punto con los comandos
unshare
ynsenter
. Esto le permite también crear espacios separados para PID, usuarios y puntos de montaje. Para más información ver:fuente
wvdial
por ejemplo, no parece configurarlo en absoluto ... por lo que debe definirse en el propio espacio de nombresip netns remove test_ns
a la normalidad? ¿O tienes que hacer algo especial?Estoy aceptando la respuesta de Graeme; Esto es simplemente un seguimiento para explicar los cambios que hice a su sugerencia para resolver mi problema.
En lugar de vincular la interfaz física dentro del espacio de nombres, creé un par de interfaces de red virtual, con un extremo en el espacio de nombres de red y otro en la raíz. Los paquetes se enrutan a través de esta red virtual desde el espacio de nombres, al espacio de nombres raíz y luego a la interfaz física. - Como tal, puedo ejecutar todas mis transferencias de datos normales y, además, iniciar procesos que solo pueden acceder a una interfaz específica.
Una vez que las interfaces se han configurado para eth0 y eth1, con sus respectivos espacios de nombres eth0_ns y eth1_ns, los programas se pueden ejecutar en la interfaz especificada a través de;
fuente
dhclient <bridge>
por aquí .Solución I: precargando una biblioteca específica
App-Route-Jail : use ld_preload para forzar la puerta de enlace de la interfaz (gran idea pero requiere capacidades de root o marcas) el uso se detalla en las notas a continuación
Proxybound : use ld_preload para forzar un proxy a una aplicación específica (esto es usar proxy en lugar de interfaz)
Force-Bind : tiene muchas características, pero el enlace tiene fugas (no confiable)
Bind-Interface-IP : conexiones demasiado simples y con fugas (no confiable)
Bind-IP : conexiones demasiado simples y con fugas (no confiable)
Solución II: espacio de usuario de Linux
Espacio de usuario clásico de Linux ip-netns : gran solución, pero requiere root e interfaz solo puede existir en un solo espacio de usuario
Firejail : Firejail puede obligar a una aplicación a usar una red específica, pero la compatibilidad es limitada (por ejemplo, no es compatible con las interfaces tun). firejail no requiere root
firejail --dns=8.8.8.8 --noprofile --net=eth0 --ip=192.168.1.1 app-command
Firejail con netns : Firejail puede obligar a una aplicación a usar un espacio de usuario específico que se creó por separado, esto nos permite nombrar espacios sin root
firejail --dns=8.8.8.8 --noprofile --netns=nameOfyourNS app-command
Firejail con mascarada y puente : Firejail puede obligar a una aplicación a usar una interfaz específica con iptables masquerade , esto es genial y no requiere root pero requiere ip_forward y podría implicar un impacto en la seguridad
firejail --net=br0 firefox
Solución III: iptables de Linux
Iptables podrían usarse para este propósito, pero esto requiere ip_forward y podría implicar un impacto en la seguridad si no está configurado correctamente, ejemplo 1 , ejemplo 2 , ejemplo 3 , ejemplo 4
Notas de soluciones (I, II y III):
Wireguard
Si está utilizando una VPN (especialmente Wireguard) y desea aplicar esta solución a una interfaz Wireguard ( Wireguard con espacio de usuario ), puede seguir las instrucciones vinculadas para crear un espacio de usuario que contenga una interfaz wg (y por lo tanto limitado a una interfaz vpn ) también se puede combinar
firejail --netns=container
para poder usar el espacio de usuario sin root.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
Cómo usar App-Route-Jail
192.168.1.1
se 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 diariamentefuente