Cortafuegos con iptables


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.

cortafuegos1

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:

cortafuegos2

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:

cortafuegos3cortafuegos4

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 eth0 -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 eth0 -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
Cortafuegos con iptables

14 comentarios en “Cortafuegos con iptables

  1. 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

    Me gusta

  2. Hola,

    Estoy trabajando en un proyecto muy interesante, no se que me recomiendes.

    Tengo una red con una tarjeta eth0 para el WAN, eth1 para LAN1 tipo 192.168.1.* y eth2 para LAN2 tipo 192.168.2.*, mi duda radica en dos puntos. Ya tengo NAT para las 2 redes, pero tengo una impresora en la IP 192.168.2.2 que quiero compartir a la red 192.168.1.* y ademas no quiero que las redes se vean entre si, me refiero a que cuando hago ping desde 192.168.1.* a 192.168.2.* y viceversa siempre me contestan, no quiero que lo hagan, prefiero que si voy a ver algún recurso compartido entren por dominio dinámico. Se puede hacer eso?

    Gracias de antemano

    Me gusta

  3. Joseph Veliz Castañeda dijo:

    Hola bien explicado, felicitaciones, quiero aprender mas de iptables, me puedes decir donde tienes tutoriales completos para poder aprender a profundo?

    Me gusta

  4. ME PARECE O HAY UN ERROR EN ESTO:
    # 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

    EN LA SEGUNDA LINEA DEBERIA DE SER DE ETH1 A ETH0 , CORRIGEME SI ESTOY MAL.

    Me gusta

    1. Hola Rodrigo,

      Gracias por tu comentario, pero lo siento, no he hecho un tutorial de iptables «avanzado», aunque tampoco creo que tuviera mucho sentido como una entrada de blog porque sería muy extenso. Lo que creo sí sería interesante sería hacer entradas de aspectos concretos de iptables o temas relacionados, lo iré haciendo cuando me encuentre algo que valga la pena compartir.

      Un saludo!

      Me gusta

  5. NGA dijo:

    Estimado tengo una consulta, en la DMZ indicaste lo siguiente:

    DMZ
    1.- Direccionamiento IP 192.168.2.0/24
    2.- Conectada a la interfaz eth2 del cortafuegos
    3.- 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)

    El servidor indicado en la tercera linea lo seteaste con ip 192.168.2.2, pero no indicas la interfaz (eth2 192.168.2.1 gateway DMZ), supongo que utilizaste una alias de tipo eth2:0 para manejarla individualmente

    estoy tratando de levantar tu ejemplo en maquinas virtuales pero no me funciona de este modo.

    Saludos.

    Me gusta

    1. Hola NGA,

      La dirección IP 192.168.2.2 corresponde a la interfaz eth0 del servidor que está en la DMZ y que aloja los servicios, no se corresponde con una dirección de ninguna interfaz del equipo que actúa como cortafuegos ni es necesario utilizar alias de red.

      Saludos!

      Me gusta

Deja un comentario