NetFilter / IPTables V

Matcheteando todo!

Antes de comenzar te recomiendo ver los post anteriores ( NetFilter / IPTables I, II, III, IV)
Finalmente podemos entrar en este tema, del cual no se suele hablar mucho, y sin embargo a mi me parece por demás útil!!
Los matches de NetFilter, convierten a este firewall en un excelente sistema de filtrado y protección para nuestro sistema, por lo que trataremos de dar una vislumbre de este amplio tema.

La verdad de la milanesa

Mencionamos en el articulo anterior que existen una buena variedad de matchs, que nos provee netfilter, para poder precisar nuestras reglas.
Vamos a ir viendo uno por uno estos matchs para poder exprimir al maximo nuestro firewall.

Nota: Los ejemplos mostrados actualmente carecen de una explicación completa de un uso real posible, son solo un ejemplo de como usarlos en una cadena.

Para comenzar, es necesario mencionar una de las funcionalidades, que le otorgan tanto poder a NetFilter, que a diferencia de lo que imaginan que voy a decir, no es el sistema de matches, si no que (además) Netfilter posee un modulo llamado Conntrack, o Connection Tracking.

Este tal ‘conntrack’,  provee herramientas, para manejar las conexiones, de una forma avanzanda..

Lo que hace, es vigilar las conexiones, darles un seguimiento y relacionarlas, para que, no solo podamos establecer reglas sobre las peticiones o respuestas (considerando los paquetes de forma individual), si no sobre los flujos de información/datos que pasan a travez de nuestro Firewall.
Para esto, a las conexiones se les asigna ‘estados’. Con este ‘etiquetamiento’ de estados, NetFilter puede ejecutar una serie de herramientas, que lo vuelven muy poderoso. Una de las facultades que adquiere, es filtrar paquetes, dependiendo de si están asociados a una conexión y el estado de la misma. Esto se podrá entender cuando veamos los distintos matchs que utilizan Connection Tracking.

(Se puede evitar que netfilter haga este seguimiento mediante la tabla raw antes vista)

Los estados de una conexión pueden ser los siguientes:
INVALID,  NEW, ESTABLISHED, RELATED, SNAT, DNAT, NONE, EXPECTED, SEEN_REPLY, ASSURED, CONFIRMED.
No voy a explicarlos a todos aqui, por que haciendo una man iptables ,pueden ver una pequeña pero suficiente explicación de cada uno de los estados.

Para acentar el conocimiento sobre este modulo, podemos prácticar algo con el primer match que estudiaremos:

State

Este match, favorito y muy popular en los scripts de firewalls, permite tomar el estado de una conexión (sea tcp , udp, o icmp).
Primero veamos cuales son los posibles estados de una conexión a matchear:

NEW, ESTABLISHED, RELATED, e INVALID
Sus nombres son muy descriptivos, hasta para los que no saben ingles.
NEW: Se da en conexiones ‘nuevas’,  en el caso de una conexión tcp, estariamos hablando del primer SYN (el que abre juego) del SYN/ACK ( la respuesta) y el ACK ( de confimación). En conexiones UDP,  en realidad no hay una ‘conexión’, sin embargo por razones que exceden este articulo, se toma al primer paquete udp enviado a un puerto como NEW, y en caso del ICMP,  pasa lo mismo, tomandose el primer paquete para el estado NEW (por ejemplo un ICMP ECHO REQUEST).

ESTABLISHED : Son las conexiones, que (valga la redundancia) estan ya establecidas, en TCP, hablamos de los paquetes que no sean los primeros 3, y dependiendo que quien envie el FIN/ACK los últimos paquetes necesarios para cerrar la conexión, en UDP son los paquetes que provienen del mismo puerto del que se mando un paquete en ‘estado NEW’, ICMP se considera established, miestras se espera la respuesta al mensaje enviado.

RELATED
: Son los paquetes que inician una nueva conexión, pero que esta asociada a otra. Por ejemplo cuando al inicio de una conexión TCP, se le responde con un mensaje ICMP, o lo mismo para UDP, o las conexiones FTP…

INVALID : Simplemente, cuando un paquete es erroneo o no reconocido, y se toma como invalido

Una vez comprendido esto, resta ver como matchear:

[ ! ] –state : Es posible listar los estados posibles que puede tener el paquete para que sea ‘atrapado’ en la regla, por ejemplo: «NEW,ESTABLISHED» o «RELATED,INVALID», o la conbinación (y cantidad) que les paresca.

Ejemplo:

iptables -A INPUT -i eth1 -m state –state ESTABLISHED,RELATED -j ACCEPT
Esto acepta todas las conexiones que estan en estado «related» o «established» (ver arriba)

Conntrack

Este match, tiene en sus manos herramientas que sirven para interfacear el trabajo del módulo llamado del mismo nombre. Es decir, nos otorga cierto control sobre el Connection Tracking del Kernel. En particular, es una forma avanzada del modulo anterior (state, al que de alguna manera podemos ver como una interfaz).
Por ejemplo:

[ ! ] –ctstate : Matchea si una conexión se encuentra en uno de los estados listados como argumento a esta opción. (pe: NEW,ESTABLISHED)
[ ! ] –ctproto : Matchea si coincide el protocolo (TCP, UDP, ICMP)

Como explicamos antes, Conntrack, hace que los paquetes no se vean, como simples paquetes individuales, si no que esten relacionados cuando pertenecen a una misma conexión. Las siguientes opciones nos permiten detectar paquetes que pertenezcan a una conexión:
[ ! ] –ctorigsrc address[/mask] :  Donde la ip de origen es la especificada («Address[/mask]»)
[ ! ] –ctorigdst address[/mask] : Donde la ip de destino es la especificada («Address[/mask]»)
[ ! ] –ctreplsrc address[/mask] : Donde la ip de origen que responde (reply) es la especificada (esto es casi igual a ctorigsrc)
[ ! ] –ctrepldst address[/mask] : Donde la ip de destino que responde (reply) es la especificada (casi igual a ctdstsrc)

Las demas son iguales solo que correspondientes a un puerto.
[ ! ] –ctorigsrcport port
[ ! ] –ctorigdstport port
[ ! ] –ctreplsrcport port
[ ! ] –ctrepldstport port

[ ! ] –ctstatus : Detecta los estados de una conexión, los cuales pueden ser los siguientes: NONE, EXPECTED, SEEN_REPLY, ASSURED.
[ ! ] –ctexpire : Detecta según la cantidad de segundos que le faltan a una cionexión para expirar. Es decir para que Netfilter / Conntrack la considere muerta

–ctdir : Detecta si los paquetes son «ORIGINAL» o «REPLY», si no se especifica, se considera los dos casos.

Como vemos, conntrack (el match) es una forma avanzada de state.

Ejemplo:

iptables -A INPUT -p tcp -m conntrack –ctstate  ESTABLISHED, RELATED  -j ACCEPT

En este ejemplo, volvemos a realizar lo que hicimos en el ejemplo anterior,  solo para mostrar que es lo mismo.

iptables -A INPUT -p tcp -m conntrack –ctorigsrc 10.1.10.0/24 -j ACCEPT

Ahora, para mostrar que este modulo es mas avanzado que state, lo que hacemos es lo siguiente: Aceptamos las conexiones, que (en el módulo conntrack ) tengan la ip origen en 10.1.10.0/24

TTL

Conociendo un poco la arquitectura del protocolo IP, veremos que si no existiera el TTL los paquetes podrían dar vueltas por internet indefinidamente, o nunca llegarían.
Que es el TTL? Time to Life, tiempo de vida.
El TTL, es una propiedad de la cabezera IP, en si, es solo un número que se decrementa, cada vez que atravieza un gateway (o pasarela). Y sirve
justamente, para que un paquete, no pueda quedar andando por pasarelas, como un fantasma sin destino.
Todos los paquetes IP, son generados este contador, cuyo número máximo, puede ser 255. Al pasar por cualquier Host o pasarela, se debe decrementar en uno, este contador, y si el contador es 0 se debe eliminar este paquete.

El típico ejemplo, cuando se habla de TTL, es hablar del «traceroute», ya que lo que hace este programita, es enviar paquetes ICMP, incrementando el valor TTL, de esta manera, el primer paquete, sale con un TTL en 1, al llegar a la «puerta de enlace», esta informa que el «paquete murio en transito», así, con el mensaje de error, se obtiene la ip del primer salto y se lo informa por pantalla, el segundo lo envia con TTL dos, y muere en el siguiente host, y asi sucesivamente.

Mucho ruido y pocas noeces..

Ok, Podemos usar las siguientes opciones:

–ttl-eq : Matchea si el ttl es igual al número pasado como argumento
–ttl-gt : Matchea si el ttl es más grande que el número pasado como argumento
–ttl-lt : Matchea si el ttl es mas chico que el número pasado como argumento

Ejemplo:

iptables -A INPUT -p icmp -m ttl –ttl-lt 15 -j DROP

El TTL, es ignorado por la mayoria, sin embargo este campo del paquete ip, puede llegar a ser usado para obtener información valiosa.
En este caso,  rechazando los paquetes icmp con ttl menor a 15, evitamos por ejemplo ciertos «traceroutes», lo que me inspira a escribir algún otro post sobre el asunto.

Multiport

Usando este match junto a «-p tcp» o «-p udp», podemos especificar rangos de puertos, tanto de origen como de destino.
–source-ports : Lista de puertos, o rango de puertos de origen
–destination-ports : Lista de puertos, o rango de puertos de destino
–ports : Lista o rango de puertos, indistinto si es de destino o de origen.
Aclaro, que Multiport matchea si el puerto del paquete (tcp o udp) coincide con cualquiera de los puertos en la lista o rango.
Se puede anteponer «!» para especificar lo contrario. (Ej. «! –ports 3:90»)

– De ahora en mas usaré [ ! ], para indicar que vale usar el «!» para negar lo especificado –

Ejemplo:

iptables -A INPUT -p tcp -m multiport –source-ports 1:1024 -j ACCEPT

Aca, aceptamos las conexiones entrantes (tcp) que provengan de los puertos 1 al 1024.  Estos puertos suelen ser solo manejados por el administrador de sistema, por lo que para que alguien puede iniciar una conexión desde esos puertos, significa que tiene acceso root (en los unix) o administrador (en los windows). Si tenemos una política restrictiva entrante (es decir -P INPUT REJECT),  estaríamos aceptando conexiones de otros sistemas, que solo pueda ser iniciadas por un root/administrador .

MAC

Cualquiera que tenga un AP con linux, le puede ser de mucha utilidad este match, y para quienes no seguramente que también.
Deben estar imaginando, que este match les permitira filtrar mediante MAC, y estan en lo cierto,
Espero que también hallan imaginado, que este modulo solo se puede usar en las cadenas de ingresos (PREROUTING, INPUT y FORWARD) de paquetes, por que también estarán en lo cierto, lo que es completamente lógico.
[ ! ] –source-mac : Se pasa como argumento la mac, con el formato «xx:xx:xx:xx:xx:xx»

Ejemplo:

iptables -A INPUT -m mac –source-mac aa:bb:cc:dd:ee:ff -j DROP

Mas facil, imposible. Esta cadena, rechaza las conexiones desde la mac aa:bb:cc:dd:ee:ff

DSCP

Existe en la cabezera IP, una serie de bits destinados a servir como flags para el servicio diferenciado, como no existe un estandar, algunos usan DSCP y otros TOS.
[ ! ] –dscp : Matchea si el valor del paquete es el indicado.
[ ! ] –dscp-class : Matchea por clase, y los valores posibles son BE, EF,AFxx o CSx.

Ejemplo:

iptables -I OUTPUT  -m dcsp –dscp 16 -j REJECT

Esta cadena, reject el uso de dscp con valor 16, de un paquete saliente. Sinceramente poco usado (hasta donde la experiencia) me muestra.

TOS

Como explicaba anteriormente, TOS es una implementación para tener en cuenta el tipo de servicio.
[ ! ] –tos : Matchea si corresponde el valor de TOS
Valores posibles:

(0x10) 16 Minimize-Delay
(0x08)  8 Maximize-Throughput
(0x04)  4 Maximize-Reliability
(0x02)  2 Minimize-Cost
(0x00)  0 Normal-Service

Ejemplo:

iptables -A INPUT -m tos –tos 0x10 -j DROP

Dropeamos todo lo entrant con TOS 16. Hoy en dia TOS es usado para implementar QoS, sumamente importante para priorizar tráfico, o controlar el ancho de banda.

Recent

Este, es uno de los módulos mas interesantes!
Es que puede ayudarnos a detectar DoS, DDoS, o incluso escaneos!
Prestemos un poco de atención:
La pegada de «recent», es que genera una lista (o varias) de ips, las cuales, luego, podemos utilizar en otra regla de iptables.
Si fueramos un super administrador, hariamos que nuestro firewall nos tiere un log de todas las ip que se conectan con nosotros, y estariamos todo el tiempo, haciendo un tail de log, para ver si alguien esta intentando realizarnos un DoS, pero como nostros somos más que un super administrador ( 😛 ), dejaremos que NetFilter sea quien trabaje por nosotros. Por lo que vamos a pedirle, que todas las conexiones que ingresen al puerto 80 sean controladas.. de que forma?
Pues pediremos que solo puedan hacer  5 conexiones (nuevas) cada 10 segundos.
Primero le diremos a iptables, como queremos que se cree la lista:

iptables -A INPUT -i eth1 -p tcp –dport 80 –tcp-flags ALL SYN  -m recent –set

Así solito nomas, entonces, todas las conexiones que sean tcp dirigidas al puerto 80, con solo el flag SYN activado, seran puestas en la lista.
Y ahora descartamos los paquetes que se excedan:

iptables -A INPUT -i eth1 -p tcp –dport –tcp-flags ALL SYN -m recent –update –seconds 10 –hitcount 5 -j DROP

Je… Y si todabia no entendes bien como funciona? Ok, veamos!

Cada vez que un paquete matchea contra la primer regla, pasa a listarse en un archivo /proc/net/ipt_recent/DEFAULT.
El archivo, es «DEFAULT», por que no le pusimos un nombre especifico a la lista, pero podemos usar «–name» para otorgarle un nombre particular, lo que nos permite hacer distintos tipos de listas para distintas puertos o aplicaciones, o lo que nuestra imaginación nos dicte.
Recent, anota cada ip que matchea contra la primer regla en /proc/net/ipt_recent/nombre_que_pusimos | DEFAULT, y si matchea mas de una vez, sobre escribe esa linea, anotando la cantidad de veces que lleva matcheando. Como la primer regla, no tiene objetivo, la compración sigue camino, y al matchear con la segunda regla,
recent, obtiene la orden de limpiar la lista si se cumplio los 10 segundos, y en este caso, si alguna ip, matcheo 5 veces, pasa a cumplirse la regla y se ejecuta el DROP sobre tal IP.

Luego de este articulo, vere de escribir uno que se dedique a usar herramientas para probar estas cosas.

TCPMSS

La cabecera TCP define un flag, que programa el tamaño maximo de un segmento (paquete tcp), esto puede se útil en redes de diferente MTU, o bien en conexiones que necesiten cierto tamaño de paquetes. Este match nos permite matchear un paquete segun el MSS (Maximun Segment Size), pudiendo usar un número o un rango.

[ ! ] –mss : Valor del MSS precisado para matchear.

Ejemplo:

iptables -A OUTPUT -p tcp -m tcpmss –mss 2000:3000

Este flag de tcp es opcional y solo se puede usar en el segmento tcp que inicia la conexión (el primer SYN). Por lo que esta cadena matchea con los segmentos tcp salientes que contengan el MSS puesto entre 2000 o 3000

AH/ESP

Estos dos módulos, Ah y ESP, sirven para quienes esten usando IPSec, y les permite leer en la cabezera ip, los valores SPI de AH o ESP.

[ ! ] –espspi : Se especifica el valor SPI

[ ! ] –ahspi : Se especifica el valor SPI

Owner

Una de las particularidades de los sistemas unix, es la forma estructurada de otorgar permisos, que se implementa a travez de los usuarios. Estos son dueños de las cosas que crean, y de los recursos asignados. Este match utiliza esa propiedad, para verificar, que socket pertenece a que usuario, y nos permite delimitar una regla segun esa carácteristica.(solo valido para cadenas OUTPUT y POSTROUTING)

[ ! ] –uid-owner : Se puede utilizar como argumento, el nombre de usuario, el numero de usuario o un rango de numeros de usuarios

[ ! ] –gid-owner : Exactamente igual que uid-owner pero con nombres y numeros de grupos.

[ ! ] –socket-exists : Matchea si un paquete esta asociado con un socket.

Ejemplo:

iptables -A OUTPUT -p udp -m owner –uid-owner 1004:1007 -j REJECT

En esta cadena, rejecto los paquetes udp creados por los usuarios con id 1004 a 1007. Util por ejemplo, para denegar el trafico P2P.

Packet Type

Simple modulo que permite detectar paquetes de la capa de Link (Modelo OSI). Los tipos de paquetes exsitentes son unicast,broadcast o multicast.

Ejemplo:

iptables -A INPUT -m pkttype –pkt-type multicast -j REJECT

Detecta un paquete multicast y lo rejecta.

Mark

Mark, sirve para detectar paquetes marcados por el kernel (con el objetivo Mark) y solo sirve dentro del host que se maque, es decir, la «marca» no será detectada en otro host o nodo de la red, solo es una maca de uso interno, ya que verdaderamente no afecta al paquete, si no que es otorgada mediante el módulo Conntrack antes explicado. Sirve para, por ejemplo, establecer rutas segun dichas marcas. La «marca» debe ser un numero entero entre 1 y 4294967296.

Ejemplo:

iptables -A POSTROUTING -p tcp –dport 80 -m mark –mark 1233 -j LOG –log-prefix  «LOADBALANCING»

Esta cadena, encuentra los segmentos tcp destinados al puerto 80, que estan siendo enrutados, y poseen una marca (numero 1233) y loguea dicha actividad. El modulo Mark, se utiliza en conjunto con IPROUTE2, el cual generalmente esta relacionado con balanceo de carga (aunque su utilidad va mas alla de eso)

Limit

Otro paquete favorito para scripts de firewalls, ya que provee la opción de limitar la cantidad de paquetes que matchean contra la regla. Esto significa que se pueden armar reglas para por ejemplo evitar DoS, o usarlo en combinación con el objetivo LOG, para generar logs de ciertas conexiones.

Limit, tiene dos parametros para matchear, el primero, es la cantidad de veces que se cumple la regla en un determinado tiempo, y el otro parametro, es la cantidad de veces que se cumplirá la regla antes de que se aplique el match.
Para poner un ejemplo, hablemos de un ataque muy común, un SYN Flood.
SYN Flood, es un ataque DoS, donde un atacante envia una gran cantidad de paquetes TCP, con el flag SYN activado. Cuando se recive un SYN, el host responde el ‘saludo’ y espera la confimación de la otra parte, pero en un ataque SYN Flood, esto no sucede, ya que el objetivo del ataque, es que el host receptor quede a la espera, y al quedar a la espera de muchas conexiónes… crush! DoS!

Como lo solucionamos? Ok, NetFilter al rescate!

iptables -A INPUT -p tcp --syn -m limit --limit 2/second  --limit-burst 5 -j DROP

Esto se traduce a: Una vez que se hayan recibido una rafaga (burst) de 5 paquetes TCP con el Flag SYN activado, se comenzaran a recibir los paquetes si se reciben de a 2 por segundos, los demas se dropearan.

Length

Interesante y simple modulo, que mide el largo de los paquetes.

Ejemplo:

iptables -A INPUT -p tcp -m length –length 64:1500 -j ACCEPT

Dejamos pasar los paquetes que solo tengan un tamaño entre 64 y 1500 bytes.

Ip Range

Match super útil, en particular si se convina con otros matches, permite establecer rangos ip, tanto de destino como de origen.

Ejemplo:

iptables -A INPUT -m iprange --src-range 192.168.1.1-192.168.1.14 -j DROP

Simple, dropea todos los paquetes provenientes del rango 192.168.1.1 al 1.14

Helper

Helper, es un módulo, que puede resultar un tanto místico, sin embargo, si se tiene en cuenta, le trabajo que hace el módulo conntrack, resulta evidente su forma de trabajo.
El ejemplo más común, para explicar este match, es hablar de FTP, que como es sabido, utiliza dos puertos para realizar una transferencia de archivos.
En el primer puerto, generalmente el 21, se establece una sesión donde se ejecutan comandos, y si es necesario, se abre un segundo puerto (generalmente el 20), el cual sirve para la transferencia de los datos de los archivos.
Helper, entonces, serviría para reconocer, cuando una conexión hecha en el puerto 20, es hija de otra conexión, es decir esta relacionada, o creada, por otra conexión.
Entonces usando «-m helper –helper ftp-20» le diremos a NetFilter, que una conexión en el puerto 20, puede ser hija de una conexión de protocolo FTP.

ECN

ECN es par de bits dentro de la cabecera IP (v4), especificado, para el aviso de congestion de una red o host. La funcionalidad de este match, es detectar, si un paquete contiene estos bits activados

[ ! ] –ecn-tcp-cwr : Matchea si el bit Congestion Window Received esta activado
[ ! ] –ecn-tcp-ece : Detecta el ECN Echo
[ ! ] –ecn-ip-ect : Seguido de un número (entre 0 y 3) espesifica al ECN-Capable Transport

Si no entendes bien para que sirve el ECN, te puede quedar claro, pensando que IP no tiene un sistema de control de recepción de paquetes, y lo mismo pasa para udp, como en este mundo abunda la tecnodiversidad, no todos los nodos aplican esta opción y no es muy posible que te encuentres en un caso que necesites usar este modulo, pero si en algun momento lo necesitas, espero se te venga a la mente que netfilter , si esta preparado para ello.

En fin, hemos dado un vistaso a una serie de herramientas, que nos dan mucho, muchisimo control sobre todo lo que atravieza nuestro host, y hemos demostrado que NetFilter es uno de los mas completos firewalls existentes…

Aún me queda por mostrar los posibles targets y herramientas para comprobar todo este tipo de utilidades que nos da NetFilter, pero por ahora hay bastante por leer. Espero en un futuro cercano compilar todo en un solo doc.

Pero como saber mover las piezas de un tablero de ajedrez, no te convierte en un gran ajedrecista, esto es solo el comienzo……

4 respuestas to “NetFilter / IPTables V”

  1. NetFilter / IPTables I « NetVulcano Says:

    […] NetFilter / IPTables I Diciembre 2, 2008 at 1:42 pm | In Articulos | 1 Comment Tags: firewall, ip, iptables, linux, netfilter, red, seguridad Antes de comenzar te recomiendo que también visites lo siguientes posts ( NetFilter / IPTables  II, III, IV, V) […]

  2. Jose Levy Says:

    que excelente documento. felicitaciones

  3. Flags del Kernel para Firewall o Tuneando el /proc « NetVulcano Says:

    […] A la hora de armar un Firewall para nuestro linux, no es cuestión de ejecutar cualquier script a fin, si no conocer bien que es lo que necesitamos, para que y como. El conocer estas variables nos permite conocer donde debemos tocar en caso de ser necesario. Para complementar este conocimiento recomiendo leer las fuentes expuestas mas abajo y leer los siguientes artículos: NetFilter / IPTables I, II, III, IV, V […]

  4. Net Secure » NetFilter / IPTables I Says:

    […] Bueno, aunque hay pocas cosas prácticas, suficiente por este post, mirate los siguientes: II, III, IV, V […]


Deja un comentario