Encaminamiento selectivo a través de más de un router con linux


Vamos a utilizar una máquina GNU/Linux como dispositivo para acceder a Internet desde una red local a través de dos enrutadores diferentes. Un montaje como éste se utiliza habitualmente con dos dispositivos de diferentes proveedores de acceso, para así garantizar el acceso a Internet de nuestros usuarios cuando ocurra un problema en uno de ellos; además sería posible configurarlo todo para que que el tráfico se reparta habitualmente entre los dos encaminadores realizando un balanceo de las peticiones alternativamente hacia uno u otro. En nuestro caso vamos a realizar una configuración un poco diferente ya que vamos a utilizar simultáneamente los dos enrutadores de acceso, pero vamos a seleccionar qué tipo de tráfico irá por cada uno de ellos, para lo que haremos uso de las herramientas iproute2 e iptables.

Situación de partida

Supongamos que inicialmente tenemos una situación como la que aparece en la siguiente imagen:

1 router

Los equipos de la red local acceden a Internet a través de su puerta de enlace que es un equipo GNU/Linux con dos interfaces de red: eth0 conectada a router1 en la red 192.168.1.0/24 y eth2 configurada como puerta de enlace de la red 172.16.0.0/24.

Supongamos que tenemos problemas de saturación en el acceso a Internet de los equipos de la red local y decidimos añadir un segundo dispositivo de acceso como en la siguiente figura:

esquema

Los equipos de la red local siguen accediendo a Internet a través de su puerta de enlace que es un equipo GNU/Linux, pero en éste se ha configurado la interfaz de red eth1 conectada a router2 en la red 192.168.2.0/24. Supongamos ahora una situación un tanto peculiar, en la que el router2 nos proporciona más ancho de banda de acceso a Internet, pero con el tráfico limitado a consultas DNS y web: 53/udp, 80/tcp y 443/tcp; mientras que el router1 nos proporciona menos ancho de banda pero sin restricción de acceso. La solución que vamos a plantear aquí es aprovechar el mayor ancho de banda del router2 para enviar a través de él todo el tráfico web originado en los equipos de la red local, que en muchos casos es el que mayor ancho de banda consume y permitirá descongestionar el tráfico que atraviesa el router1.

IProute2

Aunque seguramente la mayoría de los usuarios de sistemas GNU/Linux todavía sigan utilizando para configurar la red las herramientas del paquete net-tools: ifconfig y route principalmente, hace ya bastantes años que se desarrollaron un conjunto de herramientas más potentes para la configuración de la red en linux que se agrupan bajo el denominador iproute2. Son estas herramientas las que utilizaremos para realizar esta configuración y recomendamos encarecidamente su uso a todos los lectores de esta entrada.

Es bastante ilustrativa la tabla comparativa entre las instrucciones de net-tools e iproute2 de la wikipedia:

Purpose Legacy utility iproute2 equivalent
Address and link configuration ifconfig ip addr, ip link
Routing tables route ip route
Neighbors arp ip neigh
VLAN vconfig ip link
Tunnels iptunnel ip tunnel
Bridges brctl ip link, bridge
Multicast ipmaddr ip maddr
Statistics netstat ip -s, ss

Varias tablas de encaminamiento

Una de las características interesantes de iproute2 es que permite definir hasta 255 tablas de encaminamiento diferentes (obviamente quien utiliza varias tablas de encaminamiento es el kérnel linux, pero necesitamos unas herramientas del espacio de usuario que nos permitan definirlas). De hecho, inicialmente hay definidas 3 tablas: local, main y default:

ip rule list
0:	from all lookup local 
32766:	from all lookup main 
32767:	from all lookup default

Se podrían establecer reglas de encaminamiento en cada una de estas tablas y las que están definidas inicialmente en la situación de partida cuando el equipo GNU/Linux está conectado a router1 y a la red local son (esta tabla es normalmente mantenida por el kérnel y no es conveniente modificarla):

ip route list table local
broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1 
local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1 
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1 
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1 
broadcast 192.168.1.0 dev eth0  proto kernel  scope link  src 192.168.1.2 
local 192.168.1.2 dev eth0  proto kernel  scope host  src 192.168.1.2 
broadcast 192.168.1.255 dev eth0  proto kernel  scope link  src 192.168.1.2 
broadcast 172.16.0.0 dev eth2  proto kernel  scope link  src 172.16.0.1 
local 172.16.0.1 dev eth2  proto kernel  scope host  src 172.16.0.1 
broadcast 172.16.255.255 dev eth2  proto kernel  scope link  src 172.16.0.1 

La tabla main muestra las reglas de encaminamiento que estamos acostumbrados a ver porque son las únicas a las que tiene acceso el comando route:

ip route list table main
default via 192.168.1.1 dev eth0 
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.2
172.16.0.0/16 dev eth2  proto kernel  scope link  src 172.16.0.1 

Y la tabla de encaminamiento “default” no tiene definida inicialmente ninguna regla:

ip route list table default

Observando los resultados anteriores vemos que las reglas de encaminamiento que obtenemos sin especificar la tabla son realmente las de la tabla “main”:

ip route list
default via 192.168.1.1 dev eth0 
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.2
172.16.0.0/16 dev eth2  proto kernel  scope link  src 172.16.0.1 

Al pasar a la segunda situación en la que conectamos el equipo con router2 y definimos su interfaz de red dentro de la red 192.168.2.0/24, las tablas de encaminamiento se modifican levemente, añadiendo las reglas correspondientes a esta nueva red (nótese que no hemos puesto router2 como puerta de enlace):

ip route list table local
broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1 
local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1 
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1 
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1 
broadcast 192.168.1.0 dev eth0  proto kernel  scope link  src 192.168.1.2 
local 192.168.1.2 dev eth0  proto kernel  scope host  src 192.168.1.2 
broadcast 192.168.1.255 dev eth0  proto kernel  scope link  src 192.168.1.2 
broadcast 192.168.2.0 dev eth1  proto kernel  scope link  src 192.168.2.2
local 192.168.2.2 dev eth1  proto kernel  scope host  src 192.168.2.2
broadcast 192.168.2.255 dev eth1  proto kernel  scope link  src 192.168.2.2
broadcast 172.16.0.0 dev eth2  proto kernel  scope link  src 172.16.0.1 
local 172.16.0.1 dev eth2  proto kernel  scope host  src 172.16.0.1 
broadcast 172.16.255.255 dev eth2  proto kernel  scope link  src 172.16.0.1 
ip route list table main
default via 192.168.1.1 dev eth0 
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.2
192.168.2.0/24 dev eth1  proto kernel  scope link  src 192.168.2.2
172.16.0.0/16 dev eth2  proto kernel  scope link  src 172.16.0.1 

Marcado de paquetes y uso de una tabla de encaminamiento adicional

Todo lo anterior era simplemente para que se pudieran entender los pasos que vamos a dar a continuación, ya que vamos a utilizar iptables para etiquetar los paquetes que nos interesen y añadir una nueva regla a iproute que los desvíe por router2, no modificando el resto de paquetes que seguirán saliendo como antes por router1.

Para etiquetar o marcar los paquetes utilizaremos la tabla mangle de iptables y obviamente lo haremos sobre la cadena PREROUTING, ya que de nada nos serviría marcar los paquetes después de que se hubiera tomado la decisión de encaminamiento. En este caso la regla de iptables que necesitamos sería algo como:

iptables -t mangle -A PREROUTING -i eth2 -s 172.16.0.0/16 ! -d 172.16.0.1 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 1

Ahora creamos una nueva tabla de encaminamiento a la que llamamos router2 (podemos utilizar cualquier valor entre 1 y 252 ya que el 0,253,254 y 255 están en uso inicialmente):

echo 201 router2 >> /etc/iproute2/rt_tables

Y quizás el paso más importante, creamos una regla que hace que se apliquen las reglas de encaminamiento de la tabla “router2” sólo a los paquetes marcados con la etiqueta 1:

ip rule add fwmark 1 table router2

Ya por último añadimos la puerta de enlace de la tabla “router2” (se destaca que especificamos la tabla en la que se crea esta regla):

ip route add default via 192.168.2.1 dev eth1 table router2

Podemos ver la nueva regla que sólo se aplica a los paquetes marcados con la etiqueta 1 y que se hace antes de la tabla main:

ip rule list
0:	from all lookup local 
32765:	from all fwmark 0x1 lookup router2
32766:	from all lookup main 
32767:	from all lookup default

NAT

Estamos hablando todo el rato de reglas de encaminamiento y hay un punto fundamental que hemos pasado por alto y es que todos los equipos de esta configuración están utilizando direcciones IPv4 privadas según la RFC 1918 y por tanto no son enrutables directamente en Internet a menos que algún dispositivo intermedio realice una traducción de su dirección IP privada por una dirección IP pública. Damos por hecho que ambos routers están configurados para hacer SNAT de los paquetes que vengan de su interfaz interna, pero aún así no serían capaces de hacer llegar paquetes a la red local que está detrás de la máquina GNU/Linux salvo que adicionalmente optemos por una de estas dos opciones:

  • Definamos reglas estáticas en cada uno de los routers para que estos sepan como devolver paquetes a la red local
  • Hagamos SNAT en las interfaces de red de la máquina GNU/Linux eth0 y eth1 a los paquetes que provienen de la red local y salen por ellas

Resumen

Un paquete que se originase en la red local que tuviese como puerto destino el 80/tcp o el 443/tcp se marcaría con la etiqueta 1 en la fase PREROUTING de mangle y por tanto se le aplicarían las reglas de encaminamiento de la tabla “router2”, por lo que se enviaría a router2 a través de eth2 y en su caso se cambiaría su dirección IP origen por la de la máquina GNU/Linux si definimos reglas de SNAT aquí. Cualquier otro paquete no sería marcado, por lo que se le aplicarían las reglas de encaminamiento de la tabla main y saldría por router1.

Referencias

[1] http://www.lartc.org/howto/
[2] http://linux-ip.net/html/
[3] http://www.linuxhorizon.ro/iproute2.html

, , , ,

  1. Deja un comentario

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: