Enrutar el tráfico en un cgroup fuera de un túnel VPN

Enrutar el tráfico en un cgroup fuera de un túnel VPN

Estoy intentando que parte del tráfico pase a través de una VPN y otro tráfico no lo haga.

Se supone que los paquetes con una marca de fábrica determinada van a mi interfaz predeterminada ( wlo1) y todo el resto del tráfico a una interfaz de túnel ( tun0, usando OpenVPN) en la tabla principal. He añadido esta regla en nftables:

table ip test {
    chain test {
        type route hook output priority mangle; policy accept;
        meta cgroup 1234 meta mark set 1
    }
}

En la tabla de enrutamiento principal tengo estas entradas:

default via 10.11.0.1 dev tun0 
10.11.0.0/16 dev tun0 proto kernel scope link src 10.11.0.20 
[WANIP.0]/24 dev wlo1 proto kernel scope link src [WANIP] 
128.0.0.0/1 via 10.11.0.1 dev tun0 
[VPNIP] via [WANGATEWAY] dev wlo1

En cambio , los paquetes con fwmark 1se dirigen a su propia tabla de enrutamiento: ip rule add from all fwmark 1 lookup test. En la testtabla he añadido la siguiente ruta:

default via [WANGATEWAY] dev wlo1

Cuando huyo ping 8.8.8.8de este cgroup, se atasca. Parece capaz de enviar pero no recibir ningún paquete.

El tráfico VPN funciona como se esperaba.

¿Qué está pasando exactamente?

Respuesta1

Cuando se emite un paquete, se toma una decisión de enrutamiento: esta decisión elige la interfaz salienteyla dirección IP de origen coincidente que se utilizará.

Cuando elruta/salidaLa cadena pone una marca, desencadena unaverificación de redireccionamiento, como se ve en esteesquemático(que fue hecho paraiptablesen mente pero es totalmente utilizable paranftables). La verificación de redireccionamiento altera la ruta... pero no cambia la dirección IP de origen. Así que hay que trabajar más.

  • agregue una regla NAT para modificar la dirección IP de origen.

esto tiene que hacersedespuésla verificación de redireccionamiento, por lo que se realiza ennat/postenrutamiento. Tenga en cuenta que la misma tabla puede tener diferentes tipos de cadena (al contrario deiptablesdonde tabla <=> tipo).

    nft add chain ip test testnat '{ type nat hook postrouting priority srcnat; policy accept; }'
    nft add rule ip test testnat meta mark 1 masquerade

Ahora el paquete correcto realmente sale.

  • y permitir que se acepte el flujo de respuesta a pesar de no llegar por la ruta predeterminada
  1. Puedes relajarteReenvío de ruta inversaal modo suelto cambiandorp_filter:

        sysctl -w net.ipv4.conf.wlo1.rp_filter=2
    
  2. o marque el flujo de respuesta para usar la misma tabla de enrutamiento que el flujo saliente. Realmente no mejorará la seguridad, pero de todos modos:

        nft add chain ip test testpre '{ type filter hook prerouting priority mangle; policy accept; }'
        nft add rule ip test testpre iif "wlo1" meta mark set 1
    

Desgraciadamente, esto no funcionará sin otro ajuste que es necesario ya que una nuevacaracterística indocumentadaapareció en 2010:

        sysctl -w net.ipv4.conf.wlo1.src_valid_mark=1

Notas:

  • Es posible mejorar la seguridad almacenando la marca en el archivo de conntrack.marca de connmark( ct mark) para permitir solo los flujos de respuesta correctos y nada más para evitar el reenvío de ruta inversa estricto. En modo estricto, nada pasaráwlo1a menos que sea una respuesta del tráfico saliente. Aquí está el archivo completo de reglas de nftables correspondiente a esto (para usar con la opción 2 anterior al reemplazar las reglas de nftables):

      table ip test {
              chain test {
                      type route hook output priority mangle; policy accept;
                      meta cgroup 1234 meta mark set 1 ct mark set meta mark
              }
    
              chain testnat {
                      type nat hook postrouting priority srcnat; policy accept;
                      meta mark 1 masquerade
              }
    
              chain testpre {
                      type filter hook prerouting priority mangle; policy accept;
                      ct mark 1 meta mark set ct mark
              }
      }
    
  • Además, la verificación de redireccionamiento de marcas puede interferir con el PMTU/TCP MSS correcto en algunos casos, según lo que pude leer allí en elrango uidentrada:https://kernelnewbies.org/Linux_4.10#Networking

  • Si puede convertir el uso de cgroups en un conjunto limitado de uids, entonces esto se puede hacer correctamente usando solo la pila de enrutamiento, sin netfilter o nftables, usando ip rule add ... uidrange ...como se describe anteriormente. Vea mi respuesta allí al respecto:Enrutar el tráfico para un usuario a través de una interfaz específica (tum1).

información relacionada