Información blog

Linux, tutoriales, noticias, sistemas, redes y seguridad informática, entre otras cosas.

martes, 5 de febrero de 2013

Cap. final de iptables: La tabla mangle

La tabla mangle es con diferencia la menos usada de las tres que he explicado, pero yo creo que tiene su importancia pues se pueden llegar a hacer cosas interesantes con ella.  Cosas que de otra manera nos sería imposible de realizar. Por desgracia, esta tabla de por sí sola no hace gran cosa, pues la mayor parte de sus funcionalidades trabajan en conjunto con iproute2, que es la forma en la que llaman el conjunto ip route + ip rule. Por eso es conveniente explicar brevemente la herramienta ip, que es la herramienta que contiene aquellas utilidades entres otras.

Ip es una relativametne nueva herramienta de Linux que pronto derrocará por completo los antiguos comandos cómo ifconfig, arp o route; ya que reúne todas las funcionalidades de gestión de red en una sólo herramienta. Ip posee una larga lista de posibilidades, pero hay algunas que son más usadas que otras, por su relevancia en la administración de la red. Para una información más detallada escribir man ip. En este caso daré solo una pequeña explicación general algunas funcionalidades, para luego centrarme en las que en verdad me interesan: ip route e ip rule, que usaremos para que trabajen con la tabla “mangle”.

  • Ip link: Este comando trata las interfaces activas en linux, entre las cuales se incluyen las físicas(tarjetas de red) y/o virtuales. Este comando tiene diferentes posibilidades tales cómo ip link list o ip link show: muestra todas las interfaces con su información; ip link list nombre_dispositivo: muestra la información especifica de uno; ip link set nombre_dispositivo parámetros (up,down,off,on, dynamic on/off, alias [nombre],etc…): Modifica los parámetros FISICOS de la tarjeta, incluida la MAC por ejemplo pero no se puede modificar la ip y todos los cambios que se le hagan deben hacerse con la interfaz desactivada (ip link set dispositivo down).
  • Ip addr: Este comando te permite mostrar, añadir o borrar ips de una interfaz determinada. Todavía no la veo del todo cómoda, pues por ejemplo no me deja editar una ip sino hay que borrar la antigua e introducir la nueva, lo cual es algo engorroso. Ip addr add ip dev dispositivo: añade una ip al dispositivo deseado; Ip addr del ip dev dispositivo: borra una ip del dispositivo deseado; Ip addr show: muestra las direcciones ip de todos los dispositivos pudiendo especificar con el parámetro “dev” la interfaz deseada.
  • Ip neigh: Este comando emula el comando arp, en el cual podemos añadir una nueva entrada o simplemente mostrar aquellas ips que se encuentran dentro de la tabla arp. Los comandos más usados serían; ip neigh show: muestra las ips almacenadas dentro de la tabla arp. Estas ips se agregan cuando se hace ping a una alcanzable que esté dentro de nuestro rango o cuando añadimos una entrada arp o neigh a mano; ip neigh add/del [ip del otro equipo] lladdr [mac de dicha ip] dev [interfaz propia por el que localizaremos esa ip]: Añade o elimina una ip fija a lista de ips alcanzables.
  • Ip route: Este comando es uno de los que nos interesan para que trabaje junto a la tabla mangle de iptables. Se encarga del enrutamiento que tendrá el equipo y puede trabajar en equipo con ip rule. Los comandos más usados de ip route serían; ip route list: muestra las diferentes rutas y puertas de enlace configurados por el sistema; ip route add default via [ip de la puerta de enlace] dev [dispositivo enlazado a dicha puerta] table [nombre de la tabla]: Establece la puerta de enlace que tendrá la interfaz, el parámetro table es opcional, pero cuando trabajemos con mangle e ip rule será necesario y por eso lo menciono aunque explicaré su significado más adelante.
  • Ip rule: Este comando decide que ruta utilizar siguiendo ciertas reglas cómo por ejemplo la marca que tengan los paquetes. La explicación de este apartado sería bastante tediosa con lo que me centraré en los dos comandos más usados. Ip rule list: Muestra la lista de todas las reglas y sus acciones; ip rule add fwmark [numero] table [número o nombre de la tabla]: Dice que todo aquello de tenga la marca X (por ejemplo 1) se asigne automáticamente a la tabla deseada.

Llegados a este punto hablaré sobre las tablas, las cuales han sido mencionadas ya dos veces. Una tabla almacena las reglas de enrutamiento bajo una misma directiva, haciendo que todo aquello que se asigne a dicha tabla siga las directrices marcadas en dicha tabla. Las tablas van de 1 al 255 aunque las numero 255,254 y 253 están reservadas. Es recomendable no usar ninguna tabla que esté por debajo del número 200, cosa aconsejada por los desarrolladores del kernel de Linux. Cada tabla puede ser llamada haciendo referencia a su número, pero cómo todos somos humanos y nuestra memoria no es perfecta, es recomendable asignarle un nombre a cada tabla sobre la que queramos trabajar. Para eso escribimos echo [numero de tabla] [nombre] >> /etc/iproute2/rt_tables. ¡Importante poner >> y no > si no queremos eliminar el antiguo contenido del fichero! Ejemplo: echo 200 marcador >> /etc/iproute2/rt_tables.

Con esto ya tenemos una noción muy básica de lo que es capaz de hacer ip. Todavía puede hacer más cosas cómo el balanceo de carga o definición de tuneles pero con lo que ya sabemos nos es suficiente cómo para trabajar con iproute + iprule. Ahora nos falta conocer que podemos hacer con la tabla mangle:

La tabla mangle es muy sencilla una vez conocidas las tablas NAT y filter. Trabaja con las mismas cadenas que NAT además de usar la cadena FORWARD, aunque las más usadas y útiles son PREROUTING y POSTROUTING. Mangle al igual que NAT sirve para alterar paquetes, pero de forma mucho más sutil que su compañero. Esta tabla no cambia la ip ni hace nada que sea “visible” a primera vista, pero esas sutiles transformaciones pueden ser de gran ayuda dependiendo de nuestras necesidades. Para hacer dichas alteraciones su usan tres targets, aunque uno de ellos está en una fase muy temprana y no es recomendable usarlo pues no es apenas soportado y está en fase de desarrollo, con lo que sólo hablare de los dos que son “estables”.

  • TTL: El target TTL (Time To Live), sirve para establecer o modificar el tiempo de vida que tendrán los paquetes que cumplan la regla impuesta en iptables. Ello hace que los paquetes se destruyan pasar por X puntos o equipos o que todos los paquetes posean el mismo tiempo de vida. El target TTL tiene las siguientes opciones: TTL --ttl-set (numero): Establece un tiempo de vida exacto a los paquetes; TTL --ttl-dec (numero): Acorta el tiempo de vida en un número determinado de paquetes. Para este caso lo mejor sería poner un ejemplo:

Iptables –t mangle –A PREROUTING –i eth0 –j TTL --ttl-dec 2

Aquí decimos que todos los paquetes que lleguen por la interfaz eth0 acorten su tiempo de vida en 2. Es decir que si el tiempo de vida que tiene al llegar al equipo es de 60, su TTL pasaría a ser 58.

Evidentemente, al igual que podemos acortar su vida, también podemos alargarla mediante --ttl-inc (numero).

  • MARK: El target MARK es el más famoso de la tabla mangle. Sirve para marcar los paquetes que cumplan la regla impuesta en iptables. Esta marca sólo se mantiene dentro del equipo, una vez el paquete salga, dicha marca desaparece y sólo puede ser una marca numérica de 32 bits. Este target sólo tiene una opción que sirve para establecer la marca mediante MARK --set-mark. Ejemplo:

Iptables –t mangle –A PREROUTING –i eth0 –p tcp --dport 80 –j MARK --set-mark 1

En este caso todos los paquetes que hayan entrado por el puerto 80 mediante la interfaz eth0 han sido marcados con el número 1. El marcado de paquetes de por sí es inútil, pero combinado con iproute e iprule podemos hacer que los paquetes marcados con el número 1 sigan una ruta distinta del resto.

Con esto ya conocemos la tabla mangle. La modificación de la TTL es obvia, pero el marcado de paquetes y su utilidad todavía no ha quedado demasiado claro con lo que lo mejor será exponer un pequeño pero esclarecedor caso práctico con los pasos a seguir al respecto. Antes de explicar nada es indispensable (al igual que en NAT) tener el ip_forward igualado a 1, con lo que haremos (si es que no lo tenemos hecho ya):

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

Bien ahora os mostraré el esquema de este sencillo ejemplo:



Queremos gestionar que algunos paquetes generados por el equipo salgan por una puerta de enlace y otros por la otra, dependiendo del puerto. Primero añadimos dos tablas que representarán los dos routers:

echo 200 router1 >> /etc/iproute2/rt_tables
echo 201 router2 >> /etc/iproute2/rt_tables

Luego hacemos que cada tabla tenga asignada una marca especifica. Esto va a nuestro gusto pero para mantener una estructura les asignaremos las marcas 1 y 2.

ip rule add fwmark 1 table router1
ip rule add fwmark 2 table router2

Ahora asociamos las tablas a las puertas de enlace, en este caso los routers, teniendo en cuenta que dichas tablas harán que todos los paquetes con la misma marca que las tablas, vayan por la puerta de enlace de dichas tablas.

ip route add default via 192.168.1.1 dev eth0 table router1
ip route add default via 192.168.2.1 dev eth1 table router2

Con esto ya tenemos nuestras tablas preparadas para que todos los paquetes con las marcas 1 y 2 vayan por sus respectivos gateways. Ahora necesitamos marcar nuestros paquetes y para eso tenemos la tabla mangle. Una vez más yo recomiendo hacer un script que se ejecute en el arranque de Linux para tener las reglas activadas desde el arranque.

  1. #!/bin/bash
  2.  
  3. ### BEGIN INIT INFO
  4. # Provides:          Nombre del script
  5. # Required-Start:    $remote_fs  
  6. # Required-Stop:     $remote_fs  
  7. # Default-Start:     2 3 4 5
  8. # Default-Stop:      0 1 6
  9. # Short-Description: LSB
  10. # Description:       Codigo indispensable para respetar LSB
  11. ### END INIT INFO
  12.  
  13. iptables –t mangle –A OUTPUT –p tcp --dport 80 –j MARK --set-mark 1
  14. iptables –t mangle –A OUTPUT –p tcp --dport 22 –j MARK --set-mark 2
  15. iptables –t mangle –A OUTPUT –p tcp --dport 110 –j MARK --set-mark 1
  16. iptables –t mangle –A OUTPUT –p tcp --dport 20:21 –j MARK --set-mark 2
  17. iptables –t mangle –A OUTPUT –p tcp --dport 443 –j MARK –set-mark 1

Un pequeño pero funcional código que hace que los paquetes generados que pasen por el puerto 80,110 y 443 pasarán a través del ROUTER1 mientras que los paquetes que pasen por el puerto 20,21 y 22 pasarán por ROUTER2. Son casos rebuscados y poco usados pero que a veces pueden llegar a ser útiles. Sólo se necesita saber combinar iptables e iproute/iprule para encontrar la solución adecuada.

Espero que os haya resultado útil, un placer.

No hay comentarios :

Publicar un comentario