Enrutando en GNU/Linux

Habitualmente, cuando hablamos de enrutamiento ya sea en un router, un firewall o un servidor conectado a varias redes, siempre se hace referencia a enrutamiento por destino, es decir, si quiero llegar desde el nodo A hasta el nodo B, miro en mi tabla de rutas la forma más rapida (mejor métrica) de alcanzar el nodo B y envío el tráfico por la ruta especificada. Si no tengo ninguna ruta especifica al destino, usaré la ruta por defecto, no obstante, hay ocasiones en que esto no es suficiente.

Supongamos por ejemplo, tenemos un sistema GNU/Linux (IP forwarding activado) con una conexión a internet por defecto (ISP1). Por necesidades de la plataforma, añadimos una nueva conexion a internet, y queremos que el servidor 1 se conecte mediante el ISP1 (ISP por defecto), y el servidor 2, mediante la nueva conexión al ISP2. Esto lo conseguiremos mediante enrutamiento por origen(en ningín momento hablamos enrutamiento dinámico ni balanceo de carga de forma dinámica entre los multiples enlaces).

En las distribuciones modernas de GNU/Linux, la forma de gestionar toda la configuración de red (rutas, dispositivos, túneles, etc) es mediante el comando ip (sí, los comandos ipconfig o route están deprecated aunque sigan existiendo). En GNU/Linux nos podemos encontrar distintas tablas de rutas, las cuales aparecen indicadas en el fichero /etc/iproute2/rt_tables:

#
# reserved values
#
255	local
254	main
253	default
0	unspec
#
# local
#
#1	inr.ruhep

Como podemos ver, existe una tabla main, la cual contiene las rutas de nuestro sistema (lo que vemos formateado con el comando route):

ip route show table main

# Red directamente conectada ISP1
20.20.20.0/24 dev eth0  proto kernel  scope link  src 20.20.20.20 
# Red directamente conectada ISP2 
30.30.30.0/24 dev eth1  proto kernel  scope link  src 30.30.30.30
# Red directamente conectada LAN
10.10.10.0/24 dev eth2  proto kernel  scope link  src 10.10.10.254
# Ruta por defecto  
default via 20.20.20.254 dev eth0 				             

También existe una lista de reglas que hacen uso de dichas tablas para enrutar:

ip rule show 

0:	from all lookup local 
32766:	from all lookup main 
32767:	from all lookup default

Son estas reglas las que nos darán toda la potencia del enrutamiento por origen, manipulando la RPDB (routing policy database) de nuestro sistema GNU/Linux; para ello, primero creamos una nueva tabla de enrutamiento; existen identificadores de tablas reservados para el sistema, no obstante, los identificadores entre el 1 y el 252 están disponibles para los usuarios:

echo "250	ISP2" >> /etc/iproute2/rt_tables

Añadimos las rutas a la nueva tabla ISP2. Todo lo que no enrute la nueva tabla, sera enrutado por la tabla main, usando las políticas definidas por defecto en el sistema. Puesto que nuestro ejemplo es sencillo, únicamente crearemos una ruta por defecto hacia el ISP2 y mantendremos el resto de rutas igual que están definidas en la tabla main:

ip route add 20.20.20.0/24 dev eth0  proto kernel  scope link  src 20.20.20.20  table ISP2
ip route add 30.30.30.0/24 dev eth1  proto kernel  scope link  src 30.30.30.30  table ISP2
ip route add 10.10.10.0/24 dev eth2  proto kernel  scope link  src 10.10.10.254 table ISP2
ip route add default via 30.30.30.254 dev eth1 table ISP2 

ip route show table ISP2

20.20.20.0/24 dev eth0  proto kernel  scope link  src 20.20.20.20
30.30.30.0/24 dev eth1  proto kernel  scope link  src 30.30.30.30 
10.10.10.0/24 dev eth2  proto kernel  scope link  src 10.10.10.254 
default via 30.30.30.254 dev eth1

Llegados a este punto, creamos una nueva regla que nos permita el enrutamiento por origen del Servidor 2 usando la tabla de enrutamento creada, ISP2:

ip rule add from 10.10.10.200/32 table ISP2

Podemos observar que nos crea una nueva regla de enrutamiento:

ip rule show

0:	from all lookup 255 
32765:	from 10.10.10.200 lookup ISP2
32766:	from all lookup main 
32767:	from all lookup default

A continuación, borraríamos la cache de rutas (o solo las rutas de cada tabla) mediante el comando ip route flush, indicando los parámetros correctos dependiendo del caso, y comprobaríamos desde el Servidor 2, que tenemos conectividad con el exterior a través de la nueva conexión. Para finalizar, solo quedaría añadir las rutas y reglas de enrutamiento a uno de los ficheros de arranque del sistema (o al fichero de configuracion de red) para que lo cargara después de cada reinicio.

Otra solución válida sería por ejemplo, marcar paquetes con iptables y crear reglas de enrutamiento a partir de las marcas creadas.

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

Comments

  1. (sí, los comandos ipconfig o route están deprecated aunque sigan existiendo) <– Sera ifconfig ;)

  2. Eso, ifconfig. Un lapsus lo tiene cualquiera ;)

  3. Las politicas de enrutamiento son antiguas, sin embargo para darle mas alcance debes tener en cuenta que estas politicas no estan dentro de la tabla de enrutamiento del kernel; por lo que hay que crear un esquema de verificacion de canal, para el caso de llegar a fallar pase a la table de enrutamiento y encuentre la ruta activa.

    Saludos,

    Yamidt

  4. Gracias por el aporte Yamidt; revisare lo que comentas y si encuentro un hueco, ampliar el post o preparar uno nuevo.

    Saludos.

  5. Do you have this article in English somewhere? Thnx, Jeremy.

  6. Hi Jeremy

    We don’t have this article translated at this momente.

    Regards

Trackbacks

  1. […] Enrutando en GNU/Linux(…) Supongamos por ejemplo, tenemos un sistema GNU/Linux (IP forwarding activado) con una conexión a internet por defecto (ISP1). Por necesidades de la plataforma, añadimos una nueva conexion a internet, y queremos que el servidor 1 se conecte mediante el ISP1 (ISP por defecto), y el servidor 2, mediante la nueva conexión al ISP2… […]