IPTables - Cortafuegos
Iptables es un firewall de software incluido en la mayoría de las distribuciones de Linux que controla el tráfico de red entrante y saliente en un sistema. Su función es permitir o denegar el tráfico de red basado en reglas configuradas por el usuario.
Iptables utiliza tablas para almacenar y organizar las reglas de firewall, que se aplican a paquetes de red en función de ciertos criterios como la dirección IP, el puerto de origen y destino, el protocolo utilizado y la interfaz de red.
Las reglas de iptables se definen en cadenas, que son secuencias de reglas aplicadas a paquetes de red. Hay cinco cadenas predefinidas: INPUT, OUTPUT, FORWARD, PREROUTING y POSTROUTING, que controlan el tráfico de red que llega al sistema, sale del sistema, se reenvía a través del sistema, se redirecciona antes de que se envíe o después de que se reciba.
Iptables también tiene la capacidad de crear reglas personalizadas para adaptarse a las necesidades específicas de una organización o usuario. Las reglas se pueden configurar mediante el uso de comandos de línea de comandos o utilizando herramientas de configuración gráficas.
Cómo funciona iptables
El tráfico de red se compone de paquetes. Los datos se dividen en trozos más pequeños (llamados paquetes), se envían por la red y luego se vuelven a unir. Iptables identifica los paquetes recibidos y utiliza un conjunto de reglas para decidir qué hacer con ellos.
Iptables filtra los paquetes basándose en:
- Tablas: Las tablas son archivos que unen acciones similares. Una tabla consiste en varias cadenas.
- Cadenas: Una cadena es una cadena de reglas. Cuando se recibe un paquete, iptables busca la tabla apropiada y lo ejecuta a través de la cadena de reglas hasta que encuentra una coincidencia.
- Reglas: Una regla es una declaración que le dice al sistema qué hacer con un paquete. Las reglas pueden bloquear un tipo de paquete, o reenviar otro tipo de paquete. El resultado, el lugar al que se envía un paquete, se denomina objetivo.
- Objetivos: Un objetivo es una decisión sobre qué hacer con un paquete. Normalmente, se trata de aceptarlo, descartarlo o rechazarlo (lo que devuelve un error al remitente).
Tablas y cadenas
El cortafuegos de Linux iptables tiene cuatro tablas por defecto. A continuación se enumeran las cuatro junto con las cadenas que cada tabla contiene.
Filter
La tabla Filter es la más utilizada. Actúa como un portero, decidiendo quién entra y quién sale de tu red. Tiene las siguientes cadenas por defecto:
- Input (Entrada) - las reglas en esta cadena controlan los paquetes recibidos por el servidor.
- Output (Salida) - esta cadena controla los paquetes para el tráfico saliente.
- Forward (Reenvio) - este conjunto de reglas controla los paquetes que son enrutados a través del servidor.
Network Address Translation (NAT)
Esta tabla contiene reglas NAT (Network Address Translation) para enrutar paquetes a redes a las que no se puede acceder directamente. Cuando hay que modificar el destino o el origen del paquete, se utiliza la tabla NAT. Incluye las siguientes cadenas:
- Prerouting - esta cadena asigna los paquetes en cuanto el servidor los recibe.
- Output - funciona igual que la cadena de salida que describimos en la tabla de filtros.
- Postrouting - las reglas de esta cadena permiten hacer cambios en los paquetes después de que salgan de la cadena de salida.
Mangle
La tabla Mangle ajusta las propiedades de la cabecera IP de los paquetes. La tabla tiene todas las siguientes cadenas que se han descrito anteriormente:
- Prerouting
- Postrouting
- Output
- Input
- Forward
Raw - Sin Procesar
La tabla Raw se utiliza para eximir a los paquetes del seguimiento de conexiones. La tabla Raw tiene dos de las cadenas que anteriormente se mencionaron:
- Prerouting
- Output
Seguridad (Opcional)
Algunas versiones de Linux también utilizan una tabla de Seguridad para gestionar reglas de acceso especiales. Esta tabla incluye cadenas de entrada, salida y reenvío, de forma muy similar a la tabla de filtros.
Objetivos
Un objetivo es lo que ocurre después de que un paquete coincida con los criterios de una regla. Los objetivos sin terminación siguen comparando los paquetes con las reglas de una cadena incluso cuando el paquete coincide con una regla.
Con los objetivos de terminación, un paquete se evalúa inmediatamente y no se compara con otra cadena. Los objetivos finales en Linux iptables son:
- Accept - esta regla acepta que los paquetes atraviesen el cortafuegos de iptables.
- Drop - el paquete descartado no se compara con ninguna otra cadena. Cuando iptables descarta una conexión entrante a su servidor, el usuario que intenta conectarse no recibe ningún error. Parece como si estuvieran intentando conectarse a una máquina inexistente.
- Return - esta regla devuelve el paquete a la cadena de origen para que pueda compararlo con otras reglas.
- Reject - el cortafuegos rechaza el paquete y envía un error al dispositivo de conexión.
Instalación de Iptables
Ejecutar los siguientes comandos uno a uno:
sudo apt-get update
sudo apt-get install iptables
En el caso de necesitar arracar iptables existen los comandos:
sudo systemctl enable iptables
sudo systemctl start iptables
Para verificar el estado del servicio ejecutar el comando:
sudo systemctl status iptables
Comprobar el estado de la configuración actual de iptables ejecutando:
sudo iptables -L -v
La opción -L se utiliza para listar todas las reglas, y -v (verbose) para mostrar la información en un formato más detallado.
El sistema muestra el estado de sus cadenas. La salida mostrará una lista de tres cadenas:
Chain INPUT (policy ACCEPT)
Chain FORWARD (policy ACCEPT)
Chain OUTPUT (policy ACCEPT)
Ahora ya estará instalado el cortafuegos en Linux. En este punto, se puede observar que todas las conexiones están configuradas como ACEPTAR y no hay reglas. Eso no es seguro ya que cualquier paquete puede pasar sin ser filtrado.
Comandos más habituales
Esta es una lista de algunas de las opciones comunes de iptables:
- -A --append - Añade una regla a una cadena (al final).
- -C --check - Busca una regla que coincida con los requisitos de la cadena.
- -D --delete - Elimina las reglas especificadas de una cadena.
- -F --flush - Elimina todas las reglas.
- -I --insert - Añade una regla a una cadena en una posición determinada.
- -L --list - Mostrar todas las reglas de una cadena.
- -N -new-chain - Crear una nueva cadena.
- -v --verbose - Muestra más información cuando se utiliza una opción de lista.
- -X --delete-chain - Elimina la cadena proporcionada.
Iptables distingue entre mayúsculas y minúsculas (Case Sensitive), así que hay que verificar la utilización de las opciones correctas.
Definir las reglas de la cadena
Definir una regla significa añadirla a la cadena. Para ello, es necesario insertar la opción -A (Append) justo después del comando iptables, de la siguiente manera:
sudo iptables -A
Este comando alertará a iptables de que está añadiendo nuevas reglas a una cadena. Se puede combinar el comando con otras opciones, tales como:
- -i (interfaz) - la interfaz de red cuyo tráfico desea filtrar, como eth0, lo, ppp0, etc.
- -p (protocolo) - el protocolo de red donde se realiza el filtrado. Puede ser tcp, udp, udplite, icmp, sctp, icmpv6, etc. También es posible escribir all para seleccionar todos los protocolos.
- -s (source) - la dirección de la que proviene el tráfico. Se puede añadir un nombre de host o una dirección IP.
- -dport (puerto de destino) - el número de puerto de destino de un protocolo, como 22 (SSH), 443 (https), etc.
- -j (destino) - el nombre del destino (ACCEPT, DROP, RETURN). Es necesario insertar esto cada vez que se establece una nueva regla.
Si se desea hacer uso de todas ellas, se debe escribir el comando en este orden:
sudo iptables -A <chain> -i <interface> -p <protocol (tcp/udp) > -s <source> --dport <port no.> -j <target>
Permitir el tráfico en Localhost
Para permitir el tráfico en localhost, escribir el siguiente comando:
sudo iptables -A INPUT -i lo -j ACCEPT
Se utiliza lo o loopback interface para todas las comunicaciones en el localhost. El comando anterior se asegura de que las conexiones entre una base de datos y una aplicación web en la misma máquina funcionan correctamente.
Permitir conexiones a través de los puertos HTTP, SSH y SSL
Si se desea que las conexiones HTTP (puerto 80), HTTPS (puerto 443) y SSH (puerto 22) funcionen normalmente. Para ello, es necesario especificar el protocolo (-p) y el puerto correspondiente (-dport). Estos comandos se pueden ejecutar uno a uno:
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
Las opciones funcionan de la siguiente manera:
- -p - Comprueba el protocolo especificado (tcp).
- --dport - Especifica el puerto de destino.
- -j jump - Realiza la acción especificada.
Verificar si las reglas han sido añadidas en iptables:
sudo iptables -L -v
Permitir sólo SSH
Para permitir sólo conexiones SSH de entrada y conexiones loopback, se puede utilizar la siguiente configuración.
-A INPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT
-A FORWARD -j REJECT
Filtrado de paquetes basado en el origen (SOURCE)
Iptables permite filtrar paquetes basándose en una dirección IP o en un rango de direcciones IP. Es necesario especificarlo con la opción -s. Por ejemplo, para aceptar paquetes desde 192.168.1.5, el comando es:
sudo iptables -A INPUT -s 192.168.1.5 -j ACCEPT
También se pueden rechazar paquetes de una dirección IP concreta sustituyendo el objetivo ACCEPT por DROP.
sudo iptables -A INPUT -s 192.168.1.5 -j DROP
Si se desea descartar paquetes de un determinado rango de direcciones IP, se debe utilizar la opción -m y el módulo iprange. A continuación, especificar el rango de direcciones IP con -src-range. Recordar, que un guión debe separar el rango de direcciones ip sin dejar espacio, de la siguiente manera:
sudo iptables -A INPUT -m iprange --src-range 192.168.1.100-192.168.1.200 -j DROP
Las opciones de iptables utilizadas en los ejemplos funcionan de la siguiente manera:
- -m - Coincide con la opción especificada.
- -iprange - Indica al sistema que espere un rango de direcciones IP en lugar de una sola.
- --src-range - Identifica el rango de direcciones IP.
Descartar (DROP) el resto del tráfico
Es crucial utilizar el objetivo DROP para el resto del tráfico después de definir las reglas -dport. Esto evitará que una conexión no autorizada acceda al servidor a través de otros puertos abiertos. Para conseguirlo, simplemente basta con introducir el comando:
sudo iptables -A INPUT -j DROP
Ahora, las conexiones que no se ajusten al puerto especificado se descartarán.
Borrar Reglas
Si se desea eliminar todas las reglas y empezar de cero, se puede utilizar la opción -F (flush):
sudo iptables -F
Este comando borra todas las reglas actuales. Sin embargo, para borrar una regla específica, se debe utilizar la opción -D. En primer lugar, es necesario ver todas las reglas disponibles introduciendo el siguiente comando:
sudo iptables -L --line-numbers
Se obtiene un listado de reglas numeradas.
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- 192.168.0.4 anywhere
2 ACCEPT tcp -- anywhere anywhere tcp dpt:https
3 ACCEPT tcp -- anywhere anywhere tcp dpt:http
4 ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
Para eliminar una regla, basta con introducir la respectiva cadena y el número de la lista. Digamos que para este tutorial de iptables, queremos eliminar la regla número dos de la lista INPUT. El comando debería ser:
sudo iptables -D INPUT 2
Cambios permanentes
Las reglas creadas en iptables se guardan en memoria, por lo que deben ser almacenadas en un archivo para su posterior carga después de un reinicio.
Para realizar estas modificaciones, se pueden utilizar los comandos correspondientes según se trate de reglas IPv4 o IPv6.
sudo iptables-save > /etc/iptables/rules.v4
sudo iptables-save > /etc/iptables/rules.v6
Ahora cada vez que se reinicie el VPS tendrá que cargar las reglas guardadas con los siguientes comandos:
sudo iptables-restore < /etc/iptables/rules.v4
sudo iptables-restore < /etc/iptables/rules.v6
Si se desea que el proceso de carga sea completamente automático, se puede configurar el paquete iptables-persistent y él se encargará de cargar las reglas automáticamente.
sudo apt-get install iptables-persistent
Recursos
- https://www.sobyte.net/post/2022-04/understanding-netfilter-and-iptables/
- https://www.digitalocean.com/community/tutorials/iptables-essentials-common-firewall-rules-and-commands
- https://sbarjatiya.com/website/tutorials/iptables/iptables.pdf
- https://www.comparitech.com/net-admin/beginners-guide-ip-tables/
- https://www.digitalocean.com/community/tutorials/a-deep-dive-into-iptables-and-netfilter-architecture
- https://www.digitalocean.com/community/tutorials/how-to-list-and-delete-iptables-firewall-rules
- https://www.linuxadictos.com/como-configurar-el-firewall-en-linux-con-iptables.html