Esta entrada es la continuación de NAT con iptables y sólo he tardado 3 años en ponerme a hacerla :-)
Al igual que en la entrada anterior se utilizaba sólo la tabla nat de iptables, en ésta sólo se utilizará la tabla filter, que es la tabla por defecto en iptables. Al tratarse de una continuación, no se repetirán las explicaciones allí dadas, por lo que se recomienda su lectura previamente para aquellos lectores que se inicien en esto de iptables.
Vamos a explicar aquí la configuración de un cortafuegos de filtrado de paquetes con iptables y dejaremos para una entrada posterior (esperemos que antes de 3 años) la mejora del mismo incluyendo características más avanzadas.
Cortafuegos
Uno de los mecanismos más extendidos para proteger una red de equipos que estén conectados a otra red (el caso más habitual es Internet), es colocar un dispositivo conectado a ambas redes que analiza el tráfico entre una y otra que, de acuerdo a una serie de criterios, permite o no pasar paquetes de un lado a otro. Este dispositivo conocido como cortafuegos o firewall puede implementar esta funcionalidad de forma nativa o mediante software sobre un sistema operativo genérico, en el primer caso el dispositivo se conoce como hardware firewall (cortafuegos por hardware) y en el segundo como software firewall (cortafuegos por software).
Hay una enorme variedad de cortafuegos por hardware: Juniper, Cisco y casi cualquier marca de componentes de redes ofrecen estos equipos, además este tipo de cortafuegos suele incluir otras funcionalidades como VPN, QoS, proxies, etc. En el caso de los cortafuegos por software destacan iptables del kérnel linux e ipfw de freebsd, en nuestro caso nos centramos en la configuración de un cortafuegos software con iptables.
Tipos de cortafuegos
Una clasificación clásica de los cortafuegos distingue entre tres tipos o generaciones:
- Cortafuegos de filtrado de paquetes: Este tipo de cortafuegos analiza y filtra los paquetes que lo atraviesan en función de algunos parámetros a nivel de red, transporte o incluso enlace (por ejemplo direcciones IP origen o destino, puertos, direcciones MAC, etc.).
- Cortafuegos de estado: Consideran el estado del paquete en la comunicación, distinguiendo una nueva conexión de otra establecida por ejemplo.
- Cortafuegos de capa de aplicación: Analizan el contenido del paquete a nivel de aplicación, pudiendo hacer un filtrado más exhaustivo
Estos tipos de cortafuegos no son excluyentes, las siguientes generaciones o características se van añadiendo sobre una configuración básica de un dispositivo para el filtrado de paquetes, que será lo que veamos aquí. Dejamos para otras entradas la explicación de las caracteríscticas más avanzadas.
Esquemas de red
En primer lugar hay que decidir la ubicación en la red del cortafuegos, lo más frecuente es que el cortafuegos separe la red local de la otra red a la que queremos conectarnos (Internet por ejemplo), bien integrado en el mismo router que interconecta las dos redes o conectado en serie con éste.
El esquema anterior se corresponde con la configuración más sencilla, en la que no tenemos en nuestra red ningún servidor que tenga que ser accesible desde el exterior (servidor web por ejemplo), por lo que el cortafuegos se limita a permitir a los equipos de la red local acceso a determinados puertos. Esta configuración se puede complicar un poco si tenemos que incluir un servidor que ofrezca algún servicio al exterior:
Sin embargo, por motivos de seguridad, nunca debe ubicarse un servidor que sea accesible desde el exterior en nuestra red local, ya que al tratarse de un servidor expuesto, puede ser objetivo de ataques y conviene tenerlo separado del resto de equipos de nuestra red y obviamente de los demás servidores si los hubiera. Un esquema de red más adecuado sería ubicar el servidor o servidores accesibles desde Internet en un segmento de red específico, que se conoce como Zona Desmilitarizada o DMZ por analogía a la zona desmilitarizada militar, bien duplicando el número de cortafuegos o con un cortafuegos conectado a tres redes, lo que se conoce como cortafuegos de 3 patas:
Nota: Los esquemas se han realizado con la aplicación de gráficos vectoriales inkscape y con imágenes libres disponibles en http://focaclipart.net23.net/hardware/ y http://www.openclipart.org/.
Las configuraciones reales pueden ser más complicadas todavía, fundamentalmente porque pueden incluir varios cortafuegos y varias redes, pero un equilibrio razonable entre un caso más o menos real y suficientemente sencillo para empezar con iptables puede ser un cortafuegos de 3 patas, que será el que utilicemos en esta entrada.
La tabla filter de iptables
iptables incluye tres cuatro tablas inicialmente: filter, nat, mangle y raw, la tabla filter es la encargada del filtrado de paquetes y es la tabla por defecto, por lo que será igual poner iptables -t filter que iptables. Esta tabla contiene a su vez tres cadenas: INPUT, OUTPUT y FORWARD, las dos primeras se utilizan para paquetes que tienen como destino (INPUT) o como origen (OUTPUT) el propio cortafuegos, mientras que FORWARD es para paquetes que atraviesan el mismo, como por ejemplo cualquier paquete de la red local con destino un equipo de Internet o la respuesta del mismo.
Política asumida o por defecto
Hay dos formas básicas de configurar un cortafuegos, la primera es permitir todo y restringir uno a uno los paquetes que queramos, es lo que se conoce como política por defecto ACCEPT. De forma opuesta, se prohibe todo y se va abriendo el cortafuegos a los paquetes que sea necesario, lo que se conoce como política por defecto DROP. Desde el punto de vista del control del tipo de conexiones que se van a permitir, parece mucho más razonable utilizar un cortafuegos con política por defecto DROP, y es lo que haremos aquí, por lo que ya podemos escribir nuestra primera regla de iptables en el cortafuegos:
iptables -P FORWARD DROP
¡Tenemos el cortafuegos perfecto! no se permite el paso de NINGÚN paquete :-)
Cuando se utiliza un cortafuegos con política por defecto DROP, las reglas de iptables de la tabla filter suelen ir por parejas, ya que cada proceso que se permite incluye dos tipos de paquetes: las solicitudes y las respuestas. Estas parejas son de reglas de INPUT/OUTPUT para procesos que tienen como origen o destino el propio cortafuegos y FORWARD/FORWARD para procesos que tiene como origen y destino otros equipos.
Para que un cortafuegos sea efectivo, sobretodo si se trata de uno con política por defecto DROP, las reglas de los paquetes que se permiten debe ser lo más concretas posibles, es mucho mejor una regla como:
iptables -A FORWARD -i eth1 -s 10.0.0.1 -o eth0 -d 8.8.8.8 -p udp --dport 53 -j ACCEPT
que una regla como:
iptables -A FORWARD -p udp --dport 53 -j ACCEPT
Las dos consiguen lo mismo, pero la primera concreta mucho más el tipo de paquete que se permite y por tanto consigue mucho mayor control sobre lo que atraviesa el cortafuegos.
Problema tipo
Vamos a plantear una situación concreta, sencilla pero con suficientes detalles como para comprender la configuración de un caso real. Vamos a configurar un cortafuegos de 3 patas con los siguientes condicionantes:
Cortafuegos
- Se conecta a Internet mediante una dirección IP estática
- Tiene tres interfaces de red eth0 (IP 40.12.1.14), que da acceso a Internet, eth1 (IP 192.168.1.1), que es la puerta de enlace de la red local y eth2 (IP 192.168.2.1), que es la puerta de enlace de la DMZ.
- Es servidor DHCP de la red local
- No debe ser accesible desde Internet
- Actúa como dispositivo NAT
- Se puede acceder a él por ssh desde la red local
- Puede hacer consultas DNS al servidor de la red local
- Responde a ping hecho desde la red local o la DMZ
DMZ
- Direccionamiento IP 192.168.2.0/24
- Conectada a la interfaz eth2 del cortafuegos
- Tiene un servidor web (http y https) y un servidor de correo (smtp, pop3s e imaps) en el mismo equipo (IP 192.168.2.2)
Red local
- Direccionamiento IP 192.168.1.0/24
- Conectada a la interfaz eth1 del cortafuegos
- Hay un servidor DNS (IP 192.168.1.2) que puede realizar consultas DNS al exterior.
- Los equipos de la red local deben tener acceso a todos los servicios ofrecidos por los equipos de la DMZ
- Los equipos de la red local pueden utilizar los servicios web (http y https) de cualquier servidor de Internet
Resolución del problema
Establecemos la política por defecto:
iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP
Como ya se explicó NAT en la entrada anterior, aquí simplemente pondremos las reglas de NAT necesarias:
# Source NAT de la red local y la DMZ: iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to 40.12.1.14 iptables -t nat -A POSTROUTING -o eth0 -s 192.168.2.0/24 -j SNAT --to 40.12.1.14 # DNAT de los servicios http,https,smtp,pop3s e imaps al servidor de la DMZ: iptables -t nat -A PREROUTING -i eth0 -d 40.12.1.14 -p tcp --dport 80 -j DNAT --to 192.168.2.2 iptables -t nat -A PREROUTING -i eth0 -d 40.12.1.14 -p tcp --dport 443 -j DNAT --to 192.168.2.2 iptables -t nat -A PREROUTING -i eth0 -d 40.12.1.14 -p tcp --dport 25 -j DNAT --to 192.168.2.2 iptables -t nat -A PREROUTING -i eth0 -d 40.12.1.14 -p tcp --dport 993 -j DNAT --to 192.168.2.2 iptables -t nat -A PREROUTING -i eth0 -d 40.12.1.14 -p tcp --dport 995 -j DNAT --to 192.168.2.2
Con esto seguiríamos sin tener ningún tipo de conexión, ya que la política por defecto DROP seguiría descartando todos los paquetes que llegaran al cortafuegos. Vamos a incluir las reglas para que los equipos de la DMZ sean accesibles desde Internet:
# Cuando pasan por FORWARD los paquetes ya tienen como dirección IP destino la del # servidor de la DMZ porque la ha cambiado DNAT: # Aceptamos las peticiones al servidor web (http) y las respuestas de éste: iptables -A FORWARD -i eth0 -s 0.0.0.0/0 -o eth2 -d 192.168.2.2 -p tcp --dport 80 -j ACCEPT iptables -A FORWARD -o eth0 -d 0.0.0.0/0 -i eth2 -s 192.168.2.2 -p tcp --sport 80 -j ACCEPT # Aceptamos las peticiones al servidor web (https) y las respuestas de éste: iptables -A FORWARD -i eth0 -s 0.0.0.0/0 -o eth2 -d 192.168.2.2 -p tcp --dport 443 -j ACCEPT iptables -A FORWARD -o eth0 -d 0.0.0.0/0 -i eth2 -s 192.168.2.2 -p tcp --sport 443 -j ACCEPT # Aceptamos las peticiones al servidor smtp y las respuestas de éste: iptables -A FORWARD -i eth0 -s 0.0.0.0/0 -o eth2 -d 192.168.2.2 -p tcp --dport 25 -j ACCEPT iptables -A FORWARD -o eth0 -d 0.0.0.0/0 -i eth2 -s 192.168.2.2 -p tcp --sport 25 -j ACCEPT # El servidor smtp también envía correo, por lo que se comporta como cliente: iptables -A FORWARD -o eth0 -d 0.0.0.0/0 -i eth2 -s 192.168.2.2 -p tcp --dport 25 -j ACCEPT iptables -A FORWARD -i eth0 -s 0.0.0.0/0 -o eth2 -d 192.168.2.2 -p tcp --sport 25 -j ACCEPT # Aceptamos las peticiones al servidor pop3s y las respuestas de éste: iptables -A FORWARD -i eth0 -s 0.0.0.0/0 -o eth2 -d 192.168.2.2 -p tcp --dport 995 -j ACCEPT iptables -A FORWARD -o eth0 -d 0.0.0.0/0 -i eth2 -s 192.168.2.2 -p tcp --sport 995 -j ACCEPT # Aceptamos las peticiones al servidor imaps y las respuestas de éste: iptables -A FORWARD -i eth0 -s 0.0.0.0/0 -o eth2 -d 192.168.2.2 -p tcp --dport 993 -j ACCEPT iptables -A FORWARD -o eth0 -d 0.0.0.0/0 -i eth2 -s 192.168.2.2 -p tcp --sport 993 -j ACCEPT
Para que los equipos de la DMZ puedan hacer resolución de nombres (imprescindible por ejemplo para enviar correo), les permitimos hacer consultas DNS:
iptables -A FORWARD -i eth2 -s 192.168.2.0/24 -o eth0 -d 0.0.0.0/0 -p udp --dport 53 -j ACCEPT iptables -A FORWARD -o eth2 -d 192.168.2.0/24 -i eth0 -s 0.0.0.0/0 -p udp --sport 53 -j ACCEPT iptables -A FORWARD -i eth2 -s 192.168.2.0/24 -o eth0 -d 0.0.0.0/0 -p tcp --dport 53 -j ACCEPT iptables -A FORWARD -o eth2 -d 192.168.2.0/24 -i eth0 -s 0.0.0.0/0 -p tcp --sport 53 -j ACCEPT
Vamos a poner ahora las reglas necesarias para que los equipos de la red local puedan acceder a los servicios de la DMZ y a los servicios que se les permite de Internet:
# Aceptamos las peticiones al servidor web (http) y las respuestas de éste: iptables -A FORWARD -i eth1 -s 192.168.1.0/24 -o eth2 -d 192.168.2.2 -p tcp --dport 80 -j ACCEPT iptables -A FORWARD -o eth1 -d 192.168.1.0/24 -i eth2 -s 192.168.2.2 -p tcp --sport 80 -j ACCEPT # Aceptamos las peticiones al servidor web (https) y las respuestas de éste: iptables -A FORWARD -i eth1 -s 192.168.1.0/24 -o eth2 -d 192.168.2.2 -p tcp --dport 443 -j ACCEPT iptables -A FORWARD -o eth1 -d 192.168.1.0/24 -i eth2 -s 192.168.2.2 -p tcp --sport 443 -j ACCEPT # Aceptamos las peticiones al servidor smtp y las respuestas de éste: iptables -A FORWARD -i eth1 -s 192.168.1.0/24 -o eth2 -d 192.168.2.2 -p tcp --dport 25 -j ACCEPT iptables -A FORWARD -o eth1 -d 192.168.1.0/24 -i eth2 -s 192.168.2.2 -p tcp --sport 25 -j ACCEPT # El servidor smtp también envía correo, por lo que se comporta como cliente: iptables -A FORWARD -o eth1 -d 192.168.1.0/24 -i eth2 -s 192.168.2.2 -p tcp --dport 25 -j ACCEPT iptables -A FORWARD -i eth1 -s 192.168.1.0/24 -o eth2 -d 192.168.2.2 -p tcp --sport 25 -j ACCEPT # Aceptamos las peticiones al servidor pop3s y las respuestas de éste: iptables -A FORWARD -i eth1 -s 192.168.1.0/24 -o eth2 -d 192.168.2.2 -p tcp --dport 995 -j ACCEPT iptables -A FORWARD -o eth1 -d 192.168.1.0/24 -i eth2 -s 192.168.2.2 -p tcp --sport 995 -j ACCEPT # Aceptamos las peticiones al servidor imaps y las respuestas de éste: iptables -A FORWARD -i eth1 -s 192.168.1.0/24 -o eth2 -d 192.168.2.2 -p tcp --dport 993 -j ACCEPT iptables -A FORWARD -o eth1 -d 192.168.1.0/24 -i eth2 -s 192.168.2.2 -p tcp --sport 993 -j ACCEPT # Aceptamos las peticiones a los servidores web (http) de Internet y las respuetas: iptables -A FORWARD -i eth1 -s 192.168.1.0/24 -o eth0 -d 0.0.0.0/0 -p tcp --dport 80 -j ACCEPT iptables -A FORWARD -o eth1 -d 192.168.1.0/24 -i eth2 -s 0.0.0.0/0 -p tcp --sport 80 -j ACCEPT # Aceptamos las peticiones a los servidores web (https) de Internet y las respuetas: iptables -A FORWARD -i eth1 -s 192.168.1.0/24 -o eth0 -d 0.0.0.0/0 -p tcp --dport 443 -j ACCEPT iptables -A FORWARD -o eth1 -d 192.168.1.0/24 -i eth2 -s 0.0.0.0/0 -p tcp --sport 443 -j ACCEPT # Aceptamos las peticiones DNS del equipo 192.168.1.2: iptables -A FORWARD -i eth1 -s 192.168.1.2 -o eth0 -d 0.0.0.0/0 -p udp --dport 53 -j ACCEPT iptables -A FORWARD -o eth1 -d 192.168.1.2 -o eth0 -s 0.0.0.0/0 -p udp --sport 53 -j ACCEPT iptables -A FORWARD -i eth1 -s 192.168.1.2 -o eth0 -d 0.0.0.0/0 -p tcp --dport 53 -j ACCEPT iptables -A FORWARD -o eth1 -d 192.168.1.2 -i eth0 -s 0.0.0.0/0 -p tcp --sport 53 -j ACCEPT
Y para terminar incluimos las reglas de INPUT/OUTPUT necesarias en este problema:
# Se permiten las peticiones y respuestas DHCP: iptables -A INPUT -i eth1 -p udp -s 0.0.0.0/0 -d 255.255.255.255 --dport 67 --sport 68 -j ACCEPT iptables -A OUTPUT -o eth1 -s 192.168.1.1 -d 255.255.255.255 -p udp --sport 67 --dport 68 -j ACCEPT # Se permite entrar por ssh desde la red local: iptables -A INPUT -i eth1 -s 192.168.1.0/24 -d 192.168.1.1 -p tcp --dport 22 -j ACCEPT iptables -A OUTPUT -o eth1 -d 192.168.1.0/24 -s 192.168.1.1 -p tcp --sport 22 -j ACCEPT # Se permiten consultas DNS al servidor de la red local: iptables -A OUTPUT -o eth1 -s 192.168.1.1 -d 192.168.1.2 -p udp --dport 53 -j ACCEPT iptables -A INPUT -i eth1 -d 192.168.1.1 -s 192.168.1.2 -p udp --sport 53 -j ACCEPT iptables -A OUTPUT -o eth1 -s 192.168.1.1 -d 192.168.1.2 -p tcp --dport 53 -j ACCEPT iptables -A INPUT -i eth1 -d 192.168.1.1 -s 192.168.1.2 -p tcp --sport 53 -j ACCEPT # Se permite ping desde la red local y la DMZ: iptables -A INPUT -i eth1 -p icmp --icmp-type echo-request -j ACCEPT iptables -A OUTPUT -o eth1 -p icmp --icmp-type echo-reply -j ACCEPT iptables -A INPUT -i eth2 -p icmp --icmp-type echo-request -j ACCEPT iptables -A OUTPUT -o eth2 -p icmp --icmp-type echo-reply -j ACCEPT







#1 por Vladimir el 5-01-12 - 4:40 am
Hola
La verdad es que llegué aquí siguiendo el rastro de un link a mis imagenes (soy el ilustrador de Focaclipart), pero me he quedado por que tambien soy linuxero (slacker) y relator informatico
Me ha parecido bastante útil tu guía. Iptables es uno de mis puntos debiles y nunca viene mal una explicación detallada.
Salu2
#2 por albertomolina el 6-01-12 - 12:22 am
Gracias por el comentario Vladimir, pero sobre todo gracias por poner a nuestra disposición las imágenes de focaclipart de forma libre :-)