Cómo hacer que todo el tráfico pase por una interfaz en Linux

Cómo hacer que todo el tráfico pase por una interfaz en Linux

tengo uninterfaz autoescrita tun0(SINTONIZAR/GRIFObasado) que genera lo que recibe.
Necesito que todo el tráfico del sistema fluya a través de esta interfaz.
La función de la interfaz es:

  1. Para descubrir los paquetes que probablemente sean censurados y tunelizarlos.
  2. Pase el resto del tráfico sin ser tocado.

Como adivinarás, estoy intentando crear una herramienta anticensura.
La decisión sobre la creación de túneles debe tomarse dentro del proceso tun0
porque sólo allí podemos utilizar DNS confiables.

Necesito tu ayuda para mostrarme cómo hacer que todo el tráfico fluya a través de una interfaz tun0 escrita por mí mismo. Si tun0 necesita cambios, le pido que proporcione dichos cambios.

A continuación se muestra cómo intenté hacer que todo el tráfico pasara por tun0 y fallé (los pings fallan).

Compilando

  1. gcc tun0.c
  2. sudo ./a.out

Configurando

  1. sudo ip addr add 10.0.0.1/24 dev tun0
  2. crear tabla juan

    $ cat /etc/iproute2/rt_tables 
    #
    # reserved values
    #
    255     local
    254     main
    253     default
    0       unspec
    #
    # local
    #
    #1      inr.ruhep
    
    200 John
    

El orden es importante:

  1. sudo ip rule add from all lookup John
  2. sudo ip route add default dev tun0 table John
  3. sudo ip rule add iif tun0 lookup main priority 500

    $ ip rule
    0:      from all lookup local 
    500:    from all iif tun0 lookup main 
    32765:  from all lookup John 
    32766:  from all lookup main 
    35000:  from all lookup default 
    

Solución de problemas

  1. sudo tcpdump -i wlp2s0 -qtln icmpy luego ping -I tun0 8.8.8.8muestra que no hay paquetes capturados, significa que no se transmiten paquetes de tun0 a wlp2s0 mediante iif tun0 lookup mainla regla.

  2. Cuando lo reemplacé tun0con lotodas partes, funcionó para mí.

También lo intenté

  1. Desactivar el filtrado de ruta inversa, rp_filter=0en/etc/sysctl.conf

Respuesta Solución de problemas

iptables -I FORWARD -j LOG --log-prefix "filter/FORWARD " 
iptables -t nat -I OUTPUT -j LOG --log-prefix "nat/OUTPUT " 
iptables -t nat -I PREROUTING -j LOG --log-prefix "nat/PREROUTING " 
iptables -t nat -I POSTROUTING -j LOG --log-prefix "nat/POSTROUTNG "
tail -f /var/log/syslog

Las fuentes modificadas de la respuesta también sonaquí.

Respuesta1

Entonces, en su configuración, todos los paquetes que intenta enviar a la red se originan inicialmente 10.0.0.1(porque pasan a través de tun0la interfaz y su dirección local es 10.0.0.1). Captas los paquetes, todo está bien hasta ahora.
Ahora,tun0 envía los paquetes más lejos.Dirección de la fuentees 10.0.0.1y desea que los paquetes salgan a través de una interfaz diferente ( wlp2s0en su caso). Eso esenrutamientoasí que primero habilitemos el enrutamiento:

sysctl -w net.ipv4.ip_forward=1

Después de eso, si observa, tcpdumppodrá wlp2s0notar que los paquetes salen con la dirección de origen 10.0.0.1y no con la dirección de origen de la interfaz wlan (lo que se esperaría, supongo). Entonces necesitamos cambiar la dirección de origen y se llamafuente NAT. En Linux es fácil con la ayuda denetfilter/iptables:

iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.1 -j MASQUERADE

Por favor verifique también que su FORWARDcadena tenga ACCEPTuna política o necesitarápermitir el reenvíocon algo como:

iptables -A FORWARD -i tun0 -o wlp2s0 -s 10.0.0.1 -j ACCEPT
iptables -A FORWARD -i wlp2s0 -o tun0 -d 10.0.0.1 -j ACCEPT

Todo debería funcionar ahora:núcleo de linuxhace el enrutamiento, mueve paquetes de tun0la interfaz a wlp2s0.filtro de reddebe cambiar la IP de origen 10.0.0.1a wlp2s0la dirección asignada de su interfaz para los paquetes de salida. Memoriza todas las conexiones y cuando los paquetes de respuesta regresan (si lo hacen) cambia la dirección de destino de la wlp2s0dirección asignada a la interfaz 10.0.0.1(la función "conntrack").
Bueno, debería pero no es así. Parece,filtro de redse confunde con esta complicada configuración de enrutamiento y el hecho de que el mismo paquete primero pasa por la OUTPUTcadena y luego es enrutado y llega a PREROUTINGla cadena. Al menos en Debian 8, no funciona.
La mejor manera de solucionar problemasfiltro de redes la TRACEcaracterística:

modprobe ipt_LOG
iptables -t raw -A OUTPUT -p icmp -j TRACE
iptables -t raw -A PREROUTING -p icmp -j TRACE

Solo habilito el rastreo de paquetes ICMP; puede usar otro filtro para depurar.
Mostrará por qué tablas y cadenas pasa el paquete. Y puedo ver que el paquete no va más allá de la FORWARDcadena (y no es atrapado por la nat/POSTROUTINGcadena que realmente lo hace SNAT).
A continuación se presentan varios enfoques para que esto funcione.

ENFOQUE #1

La mejor manera de desconfundirsefiltro de redes cambiar la dirección IP de origen de los paquetes entun0.c la aplicación. También es la forma más natural. Necesitamos quecambiar 10.0.0.1 a 10.0.0.2en el camino hacia afuera y10.0.0.2 a 10.0.0.1de regreso.
he modificadotun0.c con el código de cambio de dirección fuente.Aqui esta el nuevo archivoyaquí está el archivo de parchepara tutun0.c . Los cambios en el encabezado IP también implicancorrección de suma de control, así que tomé algo de código deProyecto OpenVPN. Aquí está la lista completa de comandos que ejecuto después de un reinicio limpio y tun0_changeip.cun inicio:

ifconfig tun0 inet 10.0.0.1/30 up
sysctl -w net.ipv4.ip_forward=1
ip route add default dev tun0 table John
ip rule add from all lookup John
ip rule add from 10.0.0.2 lookup main priority 500
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.2 -j MASQUERADE

Tenga en cuenta que no es necesario apagar elfiltrado de ruta inversaen ese caso, porque todo es legal: tun0solo recibe y envía paquetes que pertenecen a su subred. También puede realizar un enrutamiento basado en fuente en lugar de basado en interfaz.

ENFOQUE #2

Es posible hacerlo SNATantes de que el paquete llegue a tun0la interfaz. Aunque no es muy correcto. Definitivamente necesitarás apagar elfiltrado de ruta inversaen este caso:

sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0

Ahora, haga lo siguiente SNAT: iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source dirección.ip.de.su.interfaz.wlan

Aquí cambiamos la dirección de origen soloanteslos paquetes llegan al tun0dispositivo. tun0.cEl código reenvía estos paquetes "tal cual" (con la dirección de origen modificada) y se enrutan exitosamente a través de la interfaz wlan. Pero es posible que tenga una IP dinámica en la interfaz wlan y desee usarla MASQUERADE(para no especificar la dirección de la interfaz explícitamente). Así es como puedes hacer uso de MASQUERADE:

iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source 10.0.55.1
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.55.1 -j MASQUERADE

Tenga en cuenta la " 10.0.55.1" dirección IP: es diferente. Puedes usar cualquier IP aquí, no importa. Los paquetes llegan a nat/POSTROUTINGla cadena en wlp2s0la interfaz si cambiamos la IP de origen antes. Y ahora no depende de una IP estática para la interfaz WLAN.

ENFOQUE #3

También puedes usar fwmark. De esa manera no necesitará SNATcapturar solo los paquetes salientes:
primero debemos desactivarfiltrado de ruta inversaporque tun0reenviará paquetes que pertenecen a otra red:

sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0

Now let's alter the routing rules a bit:
# Delete old rules
ip rule del iif tun0 lookup main
ip rule del from all lookup John

# Packets will start going from wlan interface so they will have source address of it
iptables -t mangle -A OUTPUT -o wlp2s0 -j MARK --set-mark 1
ip rule add fwmark 0x1 lookup John

Ese es otro "truco" paraenrutamientoyfiltro de redeso funciona en mi caja Debian 8, pero aún así recomiendo tomar el primer enfoque ya que es más natural y no utiliza ningún truco.


También puede considerar crear su aplicación comoproxy transparente. Creo que sería mucho más fácil en lugar de analizar paquetes desde un dispositivo.

información relacionada