NetFilter / IPTables IV

Antes de comenzar te recomiendo ver los post anteriores ( NetFilter / IPTables I, II, III, V)

IPTables el un amigo del usuario

Esta entrega sobre Netfilter / Iptables, vamos a dejar atras ya a las cadenas y las tablas, para centrarnos un poco mas en los comandos para ingresar, borrar, remplazar y ordenar las reglas y  la primera parte de los Matchs!

Sentencia de muerte!

Hace tiempo venimos ‘tuneando’ nuestro firewall y estamos muy conformes, sin embargo, hay cosas que aun no sabemos hacer y quedaremos encantados cuando conozcamos como usarlas.

Para adentrarnos en el tema, tenemos que ver cual es la forma en que usamos iptables por costumbre:

iptables [ -t table ] command [ match ] [ target ]

donde
[ -t table ]: table puede ser filter, nat, mangle o raw, lo vimos en el articulo anterior

command: Indica que es lo que queremos hacer con la regla (hasta ahora usamos -A y -I para insertar las reglas en un cadena, pero se puede hacer mas que eso.

[ match ]: Son las condiciones que debe reunir un paquete para quedar ‘atrapado’ en esa regla, y por consiguiente dispararse hacia el correspondiente objetivo (target)

[ target ]: Es la definición de que es lo que haremos con los paquetes que coincidan con la regla

Como vemos hay una sola restricción en cuanto a la sintaxis de iptables, y es que ‘comando’ debe estar primero que todo o a lo sumo, después de  “-t table”. Si bien podemos  ‘desordenar’ el orden de las opciones que estan entre paréntesis, no se recomienda, ya que es complicado de leer.

Sobre lo que incumbe a “-t table”, ya podemos darnos por satisfecho, pero como podrían pensar, si las demás opciones son igual o mas profundas que el “-t table”, sabremos que hay mucho por ver.

“Un camino de mil leguas, se comienza con el primer paso”

Estudiemos que se puede hacer desde “command”:

Un comando, tiene dos partes, una acción y una cadena donde se realiza la acción, y esto es muy tangible cuando miramos el siguiente comando:

iptables -t filter -A INPUT -s 192.168.0.0/24 -j ACCEPT

El comando, seria “-A INPUT”, donde “-A” pide que la regla se inserte en la cadena INPUT
Si quisiéramos borrarla,  de la misma forma que en muchos routers, para borrar una regla, hay que escribirla nuevamente indicando que queremos borrar esa regla.

iptables -t filter -D INPUT -s 192.168.0.0/24 -j ACCEPT

Este es un momento importante para recordar, que en NetFilter, es importantísimo el orden que ingresamos las reglas.
Por lo cual, veremos que el “-A” simplemente agrega una regla a la cadena, en el último lugar, haciendo de cada cadena un FIFO (First In, First Out, Primero ingresado Primero en salir) por así decirlo.
Y ya vimos que podemos querer insertar un regla primero que todas las demás, para lo cual usábamos “-I”

iptables -t filter -I INPUT -s 192.168.0.0/24 -j ACCEPT

Esto es casi todo lo necesario, para manejar nuestras reglas, sin embargo sería mejor tener un manejo mas ordenado de las reglas.

Pues desde iptables podemos manejar las reglas con números de identificación, y tan solo para probar que esto es cierto podemos hacer lo siguiente:

Onix:~# iptables -t filter -A INPUT -s 192.168.0.0/24 -j ACCEPT
Onix:~# iptables -t filter -A INPUT -s 10.0.0.0/24 -j ACCEPT
Onix:~# iptables -t filter -S INPUT
-P INPUT ACCEPT
-A INPUT -s 192.168.0.0/24 -j ACCEPT
-A INPUT -s 10.0.0.0/24 -j ACCEPT
Onix:~# iptables -D INPUT 1 #En esta linea borramos la regla numero 1 de la cadena input
Onix:~# iptables -t filter -S INPUT
-P INPUT ACCEPT
-A INPUT -s 10.0.0.0/24 -j ACCEPT #Aqui vemos que solo quedo la segunda linea

Así mismo, con la opción “-I” podemos elegir el numero de orden donde será insertada la regla:
(continuando con el ejemplo anterior)

Onix:~# iptables -t filter -I INPUT -s 10.0.0.1 -j DROP #Insertamos la regla primero que todas
Onix:~# iptables -t filter -I INPUT 2 -s 10.0.0.2 -j DROP #Insertamos en segundo lugar
Onix:~# iptables -t filter -I INPUT 3 -s 10.0.0.3 -j DROP # etc..
Onix:~# iptables -S INPUT
-P INPUT ACCEPT
-A INPUT -s 10.0.0.1/32 -j DROP
-A INPUT -s 10.0.0.2/32 -j DROP
-A INPUT -s 10.0.0.3/32 -j DROP
-A INPUT -s 10.0.0.0/24 -j ACCEPT

Para finalizar este punto, podemos observar que existe una opción que sirve para el remplazo:

Onix:~# iptables -t filter -R INPUT 2 -s 10.0.0.5 -j DROP
Onix:~# iptables -S INPUT
-P INPUT ACCEPT
-A INPUT -s 10.0.0.1/32 -j DROP
-A INPUT -s 10.0.0.5/32 -j DROP # Aqui vemos como el reemplazo fue efectivo
-A INPUT -s 10.0.0.3/32 -j DROP
-A INPUT -s 10.0.0.0/24 -j ACCEPT



Bien, ya hicimos el primer paso, vamos con el segundo:
Esta es la parte mas divertida, al menos para mi.
Los matches, son las condiciones que el paquete tiene que ‘matchear’ para que el paquete
‘atrapado’ en la regla. Si bien habría mucho leña para cortar aquí, no puedo detenerme en explicar los conceptos que se deben manejar sobre los protocolos (IP, TCP, UDP, ICMP), por lo cual, lo que a estos sea
referente, me restringiré a mencionarlo solamente.

Matches Genericos:

-p o –protocol : Número o nombre del protocolo, para saber el numero habrá que mirar /etc/protocols,
ya dijimos que las opciones son 4, tcp, udp, icmp y all, que involucra a los 3 anteriores. Vale usar el ! para denotar ‘lo contrario’, es decir si escrivo “! udp” quiere decir todo lo que no sea udp, osea tcp y icmp.

-s o –source : Orgien IP del paquete, se puede usar una IP, una red con notacion CDIR o bien un dominio, pero, tengamos en cuenta, que lo que se carga en las reglas es el numero IP resulto a la hora de ingresar la regla, dado que seria imposible que se resuelva en cada paquete que reciva o envie la pc. Vale usar “!”.

-d o –destination : Funciona de la misma manera que -s solo que matche sobre la dirección de destino.

-i o –in-interface : Verifica si el paquete ingresó por la interfaz pasad como argumento, solo sirve en las cadenas INPUT, FORWARD y PREROUTING, lo que es lógico. Vale usar “!”.

-o o –out-interface : Al igual que -i pero sobre la interfaz de salida, y solo vale para OUTPUT, FORWARD y POSTROUTING. Es importante aclarar que especifica las interfaces de entrada y salida permite poner una barrera mas a un ataque spoofeado.

-f o –fragment :  Cuando se fragmenta un paquete, dependiendo del protocolo, no contiene en su cabezera toda la información necesaria, para que quede atrapado en algunas reglas de NetFilter, para eso se creo este match, pero es importantisimo saber que mientras . Sin embargo, ecepto que uses la tabla raw para macthear NOTRACK, NetFilter no detectara los paquetes fragmentados.

Matches para protocolos (debe existir “-p tcp” o “-p udp” para que valga )

–sport o –source-port : Indica que puerto de origen debe tener, se puede utilizar rangos, por ejemplo son validos: 80 (puerto 80), 1:1023 (puerto desde el 1 al 1023), 1025: (desde el 1025 al 65535), :21 (desde el 0 al 21), y vale usar “!” que indicará todo lo contrario.

–dport o –destination-port : Igual que –sport (eceptuando que no maneja rangos cuando se usa “-p tcp, esto se debe hacer con otra opcion que veremos mas adelante, pero si funciona con “-p udp”).

–tcp-flags (solo con “-p tcp”, requiere conocimientos de TCP ): Este match nos permite matchear paquetes con ciertas configuracioens de flags activados/desactivados.
Como funciona?
Primero que nada los flags posibles son: SYN, ACK, PSH, RST, FIN (de forma especial se puede usar ALL para indicar todas las flags, o NONE para indicar ninguna)
Para usar –tcp-flags primero se indica las flags que Netfilter revisará, y luego, se indican las flags que pretendemos esten activadas para que entren en la regla.
Ejemplo, si queremos DROPear solo los paquetes que contengan el flag SYN activado, se usaría:
iptables -A INPUT -p tcp –tcp-flags ALL SYN -j DROP, o bien
iptables -A INPUT -p tcp –tcp-flags SYN,ACK SYN -j DROP.
O si quisieramos matchear un paquete que no tenga ningun flag activado (el cual es invalido):
iptables -A INPUT -p tcp –tcp-flags ALL SYN,ACK,PSH,RST,FIN

–tcp-options : Este match, busca matchea por el largo de los bits usados para ‘options’ en la cabecera TCP, aclaro que NetFilter no lee las opciones, solo matchea por el largo. Vale usar “!”.
iptables -A INPUT –tcp-options 8 -j DROP, dropea todas los paquetes que tengan 8 bits usados par las opciones.

Para icmp (“-p icmp”)

–icmp-type : Con iptables -p icmp –help, obtenemos una lista de los tipos de paquetes icmp.

Todos estos matches, son implicitos, es decir, no hace falta indicar que se use un modulo especial, para que los matches funcionen. Existen otros matches, que deben ser cargados con la opción -m o –match.

Estos son: ttl, dscp, multiport, tos, recent, tcpmss, ah/esp, state, owner, packet type, mark, mac, limit, length, ip range, helper, ecn, conntrack.
Luego de estos, estan los modulos de extensiones que se pueden cargar con patch-o-matic….
Como les dije, vamos por el segundo paso y aún hay mucho por recorrer!

Hasta el próximo! agradesco sus comentarios y acepto cualquier corrección ( de conceptos o de ortográfia 😀 )

/* A partir de marzo nos estamos mudando a http://netsecure.com.arhttp://www.netvulcano.com.ar */

Anuncios

NetFilter / IPTables III

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

NetFilter el manipulador

El diseño de NetFilter puede parecer un poco complejo si no se tiene un conocimiento completo del manejo de las tablas, y se pierde mucho si no se sabe todas las opciones que existen, por lo que revisaremos el funcionamiento de cada tabla, para saber que y como podemos hacer cada cosa.

Las otras ‘tables’ de iptables

Ya habíamos dicho que existen 4 tablas (filter, nat, mangle y raw), filter es la mas común, y se la suele obviar cuando usamos iptables, y nat la usamos cuando teniamos que ‘enmascarar’ una conexion, lo que comunmente se llama natear (actuar como router), pero ni por asomo sule mencionarse las otras 2 tablas, de hecho, muchas personas ni saben que existen, y los que lo saben, tienen entendido que son ‘tablas de un uso especial’.
Trataremos de desmitificarlas aquí!

Filter
Esta tabla, tiene a su cargo, la responsabilidad de filtrar TODOS los paquetes que el sistema maneje.
Para su uso, existen 3 cadenas predefinidas:

INPUT: Todos los paquetes, que ingresen al host deberan atravezar esta cadena
OUTPUT: Todos los paquetes generados por el host, con destino saliente, deberan atravezarla
FORWARD: Todos los paquetes que ingresen al host con el fin de atravezarlo como pasarela (gateway) seran controlados por esta cadena.

Como veran, a esta tabla, ‘no se le escapa nada’, desde ella se puede filtrar de forma eficiente cualquier paquete, sin embargo, aveces, filtrar no es suficiente, y necesitamos ‘manipular’ los paquetes de red…

Nat

La tabla Nat, se hace responsable de manipular, configurar o reescribir las direcciones y puertos de los paquetes, antes de que los paquetes ‘entren’ y ‘salgan’ del host.
Como es esto posible?
Bueno, obviamente, esta tabla no hace magia y modifica los paquetes mientras aun están en el cable de red, si no, a lo que nos referimos, es que antes que el paquete sea filtrado por la tabla filter (FORWARD), podra manipularse desde la tabla Nat, con las siguientes cadenas.

PREROUTING: Los paquetes atraviezan esta cadena antes que tengan que atravezar la tabla local (filter) y desde aqui se pude cambiar la dirección de destino e incluso el puerto. Como ejemplo, podemos decir que si entra un paquete destinado a la ip 192.168.1.2 puerto 80, podemos redirigirlo a la ip 192.168.1.3 puerto 8080, cosa muy útil para los firewalls que hacen DMZ (conocido como Destination NAT)

OUTPUT: Figurita repetida? Si Esta es la misma cadena que en la tabla filter, solo que desde la tabla nat podremos, como ya dijimos, manipular los paquetes.
En este caso, no hablamos de paquetes que esten siendo encaminados por el host, si no los paquetes de origen local, y a estos podremos aplicarles una redireccion (cambio de direccion de orgine) al igual que en la cadena PREROUTING.

POSTROUTING: Como dice su nombre, pasado el routeo de la tabla filter, esta es la ultima cadena a atravezar, y sirve para modificar la dirección y puerto de origen.
Ejemplos? Si un paquete a atravezado el host, y se dirige hacia un host en internet, y lleva como direccion de origen (por ejemplo una privada) y queremos cambiarsela, usaremos esta cadena.
Esto es super usado, por todos los que usan ADSL y hacen NAT, ya veremos por que.

Para acentuar un poco esto del ‘NAT’ y sus cadenas observemos un poco…

#Redireccionaremos todo el trafico web a un proxy cache (Destination NAT)
iptables -t nat -A PREROUTING -s 192.168.1.0/24 -i eth0 -p tcp –dport 80 -j DNAT –to-destination 192.168.1.99:8080

#Tenemos a nuestro firewall con una ip fija, y hemos habilitado el router, pero si solo habilitamos
#el routeo, los paquetes salen hacia internet con una direccion de origen de una red privada,
#por lo que cambiamos la dirección de origen antes de que salga, por nuestra dirección ip pública
iptables -t nat POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT –to-source 200.34.43.3x

Ahora bien, en este último ejemplo, funcionaría siempre y cuando tengamos una IP estática, sin embargo, muchos (la gran mayoria) utiliza ADSL para conectarse a internet, por lo cual, si nuestra IP cambiara, esto no funcionaría. Para lo cual, NetFilter diseño un tipo de SNAT especial: MASQUERADE

iptables -t nat POSTROUTING -s 192.168.1.0/24 -o eth1 -j MASQUERADE

Masquerade, significa, que haga SNAT con la dirección ip que tenga asignada la interfaz de red, por la cual saldrá el paquete, por lo cual, si nuestra dirección de internet cambia, automaticamente los paquetes saldran con el SNAT correcto.

Mangle

Ahora si, ya entramos en un camino hacia una comprensión un poco mas importante del funcionamiento de NetFilter.

Observemos que si ejecutamos ‘iptables -t magle -L’, veremos que esta tabla parece poseer, todos las cadenas de las tablas anteriores, y asi es. Por que esta tabla, es omnipresente.
Mangle, utiliza cada una de las cadenas, para modificar ciertos parámetros antes que filter o nat lean esa cadena.
Es decir que, si un paquete ingresa para ser routeado, antes que ingrese al PREROUTING de NAT, ingresa ‘al PREROUTING’ de MANGLE, y desde alli, puede ser modificado. Lo mismo sucederá con todas las demas cadenas,

Si esto no te queda 100% claro, es entendible, pero tampoco es tan complicado si seguiste todo hasta aquí, pero si no estas seguro de tus ideas, te ofrezco un gráfico para que te quedes tranquilo.

Tablas y cadenas
Tablas y cadenas

Pero.. un ejemplo práctico?

Ok, a ver si esto te convence:
(advertencia: para entender lo que hacemos aquí deberás conocer conceptos acerca del manejo de los protocolos a vajo nivel, para lo que te recomiendo que leas los RFC correspondientes)

#Cambiamos el TOS (Type Of Service)

iptables -t mangle -A PREROUTING -s 192.168.0.1 -i eth0 –dport 1950  -j TOS –set-tos 0x10

#TCPMSS

iptables -t mangle -A FORWARD -p tcp -j TCPMSS –clamp-mss-to-pmtu

#Cambiar el TTL

iptables -t mangle -A FORWARD -d 0.0.0.0/0 -i eth0 -p tcp –dport 1234 -j TTL –ttl-set 1
#Bueno… cada uno sabe lo que hace no?

En fin hay varias opciones que podemos cambiar con la tabla mangle, pero no podemos detenernos en cada una de ellas, lo importante es ver, que desde ella se puede modificar ciertos aspectos de los paquetes de red, insisto nuevamente hay mucha info en el man de iptables.

raw

Esta es una tabla nueva, y no tiene mucha variedad de uso, pero no puedo limitarme a decir, simplemente que es ‘de un uso especial’, pero si he de recalcar, no que la mayoria de los kernels no la poseen ecepto que esten parcheados.

Esta tabla, existe para un solo objetivo: NOTRACK
Vale aclarar algo: NetFilter y el Kernel en si, tienen un control de las conexiones, por ejemplo no es lo mismo, que una conexión TCP, este en estado NEW (cuando se manda el SYN y se espera el SYN/ACK), que este en ESTABLISHED (cuando se recibe el SYN/ACK y se envia el SYN de respuesta).
Todo esto lo vigila NetFilter, tanto en tcp, como udp, e icmp, ahora, esto conlleva un gasto significativo de recursos, cuando hablamos de muchas conexiones simultaneas.

Para que NetFilter no lleve ese control, y economice recursos, quizas querramos que ciertas conexiones no las ‘vigile’, para lo cual podriamos usar esta tabla:

iptables -t raw -A PREROUTING -s 192.168.0.0/24 -j NOTRACK

El problema deveniente es que no podremos controlar las conexiones que se establescan de esta forma.

Y hasta ahora solo estamos viendo lo ‘bàsico’ de iptables, y aun queda mas de lo ‘bàsico’, por lo que no te pierdas el proximo articulo sobre este mounstruo del filtrado!

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!!!

NetFilter / IPTables I

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

NetFilter el grande

Los firewalls, son una parte fundamental de la seguridad, en los sistemas operativos de hoy en día, ya que las redes son parte fundamental de los sistemas computacionales.
En este caso revisaremos el caso de uno de los mejores firewalls por software existentes: NetFilter
NetFilter, es el sistema de filtrado de paquetes de los Kernels Linux de la rama 2.4 y 2.6, y para mucha mas info, podes pasar por www.netfilter.org

Por que escribir un artículo mas sobre iptables
?
Simplemente por que no encontré alguno que lo explique como a mi me hubiese gustado.
Otra razón, es por que uno termina aprendiendo mucho mas.
Para una guia mas rápida, con muchos ejemplos recomiendo el artículo de bulma

Este sistema está basado en el manejos de tablas, el cual se administra desde la aplicación iptables.
Esta aplicación configura todas las reglas de filtrado, pero no es en si mismo el firewall, esto es importante de destacar, ya que no tenemos un proceso corriendo para administrar los paquetes, si no que iptables administra las reglas que el kernel maneja. Así, no corremos el peligro de que el programa si cuelgue o contenga un bug y termine por ser una puerta trasera, en lugar de ser una protección.
Es cierto que nada es perfecto, si embargo hasta el momento, no he escuchado de ninguna vulnerabilidad que haya puesto en vilo la seguridad de los servidores protegidos con Netfilter.
Vale recalcar, que Netfilter pertenece a la lista de 100 herramientas de seguridad mas importantes según Insecure.org.

Comencemos:

Decíamos que iptables maneja las tablas de filtrado del kernel, y, cada tabla contiene una serie de instrucciones condicionales (reglas).
Un ejemplo sería:

Tabla_1
Si proviene del puerto 2934 con destino al puerto 80 aceptar
Si proviene de la ip 200.32.xxx.xxx rechazar
Si proviene de la ip 201.9.xxx.xxx rechazar

Cuando comparamos un paquete (de red) con esta tabla, lo haremos hasta encontrar la primer coincidencia, y dejaremos comparar.

Si para este ejemplo enviamos un paquete proveniente del puerto 2000, desde la ip 200.32.xxx.xxx (la misma del ejemplo), compararía regla por regla de la siguiente forma:

Si proviene del puerto 2934 con destino al puerto 80 aceptar = Falso / no cumple
Si proviene de la ip 200.32.xxx.xxx rechazar = Verdadero
Fin de comprobaciones

Lo que aca vemos, es que al no cumplir con la primer regla de la tabla, prosigue con la siguiente, y asi seguiría mientras no cumpla con ninguna regla (de forma completa). En este ejemplo, cumple todas las condiciones de la segunda regla, por lo cual, no comprueba la tercera y rechaza el paquete.
Podemos deducir, que es de suma importancia el orden en el cual colocaremos las reglas ya que, si colocamos reglas muy generales al principio, se parará la comparación en esa regla y quizas no filtremos como lo deseamos.

Esta forma de filtrado nos permitirá (por lo contrario de lo que suele parecer al principio) mucha flexibilidad.

Veamos un poco mas:

Cada tabla, no es solo una lista de instrucciones a revisar, si no que cada tabla tiene ‘Cadenas’, algunas predefinidas, y otras a definir por el usuario. Para aclarar, podemos decir, que las reglas se listan en cadenas, las cuales, se agrupan dentro de las tablas.
TABLA_1
Cadena_1
Regla_1
Regla_2
Regla_3

Regla_x
Cadena_2
Regla_1
….

Pero antes de ver mas teoría de esto, empecemos a visualizar y toquetear un poco.

Como dijimos netfilter se maneja mediante tablas, y estas son manejadas por iptables, ergo, para configurar las tablas y cadenas de nuestro firewall usaremos este poderoso comando.

Ejemplo 1
#iptables -t filter -L

Si no tienes configurado, ningún script para iptables, veras lo siguiente:

Ejemplo 2

Chain INPUT (policy ACCEPT)

target     prot opt source      destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Analizando todo

Usamos iptables con la opcion “-t filter”. La opción -t nos permite seleccionar una tabla en particular. En este caso “filter”, es la tabla mas común, o principal, ya que es por donde pasan todos los paquetes, sin embargo, existen otras, y estas son: raw, mangle,  y nat.

Si son curiosos y no se aguantan, pueden hacer un man iptables y seguir investigando mas.

La opcion -L, permite listar una cadena particular o bien lista todas las existentes en la tabla, como lo hicimos en este caso. Por lo que vemos que dentro de la tabla, existen tres cadenas: INPUT, FOWARD y OUTPUT.

Cada una de estas cadenas, tienen una política por defecto, lo que significa, que si el paquete comparado, con una cadena, no coincide con ninguna regla, se aplica la política de la cadena. En el ejemplo anterior, podemos ver que en cada cadena aparece “(policy ACCEPT)”, por lo cual, como decíamos, si un paquete no coincide con ninguna regla de la cadena, se ACCEPTa (je).

Para establecer otra política por defecto usamos “-P”:

#iptables -t filter -P INPUT REJECT

De esta manera, por ejemplo, indicamos a netfiltes, que REJECTe (jeje) por defecto todo lo que entre (INPUT) al host. Luego deberiamos ingresar reglas en la cadena INPUT, para que deje pasar ciertas cosas o no tendríamos conexión con nada! (lo vemos mas adelante)

– Todavía no me mostraste como modificar nada y eso es aburrido!

Ok, si te gusta la acción podes experimentar con esta regla y de paso tratar de deducirla antes de seguir leyendo:

iptables -t filter -A INPUT  -p tcp --source-port 2934 --destination-port 80 -j ACCEPT

Como ya vimos, -t filter, sirve para seleccionar con que tabla que trabajaremos, en este caso, al ser la tabla filter, la tabla por defecto, podemos obviarla y usar “iptables -A INPUT –source-p….”.

Lo siguiente que vemos, “-A INPUT” sirve para ingresar una regla en una cadena, en este caso “INPUT”.  Por defecto, todo lo que entra al host (con destino al host). Así mismo, todo lo que sale del host (con cualquier destino, pasa por la cadena OUTPUT), y todo lo que ingresa al host con destino de ser reenviado, se compara con la cadena FORWARD.
En el ejemplo usamos “-A”, esta opción ingresa una regla al final de las reglas de la cadena, pero como pudimos ver, es muy importante el orden en que se introducen las reglas, ya que, cuando encuentra la primera coincidencia, dejará de comparar. Existe otra opción, “-I” con la cual, la regla se inserta en la primer posición de la cadena.
Pero además iptables nos permite ingresar las reglas por número de orden, sin embargo, para eso podes remitirte al man de iptables.
Las siguientes opciones son faciles de deducir:

-p tcp : Coincide si el paquete es un paquete TCP
–source-port : Coincide si el puerto de origen del paquete es 2934
–destination-port : Coincide si el puerto de destino es 80

y finalmente, “-j” establece el objetivo, es decir, que es lo que se hará con el paquete si coincide con dicha regla, las opciones predefinidas, son : ACCEPT (Aceptar el paquete) REJECT (Rechaza el paquete enviando un mensaje ICMP de que fue rechazado), DROP (obvia el paquete, es decir, lo rechaza sin avisar de que lo rechazó).
Existen otros objetivos predefinidos, pero por ahora conviene ver solo estos.
Además de las opciones predefinidas, se pueden poner como objetivos una cadena de la misma tabla.

Muy bien, estas son las cuestiones básicas de iptables, solo nos falta ver otras opciones que podemos ingresar en una regla, para poder empezar a tirar unas lineas y comprender varios scripts de iptables que andan dando vuelta.

Pequeño Laurouse Ilustrado de Iptables:


–source : Dirección de origen (ip o rango de red)
–destination : Destino del paquete (ip o rango de red)
–in-interface : Interface de red por donde ingresa el paquete (eth1, wlan0 …)
–out-interface : Interface por donde sale el paquete (lo mismo eth1, wlan0…)
–fragment : Aplica la regla a los fragmentos sucesivos al primero

y las opciones q vimos antes:
–protocol : Protocolo con el que debe coincidir la regla, puede ser tcp, udp, icmp o all
–source-port : Coincide si el puerto de origen del paquete es el indicado
–destination-port : Coincide si el puerto de destino es el indicado

A todas estas opciones se les puede agregar un ! para indicar lo contrario, por ejemplo si usamos “-p ! tcp”, estamos indicando todos los protocolos que no sean tcp, o si indicamos “-s ! 10.0.0.0/24”, la regla coincide solo si el paquete no proviene de la red 10.0.0.0/24.

Ahora si ya podemos escribir algunas lineas concienzudamente:
Pongamos un ejemplo común: un servidor web, el cual queres manejar remotamente mediante ssh desde una ip en particular, y acceso a ftp desde la red interna.

Si es un servidor web, debemos dejar el puerto 80 abierto
Si queremos dejar el servidor ssh para la administración habilitamos el puerto 22 para nuestra ip
y para el ftp habilitamos el puerto 21

Lo más común es establecer un política por defecto cerrada y abrir lo que haga falta:

iptables -P INPUT REJECT
iptables -A INPUT -p tcp -s 0.0.0.0/0 -dport 80 -j ACCEPT
iptables -A INPUT -p tcp -s 204.54.45.x -dport 22 -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.6.0/24 -dport 21 -i eth1 -j ACCEPT

Primero habrán observado, que no uso “-t filter” , y es que como dije antes, la tabla “filter” es la tabla por defecto, y se puede obviar. Así mismo, uso -dport en lugar de –destination-port, y es por que esta es la opción recortada de la misma.

Bueno, aunque hay pocas cosas prácticas, suficiente por hoy, espero que les sirva.

/* A partir de marzo nos estamos mudando a http://netsecure.com.arhttp://www.netvulcano.com.ar */