Estoy tratando de determinar si es posible enrutar selectivamente paquetes IP desde un proceso o grupo de procesos a través de una interfaz específica mientras que todos los demás paquetes se enrutan a través de otra interfaz. Es decir, quiero que todo el tráfico /usr/bin/testapp
se enrute eth1
mientras pasan todos los demás paquetes eth0
. Los paquetes en este caso pueden ser TCP, UDP, ICMP, etc. y los usuarios finales pueden configurarlos para utilizar varios puertos.
Debido a que no puedo forzar fácilmente que el proceso en cuestión se vincule a una interfaz específica, estoy tratando de lograr el mismo resultado mediante el enrutamiento. es posible?
--- editar ---
Una sugerencia útil aquí, y en muchos otros lugares, es marcar los paquetes según el UID; ese no es realmente el objetivo. El objetivo es marcar/filtrar/enrutar según el proceso.independientemente del usuario. Es decir, si alice
y bob
todos charlie
ejecutan su propia instancia de /usr/bin/testapp
; todos los paquetes de las tres instancias deben pasar eth1
mientras que todos los demás paquetes del sistema deben pasar eth0
.
Tenga en cuenta que marcar por puerto de origen/destino, nombre de usuario/UID, etc. no es suficiente ya que varios usuarios pueden ejecutar testapp
y pueden configurar diferentes puertos por su cuenta ~/.config/testapp.conf
o lo que sea. La pregunta es sobre el filtrado por proceso.
Una opción que está disponible, aunque no sé qué tan útil es, es usar un /bin/(ba|z)?sh
contenedor basado en -alrededor del binario nativo.
--- editar ---
Me refiero al enrutamiento en un sistema que ejecuta un kernel Linux moderno, digamos 4.0 o superior. Si existen dependencias de software más allá de iproute2
, y herramientas similares, estoy dispuesto a explorar soluciones de código abierto, aunque son preferibles las herramientas básicas nftables
.conntrack
Respuesta1
Está enrutando los paquetes a través de eth1 o eth0. Las tablas mangle deberían solucionar este problema. Para hacerlo, tuve que marcar paquetes y establecer reglas para manejarlos. Primero, agregue una regla que haga que los paquetes de ruta del kernel estén marcados con 2 a través de la tabla.
ip rule add fwmark 2 table 3
Agregue una ruta para redirigir el tráfico a través de una interfaz diferente, suponiendo que la puerta de enlace sea 10.0.0.1:
ip route add default via 10.0.0.1 table 3
Vacíe su caché de enrutamiento.
ip route flush cache
Ahora, establezca una regla de firewall para marcar los paquetes designados:
iptables -t mangle -A OUTPUT -p tcp --dport 465 -j MARK --set-mark 2
Finalmente, relaje la validación de la fuente de la ruta inversa. Algunos sugieren que lo establezcas en 0, pero 2 parece una mejor opción según https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
. Si omite esto, recibirá paquetes (esto se puede confirmar usando tcpdump -i tap0 -n
), pero los paquetes no se aceptarán. El comando para cambiar la configuración para que los paquetes sean aceptados:
sysctl -w net.ipv4.conf.tap0.rp_filter=2
Referencia :http://serverfault.com/questions/345111/iptables-target-to-route-packet-to-specific-interface
Respuesta2
Puede ejecutar el proceso con un usuario específico y hacer coincidir los paquetes con la owner
extensión de iptable. Una vez coincidente, puede marcarlo y usarlo con otra tabla de enrutamiento, uso POSTROUTING
o cualquier solución que desee.
EsteLa publicación explica mejor la coincidencia de paquetes con owner
.
Respuesta3
Esto es posible utilizando espacios de nombres de red para aislar el proceso, una conexión Ethernet virtual para conectar ese espacio de nombres de red a su espacio de nombres principal. Luego puede usar iptables para enrutar según esa fuente.
Así que aquí tienes un ejemplo. Estoy usando el administrador de red para algunos comandos, pero puedes hacerlo sin formato.
# Create a namespace
ip netns add ns1
# create a bridge between them
nmcli connection add type veth ifname virt0 peer virt1
ip link set virt1 netns ns1
ip addr add 192.168.69.1/24 dev virt0
ip netns exec ns1 ip addr add 192.168.69.2/24 dev virt1
ip netns exec ns1 ip link up virt1
echo 1 > sudo tee /proc/sys/net/ipv4/ip_forward
# At this point traffic from ns1 will appear in your main network namespace as coming from ip 192.168.69.2 dev virt0, so you can handle it from there. You will need NAT to make it go somewhere useful.
# In this case I want the traffic to go out through interface vpn1, which is not a default route on my system.
# Add your process-specific routing rules in a non-default table (12345 in this case)
ip route add default dev vpn1 table 12345 proto static scope link metric 50
# Set up a rule to use that table for the traffic coming from that IP, with lower priority than the default table's rule.
ip rule add priority 30000 from 192.168.69.0/24 lookup 12345
# Add the nat, so that the traffic can actually exist on your outbound interface
iptables -t nat -A POSTROUTING -o vpn1 -j MASQUERADE
# At this point traffic from ns1 will go out through interface vpn1. Now you can run command sin that netns to utilize this.
nsenter --net=/var/run/netns/ns1 your_program
Respuesta4
Bueno, dado que nos dijiste:
Debido a que no puedo forzar fácilmente que el proceso en cuestión se vincule a una interfaz específica, estoy tratando de lograr el mismo resultado mediante el enrutamiento. es posible?
Podemos empezar a ayudarle desde este mismo punto. Érase una vez en FreeBSD jail
una llamada al sistema que aparecía con el propósito de restringir un proceso o grupo de procesos a alguna subsección de recursos del sistema. En particular, se podría especificar una dirección IP que esos procesos "aislados" usarían para su actividad de red. Fue tan útil que realmente extrañé mucho esta característica en Linux. Pero Linux también tiene algunas formas de lograr resultados similares:
o, lo más liviano sería simplemente modificar los espacios de nombres manualmente:https://unix.stackexchange.com/questions/155446/linux-is-there-handy-way-to-exec-a-program-binding-it-to-ip-address-of-choice