1. Empezando con Iptables Iptables es una herramienta que utiliza Netfilter (viene en el kernel) para establecer reglas de filtrado de paquetes. Con ella podemos definir reglas que restrinjan el acceso a nuestra máquina, que nos permitan hacer nat, que nos permitan, junto con otras herramientas, implementar un QoS, etc. Es una herramienta muy compleja, y tremendamente configurable, pero aquí vamos a aprender cómo podemos establecer reglas de filtrado para filtrar por IP y por puerto los paquetes que pasen por nuestra máquina. En iptables, tenemos varios tipos de reglas: reglas de filtrado, reglas de nat, reglas de mangle (para manipular paquetes)... Nosotros nos centraremos en las reglas de filtrado, para poder filtrar tráfico y implementar nuestro firewall. Estas reglas se definen en la tabla filter (que es la tabla por defecto de iptables). Esta tabla tiene 3 cadenas: INPUT: es para filtrar paquetes que vienen hacia nuestra máquina. OUTPUT: es para filtrar paquetes generados por nuestra máquina. FORWARD: es para filtrar aquellos paquetes que llegan a nuestra máquina pero no son para nosotros, es decir, que llegan para que nuestra máquina los reencamine. 2. Sintaxis básica de Iptables La sintaxis que seguiremos para añadir reglas a cada una de las cadenas anteriores será del estilo: iptables -t filter -A INPUT iptables -A INPUT Podemos usar cualquiera de las 2, ya que la tabla filter es la tabla por defecto. El parámetro -A se utiliza para añadir una regla a la cadena especificada justo después. Los parámetros que utilizaremos para filtrar son los siguientes: * -t Para especificar la tabla sobre la que trabajamos. Por ejemplo: -t nat * -i Para especificar la interfaz de red por la que entra el paquete. Por ejemplo: -i eth0 * -o Para especificar la interfaz de red por la que sale el paquete. Por ejemplo: -o eth0 * -p Para especificar el protocolo del paquete. Por ejemplo: -p tcp * -s Para especificar la ip de origen (o red de la que procede) del paquete. Por ejemplo: -s 192.168.0.2 para especificar una ip, o bien -s 192.168.0.0/24 para especificar una red de origen. * -d Igual que en el caso anterior pero para la ip destinataria del paquete. * --dport Para especificar el puerto al que va dirigido el paquete. Por ejemplo: --dport 22, o bien --dport 1:1024 (para especificar un rango de puertos). * -j Para especificar la acción que realizaremos con el paquete si al regla se acepta. Por ejemplo -j ACCEPT para aceptar el paquete. 3. Nuestro primer cortafuegos con Iptables Visto esto podemos empezar ya a diseñar nuestro cortafuegos, ya que Iptables se aprende mucho mejor viendo ejemplos que con líneas y líneas de explicacion. Lo que haremos será crear un fichero, y en él colocar una detrás de otra todas las reglas de filtrado que queramos poner, teniendo en cuenta el orden, ya que cuando una regla puede ser aplicada, se aplica esa y no se revisan el resto. Vamos a ver un primer ejemplo de script de iptables. Supondremos que tenemos un servidor web y un ftp al que queremos dejar acceso a todo el mundo, y también un servidor mysql al que sólo queremos dejar acceso a un amigo que nos ayuda a administrar la base de datos. #!/bin/bash echo "Aplicando reglas del firewall..." # Borramos las reglas que ya pudieran existir, y los contadores iptables -F iptables -X iptables -Z # Establecemos las políticas por defecto iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD DROP ### Filtrado de paquetes ### # Permitimos acceso desde la propia máquina iptables -A INPUT -i lo -j ACCEPT # Permitimos acceso a los puertos 80 (web), 20 y 21 (ftp) iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT iptables -A INPUT -i eth0 -p tcp --dport 20:21 -j ACCEPT # permitimos a nuestro amigo el acceso a mysql (puerto 3306) iptables -A INPUT -i eth0 -p tcp -s 80.37.45.123 --dport 3306 -j ACCEPT # Ahora cerramos los puertos de gestión típicos iptables -A INPUT -i eth0 -p tcp --dport 1:1024 -j DROP iptables -A INPUT -i eth0 -p udp --dport 1:1024 -j DROP # Cerramos el puerto de mysql para que nadie más pueda acceder iptables -A INPUT -i eth0 -p tcp --dpost 3306 -j DROP # Cerramos el peurto de webmin iptables -A INPUT -i eth0 -p tcp --dport 10000 -j DROP Bueno, aquí termina nuestro primer ejemplo de cortafuegos. Para ver si las reglas han quedado bien aplicadas, podemos utilizar el comando: # iptables -nL Tambiéne s importante remarcar que sólo root puede manipular las reglas iptables, así que deberemos ejecutal script como root. 4. Expliquemos un poco más el script Primero borramos todas las reglas de iptables que pudiera haber cargadas. Esto es importante si no sabemos si el operativo o alguna ejecución nuestra anterior nos han dejado reglas ya cargadas. Lo segundo que hacemos (y muy importante) es establecer las políticas por defecto. Estas políticas definen la acción que se realizará con el paquete si ninguna regla especificada llega a cumplirse. Nosotros, por defecto, hemos aceptado todo lo de la cadena OUTPUT (dejamos salir todo), aceptamos por defecto todo lo de la cadena INPUT, ya filtraremos luego lo que no nos interese, y no dejamos pasar los paquetes de FORWARD (ya que esto solo debería permitirse en equipos que van a hacer de routers de una red). Podríamos haber establecido la política de INPUT a DROP por defecto, así no permitiríamos nada, y luego establecer reglas para permitir el acceso a todo aquello que queramos; pero eso ya va a elección de cada uno. Luego ya empezamos a filtrar. Lo primero que hacemos es dejar a localhost acceso a todo, ya que desde nuestro PC podremos iniciar conexiones al servidor web local, etc. Estas conexiones irán por la interfaz de lo (loopback). Luego permitimos explícitamente acceso a los puertos 20,21 y 80. Esto es necesario ya que en las siguientes reglas cerramos el acceso a los peurtos del 1 al 1024. Puede parecer contradictorio, pero tiene sentido ya que las reglas se miran en orden, y si un paqeute coincide, por ejemplo, con la regla del puerto 80, se admitirá y no se mirarán más reglas. Seguidamente permitimos el acceso a mysql (puerto 3306) sólo a una ip en concreto (la de nuestro amigo). Luego ya cerramos los puertos típicos de gestión (1:1024), el de webmin (10000) y el de mysql, ya que no queremos que nadie más acceda a él. * NOTA: Podemos obtener un listado completo de puertos y el servicio que dan mirando el fichero /etc/services 5. Pautas generales para cortafuegos básicos Habiendo entendido el script vamos a resumir los pasos que deberían seguirse a la hora de configurar un cortafuegos básico como este. Evidentemente, cualquier variación para adaptarlo a las necesidades de cada uno es perfectamente válida. 1. Borrar las reglas y las cadenas que hubiera, para asegurarnos de que sólo estén cargadas nuestras reglas. 2. Establecer las políticas por defecto para saber qué hacer si un paquete no coincide con ninguna regla. 3. Empezar el filtrado de paquetes con las reglas que queramos, cuidando el orden: pondremos las reglas de más específicas a más generales.