PBR (Policy Based Routing) en Linux

«Si quieres ser universal habla de tu aldea«, esta frase lo que viene a decir es que para saber donde ir es importante saber de donde se viene; esto quizás parezca no tener sentido en linux, pero a veces queremos llegar a un destino dependiendo únicamente del destino (routing) y otra vez queremos llegar a un destino teniendo en cuenta el origen (policy based routing – PBR).

Ni que decir que siempre que se pueda el PBR hay que evitarlo por millones de razones como la simplicidad, gestión, uso optimo de recursos, claridad, comprensión de arquitectura …

Antes de nada hay que definir que son las tablas de routing policy y las reglas de policy routing.

Las tablas hacen referencia las distintas tablas de routing existentes en nuestra máquina, por ejemplo la ruta por defecto puede ser una u otra dependiendo de la tabla en la que nuestro tráfico encaje y nuestro tráfico encaja en una tabla u otra dependiendo de las reglas de policy routing, según vayamos avanzando lo veremos más claro.

En Linux tenemos por defecto tres tablas de policy routing (Policy Routing Tables):

  1. 255 local -> No modificable
  2. 254 main
  3. 253 default

Y tenemos una única regla de policy routing por tabla, la ruta por defecto.

En linux para tener PBR necesitaremos como mínimo tres cosas:

  1. Al menos una tabla de policy routing que no sea las de por defecto (Custom Policy Routing Table)
  2. Crear al menos una regla de policy routing personalizada para esa tabla de policy routing que hemos creado.
  3. Propagar eso a los demás routers.

Para crear las tablas de policy routing lo primero que hay que hacer es definirlas, para eso editaremos el fichero /etc/iproute2/rt_tables que por defecto tiene este contenido

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

Y añadiremos nuestra tabla personalizada:

echo 200 custom >>  /etc/iproute2/rt_tables

En este punto procederemos a crear la regla de policy routing, por ejemplo que todo lo que venga de la 10.10.10.10 se vaya a la tabla custom que acabamos de crear.

ip rule add from <ip_origen> lookup <tabla_policy_routing>

ip rule add from 10.10.10.10 lookup custom

Por supuesto esto se puede complicar un poquito más y podemos crear reglas de policy routing dependiendo del ToS o incluso jugar con el NAT.

En el momento en que tenemos definida la regla de policy routing y la tabla de policy routing sólo nos quedará definir las rutas a utilizar, para ello lo haremos como el siguiente ejemplo:

ip route add default via 1.1.1.1 dev eth1 table custom

Y una vez hecho todo esto lo que queremos es que se mantenga todo después de arrancar, para eso tenemos que añadir al fichero /etc/network/interfaces las siguientes líneas:

post-up ip rule add from 10.10.10.10 lookup custom

post-up ip route add default via 1.1.1.1 dev eth1 table custom

pre-down ip route del default via 1.1.1.1 dev eth1 table custom

pre-down  ip rule del from 10.10.10.10 lookup custom

Obviamente si queremos utilizar la caja linux para que encamine tráfico, que haga de router, tendremos que permitir el ip forward, para ello:

echo 1 > /proc/sys/net/ipv4/ip_forward

O bien para que se habilite cada vez que arranca la máquina

echo «net.ipv4.ip_forward=1» >> /etc/sysctl.conf

Si queréis ampliar os recomiendo que leáis esto.