Netfilter / IPTables II

Antes de comenzar te recomiendo que también visites lo siguientes posts ( NetFilter / IPTables  I, III, IV, V)

NetFilter y las cadenas de Adromeda

En este artículo haremos un repaso sobre el sistema de manejo de cadenas dentro de una tabla de iptables. Esto nos dara una poderosa herramienta para idear nuestro propio script de firewall.

Repasando

En el articulo anterior vimos el manejo de netfilter atravez de iptables.
Vimos que existen cuatro tablas: filter, raw, nat, y mangle.
Vimos que dentro de filter, existen 3 cadenas: INPUT, OUTPUT, y FORWARD.

Y vimos que podemos ingresar reglas en una cadena en particular usando “-A” ó “-I”.

Hagamos un ejemplo primero que nada para poder creer:

#!/bin/bash
alias iptables=’/sbin/iptables’

iptables -t filter -F #Borra todas las reglas de las cadenas de la tabla filter
iptables -t filter -Z #Borra los contadores de la tabla filter
iptables -t filter -X #Borra las cadenas definidas por el usuario

iptables -t nat -F #Adivinen….
iptables -t nat -Z
iptables -t nat -X

#Establecemos las políticas por defecto en reject
#Apartir de ingresar estas reglas nuestra maquina queda completamente aislada
iptables -P INPUT REJECT
iptables -P OUTPUT REJECT
iptables -P FORWARD REJECT
#En linux el la mayoria de las aplicaciones funcionan con el paradigma de cliente-servidor
#lo que involucra en muchos casos usar la interfaz de loopback, por lo que la desbloquearemos
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -i lo -j ACCEPT
#Habilitamos el SSH solo para la red interna (lo que además deberíamos hacerlo desde el sshd_config)
iptables -A INPUT -s 192.168.4.0/24 -i eth0 -d 192.168.4.1 -p tcp –dport 22 -j ACCEPT
#Aunque paresca redundante especificar algunas cosas. Por ejemplo -i eth0, si se supone que solo esa
#esa interfaz tiene una direccion en ese rango, sin embargo, estamos evitando posibles ataques
#de spoofing

iptables -A OUTPUT -d 192.168.4.0/24 -i eth0 -p tcp –sport 22 -j ACCEPT

#Como establecimos anteriormente las políticas cerradas por defecto, debemos habilitar a los paquetes,
#tanto a entrar como a salir, por eso la regla anterior.

#Habilitamos las consultas a los servidores dns
servidor_dns=”200.200.200.20x” #Variable que contiene el servidor dns (/etc/resolv.conf)
iptables -A INPUT -p udp -sport 53 -s $servidor_dns –dport 1024:65535 -j ACCEPT
iptables -A OUTPUT -p udp -dport 53 -d $servidor_dns –sport 1024:65535 -j ACCEPT
#Como vemos, nuevamente, habilitamos el ingreso y el egreso.
#Es importante tener en cuenta, que las consultas dns se hacen desde nuestro host,
#al puerto 53 del servidor dns (en este caso $servidor_dns) y se hacen desde los puertos 1024 al 65535.
#y obviamente la respuesta, la recivimos desde el puerto 53 al puerto desde el cual fue hecha la consulta

#Habilitamos el ICMP
iptables -A INPUT -p icmp -j ACCEPT
iptables -A OUTPUT -p icmp -j ACCEPT
#Existen distintas posturas en cuanto al icmp (si habilitarlo o no, y para donde) pero lo cierto, es que,
#la idea ahora es aprender iptables y no discutir las distintas escuelas de firewalling

# Y habilitamos NAT, es decir el ruteo a travez de nuestro servidor
echo 1 > /proc/sys/net/ipv4/ip_forward
#Esto habilita al kernel a reenviar los paquetes que vienen con intención de ser routeados

#Habilitamos mediante firewall al rango de la lan interna para ser reenviados
iptables -A FORWARD -s 192.168.4.0/24 -i eth0 -d 0.0.0.0/0 -j ACCEPT
# y luego habilitamos el nat
iptables -t nat -A POSTROUTING -s 192.168.4.0/24 -i eth0 -d 0.0.0.0/0 -j MASQUERADE
#Quizas esta regla no la entiendas del todo, pero lo que dice es que a todos los paquetes que son
#routeados, los envie con la direccion ip publica del servidor, y ademas guarda una tabla
#con las conexion que son nateadas, para que cuando lleguen las reenvie al host correspondiente

De aquí podemos empezar a comprender de forma un poco mas práctica como trabaja NetFilter.
Con un poco de trabajo, y aplicando lo que ya vimos podrías armar un firewall funcional y podría ser muy bueno, si aplicas tus conocimientos de scripting, sin embargo, no estarías utilizando todo el potencial de NetFilter.

Comentamos ya, en el artículo anterior, que podemos crear nuestras propias cadenas, y que esto brindaba una mayor flexibilidad a nuestro firewall.
Veamos exactamente de que estamos hablando…

Las cadenas hechas de reglas para las tablas!!!

Para visualizar de forma simple lo que queremos ver, vamos a suponer, que simplemente, tenemos un host especial, el cual, queremos tratar de forma única. Podemos suponer, que sera un host desde el cual controlaremos el servidor, o bien un host destinado a cierto tipo de testeo, en cualquier caso, lo importante sera, que este host en particular va a tener un tratamiento especial.

Siguiendo el metodo del script anterior, tendríamos que ingresar varias reglas para darle un tratamiento especial en cuanto a los puertos habilitados, y eso no seria demasiado complicado, sin embargo, si tubieramos varios tipos de host especiales, quizas se complicaría un poco.
Vuelvo a aclarar, que el escenario que estoy proponiendo es solo uno de los ejemplos posibles.

Definimos entonces a 204.34.33.3x como a la cual, queremos darle un tratamiento especial
Vamos a meter un poco de mano, para que se vea más:

#!/bin/bash
alias iptables=’/sbin/iptables’

#omito la seccion del flush para acortar
iptables -P INPUT REJECT
iptables -P OUTPUT REJECT
iptables -P FORWARD REJECT

#imaginemos que tenemos las mismas reglas que antes…
iptables -N tratamiento_especial
#Hemos creado una cadena nueva, y podemos verla, invocando el siguiente conjuro: iptables -L -n
#ó bien iptables -L tratamiento_especial

#Como queremos tratar de forma especial a este host, haremos que antes de aplicar
#alguna regla, verifiquemos si el paquete proviene de 204.34.33.3x
#para lo cual insertaremos la regla arriba de todas para que sea la primera en comparar
iptables -I INPUT -s 204.34.33.3x -j tratamiento_especial
#Recordemos que “-I” sin ningún numero, inserta la regla por ensima de las demas regla de la cadena
#Por lo que lisa y llanamente, todo lo que provenga de 204.34.33.3x, se comparará con
#las reglas de la cadena tratamiento_especial
#De la misma manera que agregamos (-A) reglas a las cadenas INPUT ó OUTPUT ó bien FORWARD
#podemos agregar reglas a las cadenas que creemos nosotros
iptables -A tratamiento_especial -p tcp –dport 1:1023 -j ACCEPT
iptables -A tratamiento_especial -p udp –dport 1:1023 -j ACCEPT

Bien, te recomiendo que hagas un iptables -L -n, para ver como las reglas se insertan una tras otra en la cadena tratamiento_especial, además podes insertar una regla a mano (desde la consola) con la opción “-I” y ver como se posiciona en el primer lugar.

Lo que sucederá aquí, es lo siguiente:
#A todos los paquetes que ingresen (no destinados a ser routeados) ( INPUT )
Si el paquete proviene de la ip 204.34.33.3x saltamos a la tabla de tratamiento_especial
SI la interfaz es “lo”, es aceptado
Si el paquete proviene de la red 192.168.4.0/24 y viene hacia el puerto 22 tcp a travez de la interfaz eth0, es aceptado
Si el paquete es udp y proviene del puerto 53 del servidor DNS y tiene como destino un puerto entre
el 1024 y el 65535, es aceptado
Si no cumple con ninguna la politíca es REJECTarlo

Por lo cual, cualquier paquete que ingrese al host, verificará si se cumple la primer regla, si se cumple,
automaticamente pasará a comprobar las reglas establecidas en tratamiento especial, y estas indican que:
Si es un paquete tcp entre el puerto 1024 y el 65535, es aceptado
Si es un paquete udp entre el puerto 1024 y el 65535, es aceptado

Si el paquete no proviene del host 204.34.33.3x, entonces seguira las comprobaciones (si proviene de la interfaz lo, si proviene de 192.168.4.0/24.. etc)

Ahora bien, si suponemos que ingresa un paquete icmp proveniente del paquete 204.34.33.3x, este ingresará en la tabla de tratamiento especial, pero no coincidirá con ninguna de las reglas allí establecidas… que pasará?
Se aplica la politica por defecto de rechazarlo?
Se aplica continua con las comprobaciones de la cadena INPUT?

La respuesta a la primera pregunta es NO
Simplemente por que las cadenas creadas personalmente no tienen politica, para ver esto, pueden ejecutar,
el conocido comando de listado iptables -L ó bien iptables -L tratamiento_especial. Donde podemos diferenciar de las cadenas pre establecidas que no existe una política (Policy)
La respuesta a la siguiente pregunta es SI,
si el paquete fuera icmp, ‘cruzaría’ la tabla tratamiento_especial y seguiría nuevamente por las reglas de la cadena INPUT, donde llegaria hasta la regla que dice que si el paquete es icmp, sin importar de donde venga o vaya, es aceptado.
Sin embargo, si esto no es lo que Uds esperaban, no se preocupen, por que se puede arreglar.
Como habran visto, cada vez que mandamos un paquete hacia un objetivo (“-j ACCEPT, o -j tratamiento_especial)
usamos la opción “-j”, que viene de “jump”, saltar.
Pero existe otra opción, similar a sentencias de los lenguajes de programación modulares, y esta es “-g” ó “–goto”.
Si usaramos:
iptables -I INPUT -s 204.34.33.3x -g tratamiento_especial
en lugar de
iptables -I INPUT -s 204.34.33.3x -j tratamiento_especial
En tonces, el paquete icmp, que no queda atrapado en ninguna regla de la cadena tratamiento_especial, simplemente, se le aplica la politica por defecto de INPUT.

Antes de terminar, hagamos unas pruebas para que todo esto sea verdaderamente comprobable y ya no creas mas por fe, si no antes bien, que prácticamente lo palpes.

Haremos pruebas con una herramienta muy util y ancestral… el ping.

#!/bin/bash
iptables -P INPUT DROP #Por política rechazo todo
iptables -A INPUT -i lo -j ACCEPT #acepto todo lo que pase por la interfaz de loopback
iptables -A INPUT -p tcp -j ACCEPT #acepto todo lo que sea tcp
iptables -A INPUT -p udp -j ACCEPT #acepto todo lo que sea udp
#Es decir que lo unico que queda bloqueado es el imcp

iptables -N tratamiento_icmp #creamos la cadena tratamiento_icmp
iptables -A tratamiento_icmp -i lo -j ACCEPT #ingresamos una regla a la cadena que acepta
#todo lo que ingresa por la interfaz loopback

iptables -I INPUT -p icmp -g tratamiento_icmp
#Ingresamos una regla en INPUT para que todo lo que sea ICMP lo envie a la cadena tratamiento_icmp
#hubiese sido lo mismo, definir la cadena tratamiento_icmp primero, y luego usar
# iptables -A INPUT -p icmp -g tratamiento_icmp

Ahora bien, con este script, podemos modificar la opcion -g por -j para probar los distintos funcionamientos
La primera prueba seria, correr el script así solito, y usar el comando: ping localhost, y como todo lo que sea icmp que venga por la interfaz “lo”, sera enviado (con –goto) a la cadena tratamiento_icmp, el ping responderá , ya que queda atrapado en la primera (y única) regla de la cadena, la cual acepta el icmp.

Ahora es cuestion que uses tu imaginación y observes si los cambios que haces en el script son los esperados o no, hasta que tu mente comienze ver iptables como el mejor amigo de un segu-geek!

Hay mas pruebas, pero la idea no es darte todo masticado… 😀
Si se te ocurre algun aporte o algo te parece confuso comentamelo.
Hasta el proximo!!!

Anuncios

2 comentarios to “Netfilter / IPTables II”

  1. NetFilter / IPTables V « NetVulcano Says:

    […] 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, […]

  2. Net Secure » NetFilter / IPTables VI Says:

    […] en el segundo artículo, repasamos la forma de trabajar de los targets (jumps y goto), y conocemos por demás los […]


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: