routing por diferentes proveedores

29 de noviembre de 2009

Supongamos que tenemos un servidor (en este caso un servidor de VPN) que por cualquier razón su conexión a Internet (por el RouterA) se ha quedado pequeña. Hemos decidido comprar un nuevo router simétrico (el RouterB) para garantizar la calidad de la conexiones VPN para ciertas personas. Una grupo de personas se conectarán a la VPN por el RouterA y otros por el RouterB.



Este ejemplo es extensible a cualquier otro tipo de servicio que queramos ofrecer de forma que una parte del trafico va por un sitio y el otro por otro. La dificultad radica en que el tráfico debe volver por el mismo router por el que ha llegado.

Para realizar esto utilizaremos el comando "ip" que nos permite manipular las tablas de rutas, crear políticas de rutas y crear tuneles.

Veamos como está la tabla de rutas del servidor:

root# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.2.0     *               255.255.255.0   U     1      0        0 eth1
192.168.1.0     *               255.255.255.0   U     1      0        0 eth0
link-local      *               255.255.0.0     U     1000   0        0 eth1
default         192.168.1.1     0.0.0.0         UG    0      0        0 eth0

root# ip route show
192.168.2.0/24 dev eth1  proto kernel  scope link  src 192.168.2.2  metric 1
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.6  metric 1
169.254.0.0/16 dev eth1  scope link  metric 1000
default via 192.168.1.1 dev eth0  proto static
Tanto el comando "route" e "ip route show" muestran la misma información. El comando "route" es la versión ligera del comando "ip route show".

Cuando Linux necesita enrutar un paquete busca dentro de las tablas su camino. Por defecto hay tres tablas de enrutamiento: local, main y default.
root# ip rule list
0: from all lookup local
32766: from all lookup main
32767: from all lookup default

Veamos que hay dentro de cada una de ellas:
root# ip route list table local
broadcast 192.168.1.0 dev eth0  proto kernel  scope link  src 192.168.1.6
broadcast 192.168.2.255 dev eth1  proto kernel  scope link  src 192.168.2.2
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1
local 192.168.1.6 dev eth0  proto kernel  scope host  src 192.168.1.6
broadcast 192.168.1.255 dev eth0  proto kernel  scope link  src 192.168.1.6
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 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1
local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1

root# ip route list table main
192.168.2.0/24 dev eth1  proto kernel  scope link  src 192.168.2.2  metric 1
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.6  metric 1
169.254.0.0/16 dev eth1  scope link  metric 1000
default via 192.168.1.1 dev eth0  proto static

root# ip route list table default
(vacia)

Ver como la tabla por defecto del sistema (la que vemos al hacer "route") se llama main.

Lo que vamos hacer es crear dos tablas más (lan1 y lan2) para que contengan las rutas para cada una de las diferentes salidas a Internet. Para ello editaremos el archivo /etc/iproute2/rt_table con el siguiente contenido:
root# cat /etc/iproute2/rt_tables
#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep
10 lan1
20 lan2

Ahora crearemos las rutas que irán en cada una de estas tablas. Para que estas rutas se carguen en el sistema cada vez que arranquemos, la meteremos en /etc/rc.local:
root# cat /etc/rc.local
#!/bin/sh -e

ip rule add from 192.168.1.6 table lan1
ip route add 192.168.1.0/24 dev eth0 src 192.168.1.6 table lan1
ip route add default via 192.168.1.1 table lan1

ip rule add from 192.168.2.2 table lan2
ip route add 192.168.2.0/24 dev eth0 src 192.168.2.2 table lan2
ip route add default via 192.168.2.1 table lan2

exit 0
root# reboot

Estas órdenes aseguran que el tráfico que proviene de una interfaz, es contestado por la misma interfaz.

Una vez reiniciado el sistema vemos si las rutas se han cargado correctamente en el sistema:
root# ip rule list
0:      from all lookup local
32764:  from 192.168.2.2 lookup lan2
32765:  from 192.168.1.6 lookup lan1
32766:  from all lookup main
32767:  from all lookup default

root# ip route list table lan1
192.168.1.0/24 dev eth0  scope link  src 192.168.1.6
default via 192.168.1.1 dev eth0

root# ip route list table lan2
192.168.2.0/24 dev eth0  scope link  src 192.168.2.2
default via 192.168.2.1 dev eth1

Cuando un paquete llega al servidor este comprueba por orden si se cumple alguna de las reglas de tabla. Primero mira si se cumple "from 192.168.2.2". Si se cumple utiliza la tabla "lan2", de lo contrario pasará a ver si se cumple "from 192.168.1.6". Si se cumple utilizará la tabla "lan2". Por ultimo utilizará la tabla por defecto "main".

Para depurar y ver que todo funciona se puede utilizar el comando tcpdump y ver si el trafico pasa por una interfaz o u otra.

El siguiente escenario también lo podríamos utilizar por ejemplo para un servidor de correo donde queremos que el trafico del webmail (puerto 80 y 443) vaya por una ISP y el trafico al 25 vaya por otro ISP.

Más información:
+ Linux Advanced Routing & Traffic Control HOWTO

2 comentarios:

Unknown dijo...

hola amigo, una consulta quisiera saber si el grafico esta bien es que sucede que lo llego a entender.

Unknown dijo...

sucede que no lo llego a entender.