Introducción a iptables

Protege tu servidor con este potente cortafuegos gracias a unas reglas básicas y sencillas de entender.

Introducción

iptables es una potente herramienta que todo administrador de sistemas debería conocer y utilizar. Pero como desarrollador web, a veces es difícil sacar provecho a todas las funcionalidades que este enorme cortafuegos ofrece.

A continuación veremos un ejemplo de configuración de iptables restrictivo y útil, en el que cerraremos todos los puertos e iremos abriendo los necesarios según las necesidades personales de cada uno.

Lo primero es especificar qué tipo de reglas vamos a añadir. Esto se hace marcando el inicio y el fin:

*filter

# Aquí nuestras reglas

COMMIT

Reglas básicas

Utilizaremos una política restrictiva donde cerraremos todos los puertos por defecto:

-P INPUT DROP
-P OUTPUT DROP
-P FORWARD DROP

Si una conexión ya obtuvo permiso para interactuar con nuestra máquina, dejamos que los siga teniendo:

-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

También permitimos las conexiones loopback de nuestra máquina:

-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT

Y por último configuramos el sistema de registros:

-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
-A OUTPUT -j LOG --log-prefix "[Output Log] "

Reglas comunes

Las reglas vienen a ser bastante sencillas: especificamos el protocolo, el puerto e incluímos INPUT si queremos conexiones entrantes y/o OUTPUT si queremos conexiones salientes.

Por ejemplo, si nuestro servidor corre un servicio HTTP (Apache, Nginx, etc), generalmente nos interesa que se pueda acceder desde el exterior a los puertos 80 (HTTP) y 443 (HTTPS):

-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT

Y a su vez, si queremos navegar desde nuestro servidor hacia el exterior (p. ej. con lynx u otro navegador), necesitaremos crear la misma regla pero esta vez cambiando INPUT por OUTPUT:

-A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT

Sencillo, ¿verdad? A continuación una lista de reglas comunes que nos podría interesar añadir.

SSH

Para poder conectar por SSH y a su vez que nuestro servidor pueda conectar por SSH a otros servidores, necesitaremos crear las reglas INPUT y OUTPUT para el puerto 22:

-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 22 -j ACCEPT

DNS

Si queremos que nuestro servidor pueda consultar nombres de dominio a otros servidores DNS, necesitaremos abrir el puerto 53:

-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT

Y si nuestro servidor corre un servicio DNS (p. ej. BIND), utilizaremos INPUT:

-A INPUT -p udp -m udp --dport 53 -j ACCEPT

FTP

En el caso del protocolo FTP, normalmente nuestro servidor correrá el servicio FTP en el puerto 21. Pocas veces necesitaremos conectar desde nuestro servidor al exterior por FTP, así que solo INPUT:

-A INPUT -p tcp -m tcp --dport 21 -j ACCEPT

Rsync

Es muy común utilizar rsync para realizar backups. Además algunos gestores de paquetes en Linux también utilizan rsync para descargar paquetes. Para estos casos nos sirve la regla OUTPUT para el puerto 873:

-A OUTPUT -p tcp -m tcp --dport 873 -j ACCEPT

Git

El puerto por defecto para Git es 9418. Como no corremos un servidor Git en nuestra máquina y solo necesitamos descargar software a través de GitHub, utilizaremos lo siguiente:

-A OUTPUT -p tcp -m tcp --dport 9418 -j ACCEPT

Ping

Si queremos que nuestro servidor pueda enviar y recibir pings, estas son las reglas:

-A INPUT -p icmp -j ACCEPT
-A OUTPUT -p icmp -j ACCEPT

Resumen

Si quieres copiar y pegar todo el fichero de reglas, recuerda que lo tienes disponible en articles/introduction-to-iptables/rules.

En el repositorio del blog en GitHub encontrarás todo el contenido asociado con este y otros artículos.

Para limitar más aún la apertura del puerto y acceder desde una IP específica (por ejemplo, para conectar únicamente desde nuestro ordenador de sobremesa), solo hay que añadir el parámetro -s 12.34.56.78 a la regla en cuestión.

Para cargar las reglas en iptables basta con guardar estas reglas en un fichero y después ejecutar iptables-restore < fichero.

Una vez hayamos cargado las reglas en iptables, si queremos reemplazar las reglas por otras nuevas o si queremos eliminar las actuales, debemos ejecutar una serie de comandos:

iptables -F
iptables -X
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT

Esto eliminará las reglas existentes y permitirá acceso de nuevo a todo.

Si solo hacemos flush (iptables -F), eliminaremos las reglas pero nos quedaremos sin conexión, por lo que no es buena idea.

Puedes apoyarme para que pueda dedicar aún más tiempo a escribir artículos y tener recursos para crear nuevos proyectos. ¡Gracias!