iptables es una herramienta de línea de comandos que permite configurar reglas de filtrado de paquetes en Linux. Se utiliza para definir qué tráfico de red se permite o se bloquea, ayudando a proteger el sistema frente a conexiones no deseadas.
Aunque Ubuntu incorpora herramientas simplificadas como ufw para la gestión del firewall, aprender a usar iptables directamente proporciona un mayor nivel de control y flexibilidad.
Iptables es el sucesor del anterior ipfwadm e ipchains y esta disponible desde la versión 2.4 del kernel linux (2001) y ha sido desarrollado por el .
Algunas de las ventajas de este software es que puede trabajar conjuntamente con ip6tables, ebtables y arptables, sin embargo, ya no se desarrollan nuevas funcionalidades por que va a ser sustituido por un nuevo proyecto, , disponible desde la versión 3.13 del kernel linux (2014), pero que añade una capa de compatibilidad con iptables, otorga mas peso al usuario y es de alto rendimiento. También empieza a escucharse un nuevo proyecto llamado , mas moderno y de alto rendimiento pero poco maduro.
Para el uso de iptables en linux es necesario conocer algunos conceptos previos:
Más info:
La información de iptables la podemos ver en:
apt show iptables
Se puede hacer la siguiente clasificación del tipo de tráfico que lo relacionamos con las cadenas (chains):
Entrante con destino el equipo (INPUT)
Saliente, originado en el equipo (OUTPUT)
Que atraviesa el equipo (entra por una interfaz de red y sale por otra, FORWARD)
Esto, junto a lo que queramos hacer, nos permite agrupar las reglas que tienen la siguiente jerarquía:
Reglas por tráfico
Las reglas se agrupan en cadenas
Las cadenas se agrupan en tablas
Tablas y cadenas (chains)
iptables organiza las reglas en diferentes tablas según la función (ordenado de más común a menos):
Tabla
Descripción
Comando
filter
Es la tabla por defecto, si no especifico nada usa esta, usada para filtrar paquetes (cortafuegos).
sudo iptables
nat
Se usa para la traducción de direcciones (por ejemplo, redireccionamiento de puertos).
sudo iptables -t nat -L -v -n
mangle
Permite modificar ciertos campos de los paquetes, marcarlos y modificarlos.
sudo iptables -t mangle -L -v -n
raw
para depurar la conexión.
security
Usada para control de la MAC (por ejemplo con SELinux)
Cadenas de filter:
INPUT: Maneja paquetes entrantes dirigidos a mi máquina.
OUTPUT: Gestiona paquetes que se generan y salen de mi máquina.
FORWARD: Se utiliza para paquetes que pasan a través de mi máquina (enrutamiento).
Cadenas de nat:
PREROUTING: Pensada para hacer modificaciones de tipo NAT antes de tomar la decision de encaminamiento por ejemplo, cambiarle la dirección IP destino. Esto se ejecuta antes del FORWARD
INPUT y OUTPUT: Casos más específicos
Como se ve en el gráfico, básicamente se mira si el paquete esta destinado a la propia maquina o si va a otra. Para los paquetes (o datagramas, según el protocolo) que van a la propia maquina se aplican las reglas INPUT y OUTPUT, y para filtrar paquetes que van a otras redes o maquinas se aplican simplemente reglas FORWARD.
En nuestra máquina hay reglas aplicadas y empiezan a llegar/salir/pasar paquetes. Por ahora olvidemos la red, las reglas están a nivel de kernel, y al kernel lo que le llega es un paquete y tiene que decidir que hacer con él. El kernel lo que hace es, dependiendo si el paquete es para la propia maquina o para otra maquina, consultar las reglas de firewall y decidir que hacer con el paquete según mande el firewall. Por ejemplo:
Paquete del exterior con destino al equipo:
PREROUTING de nat e INPUT de nat y filter
Paquete originado en el equipo que sale:
OUTPUT de nat, OUTPUT de filter y POSTROUTING de nat
Paquete que atraviesa el equipo
PREROUTING de nat, FORWARD de filter y POSTROUTING de nat
INPUT, OUTPUT y FORWARD son los tres tipos de reglas de filtrado. Pero antes de aplicar esas reglas es posible aplicar reglas de NAT: estas se usan para hacer redirecciones de puertos o cambios en las IPs de origen y destino.
E incluso antes de las reglas de NAT se pueden meter reglas de tipo MANGLE, destinadas a modificar los paquetes; son reglas poco conocidas y es probable que no las usen.
El ultimo concepto son las acciones (TARGETs), estas funcionan como una ACL. Cuando llega un paquete se leen secuencialmente todas las reglas al paquete hasta que se encuentra una regla aplicable a este, y ahora que hago con ella? Pues una vez se defina una regla hay que determinar qué hacer con el paquete:
ACCEPT: Se permite el paso del paquete si cumple la característica.
DROP: Se elimina silenciosamente el paquete.
RETURN: Cumple la regla y deja de leer más reglas y pasa a la siguiente cadena, esto ocurre cuando te interesa optimizar la lectura de reglas.
Si no se encuentra ninguna regla se aplica la política de la cadena.
Es recomendable que recuerdes como funciona el protocolo TCP/IP
, una conexión tcp/ip empieza con el
three−way−handshake:
− La maquina que desea conectarse a otra envía un paquete con flan SYN
− Si la otra maquina acepta, envía un SYN/ACK
− Entonces la máquina establece la conexión.
Comandos Básicos de iptables
Listar reglas:
sudo iptables -L -vn --line-numbers
Este comando muestra las reglas actuales en todas las cadenas del filter con detalles, o bien por si quiero verlo de la forma que lo añado:
sudo iptables -S [chain] -v
Agregar unas reglas por defecto:
sudo iptables [-t TABLA] -P [CADENA] ACCEPT|DROP
# por ejemplos
Por ejemplo, bloquear todo el trafico por FORWARD:
sudo iptables -t filter -P FORWARD DROP
#Aunque no tiene sentido por que filter es la tabla por defecto
Agregar reglas sencillas, se puede hacer con Append (-A) o con Insert (-I) dependiendo si te interesa añadirla al final o al principio respectivamente:
iptables -A [CADENA] [-p PROTOCOLO] [-s IP ORIGEN] [-d IP DESTINO] [-i INTERFAZ ENTRADA] [-o INTERFAZ SALIDA] [-j ACCEPT|DROP]
iptables -I [CADENA] [-p PROTOCOLO] [-s IP ORIGEN] [-d IP DESTINO] [-i INTERFAZ ENTRADA] [-o INTERFAZ SALIDA] [-j ACCEPT|DROP]
Podemos poner una exclamación (!) para determinar la regla inversa, por ejemplo
#Permitir todo menos una IP específica
iptables -A INPUT -s ! 192.168.1.100 -j ACCEPT
#Bloquear todo el tráfico excepto el puerto 22 (SSH)
iptables -A INPUT -p tcp ! --dport 22 -j DROP
#Aceptar paquetes que no vengan por la interfaz eth0
iptables -A INPUT -i ! eth0 -j ACCEPT
Ejemplo de uso de reglas
Vamos ahora a ver un ejemplo de como funciona con los paquetes de entrada que tienen como destino mi máquina con protocolo icmp con origen la IP de red y que entren por la interfaz eth0 se aceptan:
Podemos ver ahora la regla listándola y, si hacemos un ping al GW 192.128.100.1 podremos ver que los paquetes se han contabilizado. Si ahora configuramos para que no se acepte ningún paquete:
iptables -P OUTPUT DROP
Veremos que (primero nos echa de la sesión de SSH) y que los paquetes siguen contabilizándose pero que no llegan:
Más ejemplos:
Para aceptar tráfico HTTP en la cadena INPUT:
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
Si probamos veremos que se envian paquetes pero no se reciben
iptables -A INPUT -o enp0s3 -p icmp -j ACCEPT
Sin embargo, si yo ahora hago ping a localhost seguirá sin funcionar por que solo hemos especificado el adaptador enp0s3, es común añadir las siguientes reglas:
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
Ahora cualquier protocolo con mi máquina funcionará.
Vamos a configurar ahora que se envíen y reciban las peticiones DNS al servidor DNS que tengamos configurado:
iptables -F # Borra todas las reglas en todas las cadenas
iptables -X # Elimina todas las cadenas creadas por el usuario
iptables -Z # Resetea los contadores de paquetes y bytes
iptables -t nat -F # Borra todas las reglas en la tabla NAT
iptables -t nat -X # Elimina todas las cadenas en la tabla NAT
iptables -t mangle -F # Borra reglas en la tabla MANGLE (opcional)
iptables -t mangle -X # Elimina cadenas en MANGLE (opcional)
iptables -t raw -F # Borra reglas en la tabla RAW (opcional)
iptables -t raw -X # Elimina cadenas en RAW (opcional)
iptables -P INPUT ACCEPT # Aceptar tráfico entrante (puedes cambiarlo a DROP después)
iptables -P FORWARD ACCEPT # Aceptar tráfico reenviado
iptables -P OUTPUT ACCEPT # Aceptar tráfico saliente
#Comprobación:
iptables -L -v -n --line-numbers
iptables -t nat -L -v -n
En Ubuntu es común usar el paquete iptables-persistent para que las reglas se carguen al iniciar el sistema.
Depuración de reglas
Antes de nada, para comprobar que las reglas están funcionando o no, debemos habituarnos a ciertos comandos para la comprobación, depende lo que quieras realizar:
✔ Ver reglas activas y contar paquetes
iptables -L -v -n --line-numbers
✔ Capturar paquetes rechazados por iptables
sudo dmesg | grep iptables
✔ Ver tráfico en un puerto específico en tiempo real
sudo tcpdump -i enp0s3 port 22
✔ Ver conexiones activas en la red (debe instalarse net-tools)
netstat -anp | grep ESTABLISHED
✔ Monitorizar tráfico en tiempo real con más detalles (debe instalarse)
iftop -i eth0
Escenario de configuración
Crearemos una máquina virtual (Ubuntu server en mi caso) con la siguiente configuración de adaptadores:
Para este tipo de simulación recomiendo configurar tres adaptadores (o dos pero después añadiremos otro):
Uno o dos en "Red Interna" para conectarse con la LAN interna (donde se ubica el servidor interno) y posteriormente la DMZ.
El otro en "NAT Network" para simular la conexión al exterior.
Con el adaptador en NAT Network, la VM podrá realizar conexiones salientes (y si lo configuras, recibir ciertas conexiones entrantes) que imitan el funcionamiento de una red pública.
Aunque también se podría conectar en modo adaptador puente si te es más fácil.
Los servidores y clientes tendrán la .100 por defecto.
Ten cuidado, con esta simulación, desde el principio verás que, a pesar de las redes, estas no tienen conocimiento entre si ya que los paquetes no pasan de la máquina firewall, para que funcione hay que habilitar el byte forward:
echo 1 > /proc/sys/net/ipv4/ip_forward
Esto pondrá a "1" este proceso.
PRÁCTICA: protegiendo la máquina con un script
A continuación, vamos a ver algunos ejemplos guiados para construir un script que satisfaga nuestras necesidades de IT, para ello usaremos un script que iremos modificando progresivamente.
Los scripts de iptables deberían tener este aspecto:
Saludo a la afición (echo)
Borrado de las reglas aplicadas actualmente (flush)
Aplicación de políticas por defecto para INPUT, OUPUT, FORWARD
Listado de reglas iptables
Ten en cuenta que cuando la política es DROP a cada regla de INPUT le suele corresponder una de OUTPUT.
Supongamos que tenemos un servidor contra una red entera, vamos a configurar algunas reglas sencillas:
#!/bin/sh
## SCRIPT de IPTABLES − ejemplo del manual de iptables
## Ejemplo de script para proteger la propia máquina
echo −n Aplicando Reglas de Firewall...
## FLUSH de reglas
#Elimina todas las reglas en las cadenas predeterminadas.
iptables −F
#Borra las cadenas personalizadas si existen.
iptables −X
#Restablece los contadores de paquetes/bytes.
iptables −Z
#Borra las reglas de la tabla NAT
iptables −t nat −F
## Establecemos politica por defecto
#Acepta conexiones entrantes y salientes y de forward
iptables −P INPUT ACCEPT
iptables −P OUTPUT ACCEPT
iptables −P FORWARD ACCEPT
#No filtra paquetes NAT:
iptables −t nat −P PREROUTING ACCEPT
iptables −t nat −P POSTROUTING ACCEPT
## Empezamos a filtrar
# El adaptador localhost (lo) se deja (por ejemplo conexiones locales a mysql)
/sbin/iptables −A INPUT −i lo −j ACCEPT
# A nuestra IP le dejamos todo
iptables −A INPUT −s 10.0.0.5 −j ACCEPT
# A un colega le dejamos entrar al mysql para que mantenga la BBDD
iptables −A INPUT −s 10.0.0.100 −p tcp −−dport 3306 −j ACCEPT
# A un diseñador le dejamos usar el FTP
iptables −A INPUT −s 10.0.0.120 −p tcp −-dport 20:21 −j ACCEPT
# El puerto 80 de www debe estar abierto, es un servidor web.
iptables −A INPUT −p tcp −−dport 80 −j ACCEPT
# Cerramos rango de los puertos privilegiados. Cuidado con este tipo de
# barreras, antes hay que abrir a los que si tienen acceso.
iptables −A INPUT −p tcp −−dport 1:1024 -j DROP
iptables −A INPUT −p udp −−dport 1:1024 -j DROP
# Cerramos otros puertos que estan abiertos
iptables −A INPUT −p tcp −−dport 3306 −j DROP
iptables −A INPUT −p tcp −−dport 10000 −j DROP
iptables −A INPUT −p udp −−dport 10000 −j DROP
echo " OK . Verifique lo que se aplica con: iptables −L −n"
## Fin del script
Guardamos el script y le damos permisos de ejecución:
chmod +x firewall.sh
Firewall de una LAN con salida a internet
Ahora vamos a ver una configuración de firewall iptables para el típico caso de red local que necesita salida a internet.
Para este caso nos hace falta una regla que haga NAT hacia fuera (enmascaramiento en iptables), con lo que se haría dos veces NAT (en el firewall y en el router). Entre el router y el firewall lo normal es que haya una red privada (En nuestro caso enp0s3 como adaptador WAN en 89.67.45.23 y enp0s8 como adaptador LAN en 10.0.0.0), aunque dependiendo de las necesidades puede que los dos tengan IP pública.
El router se supone que hace un NAT completo hacia dentro, o sea que desde el exterior no se llega al router si no que de forma transparente se "choca" contra el firewall. Lo normal en este tipo de firewalls es poner la política por defecto de FORWARD en denegar (DROP), pero eso lo vemos más adelante.
Veamos como sería este firewall−gateway, vamos a usar el siguiente script:
#!/bin/sh
## SCRIPT de IPTABLES − ejemplo del manual de iptables
## Ejemplo de script para firewall entre red−local e internet
## con filtro para que solo se pueda navegar.
echo −n Aplicando Reglas de Firewall...
## FLUSH de reglas
iptables −F
iptables −X
iptables −Z
iptables −t nat −F
## Establecemos politica por defecto
iptables −P INPUT ACCEPT
iptables −P OUTPUT ACCEPT
iptables −P FORWARD ACCEPT
iptables −t nat −P PREROUTING ACCEPT
iptables −t nat −P POSTROUTING ACCEPT
## Empezamos a filtrar
## Nota: enp0s3 es el interfaz conectado al router y enp0s8 a la LAN
# El localhost se deja (por ejemplo conexiones locales a mysql)
/sbin/iptables −A INPUT −i lo −j ACCEPT
# Al firewall tenemos acceso desde la red local
iptables −A INPUT −s 10.0.0.0/24 −i enp0s8 −j ACCEPT
## Ahora con regla FORWARD filtramos el acceso de la red local
## al exterior. Como se explica antes, a los paquetes que no van dirigidos al
## propio firewall se les aplican reglas de FORWARD
# Aceptamos que vayan a puertos 80
iptables −A FORWARD −s 10.0.0.0/24 −i enp0s8 −p tcp −−dport 80 −j ACCEPT
# Aceptamos que vayan a puertos https
iptables −A FORWARD −s 10.0.0.0/24 −i enp0s8 −p tcp −−dport 443 −j ACCEPT
# Aceptamos que consulten los DNS
iptables −A FORWARD −s 10.0.0.0/24 −i enp0s8 −p tcp −−dport 53 −j ACCEPT
iptables −A FORWARD −s 10.0.0.0/24 −i enp0s8 −p udp −−dport 53 −j ACCEPT
# Y denegamos el resto. Si se necesita alguno, ya avisaran
iptables −A FORWARD −s 10.0.0.0/24 −i enp0s8 −j DROP
# Ahora hacemos enmascaramiento de la red local,
# reemplazando la IP de origen de los paquetes con la IP pública de la interfaz enp0s3
# permitiendo que los dispositivos de la red privada accedan a Internet.
iptables −t nat −A POSTROUTING −s 10.0.0.0/244 −o enp0s3 −j MASQUERADE
# Con esto permitimos hacer forward de paquetes en el firewall, o sea
# que otras máquinas puedan salir a traves del firewall.
echo 1 > /proc/sys/net/ipv4/ip_forward
## Y ahora cerramos los accesos indeseados del exterior:
# Nota: 0.0.0.0/0 significa: cualquier red
# Cerramos el rango de puerto bien conocido
iptables −A INPUT −s 0.0.0.0/0 −p tcp −dport 1:1024 −j DROP
iptables −A INPUT −s 0.0.0.0/0 −p udp −dport 1:1024 −j DROP
# Cerramos un puerto de gestión: webmin
iptables −A INPUT −s 0.0.0.0/0 −p tcp −dport 10000 −j DROP
echo " OK . Verifique que lo que se aplica con: iptables −L −n"
# Fin del script
De nuevo, no te olvides de darle permisos de usuario.
Vamos a complicar un poco mas el script, ahora supongamos:
El servidor de firewall también es un servidor de SMTP, pop3,
El jefe quiere entrar al servidor por PPTPD (VPN)
Añadimos una máquina Windows server que tenemos dentro de la red local con IIS
Nos han pedido que permitamos la gestión por terminal remoto (RDP) para esta máquina para una empresa externa que se encarga del mantenimiento de la web.
Tengamos en cuenta que ahora vamos a trabajar reglas de entrada del exterior para los servicios y con redirecciones de puertos (para el servidor windows):
#!/bin/sh
## SCRIPT de IPTABLES − ejemplo del manual de iptables
## Ejemplo de script para firewall entre red−local e internet
echo −n Aplicando Reglas de Firewall...
## FLUSH de reglas
iptables −F
iptables −X
iptables −Z
iptables −t nat −F
## Establecemos politica por defecto
iptables −P INPUT ACCEPT
iptables −P OUTPUT ACCEPT
iptables −P FORWARD ACCEPT
iptables −t nat −P PREROUTING ACCEPT
iptables −t nat −P POSTROUTING ACCEPT
## Empezamos a filtrar
## REDIRECCIONES
# Todo lo que venga por el exterior y vaya al puerto 80 lo redirigimos
# a una maquina interna
iptables −t nat −A PREROUTING −i enp0s3 −p tcp −−dport 80 −j DNAT −−to 10.0.0.50:80
# Los accesos de un ip determinada (221.23.124.181) a Terminal
# server se redirigen e esa maquina
iptables −t nat −A PREROUTING −s 221.23.124.181 −i enp0s3 −p tcp −−dport 3389 −j DNAT −−to 10.0.0.50:3389
## Nota: enp0s3 es el interfaz conectado al router y enp0s8 a la LAN
# El localhost se deja (por ejemplo conexiones locales a mysql)
iptables −A INPUT −i lo −j ACCEPT
# Al firewall tenemos acceso desde la red local
iptables −A INPUT −s 10.0.0.0/24 −i enp0s8 −j ACCEPT
## Abrimos el acceso a puertos de correo
# Abrimos el puerto 25, hay que configurar bien el relay del servidor SMTP
iptables −A INPUT −s 0.0.0.0/0 −p tcp −−dport 25 −j ACCEPT
# Abrimos el pop3
iptables −A INPUT −s 0.0.0.0/0 −p tcp −−dport 110 −j ACCEPT
# Y abrimos el puerto pptpd para la ip de la VPN con PPTPD
iptables −A INPUT −s 211.45.176.24 −p tcp −−dport 1723 −j ACCEPT
## Ahora con regla FORWARD filtramos el acceso de la red local
## al exterior. Como se explica antes, a los paquetes que no van dirigidos al
## propio firewall se les aplican reglas de FORWARD, por lo tanto pasan por encima
# Aceptamos que vayan a puertos 80
iptables −A FORWARD −s 10.0.0.0/24 −i enp0s8 −p tcp −−dport 80 −j ACCEPT
# Aceptamos que vayan a puertos https
iptables −A FORWARD −s 10.0.0.0/24 −i enp0s8 −p tcp −−dport 443 −j ACCEPT
# Aceptamos que consulten los DNS
iptables −A FORWARD −s 10.0.0.0/24 −i enp0s8 −p tcp −−dport 53 −j ACCEPT
iptables −A FORWARD −s 10.0.0.0/24 −i enp0s8 −p udp −−dport 53 −j ACCEPT
# Y denegamos el resto. Si se necesita alguno, ya avisaran
iptables −A FORWARD −s 10.0.0.0/24 −i enp0s8 −j DROP
# Hacemos enmascaramiento de la red local, imprescindible para el funcionamiento
iptables −t nat −A POSTROUTING −s 10.0.0.0/24 −o enp0s3 −j MASQUERADE
# Con esto permitimos hacer forward de paquetes en el firewall, o sea
# que otras máquinas puedan salir a traves del firewall.
echo 1 > /proc/sys/net/ipv4/ip_forward
## Y ahora cerramos los accesos indeseados del exterior:
# Cerramos el rango de puerto bien conocido
iptables −A INPUT −s 0.0.0.0/0 −i enp0s3 −p tcp −dport 1:1024 −j DROP
iptables −A INPUT −s 0.0.0.0/0 −i enp0s3 −p udp −dport 1:1024 −j DROP
# Cerramos un puerto de gestión: webmin
iptables −A INPUT −s 0.0.0.0/0 −i enp0s3 −p tcp −−dport 10000 −j DROP
# Y cerramos el puerto del servicio PPTPD, solo abierto para el usuario de la VPN.
iptables −A INPUT −s 0.0.0.0/0 −i enp0s3 −p tcp −−dport 1723 −j DROP
echo " OK . Verifique que lo que se aplica con: iptables −L −n"
# Fin del script
Bueno ya tenemos montada la red, pero conviene insistir en que esta última configuración, con las redirecciones y los servicios de correo funcionando en el firewall es bastante insegura. ¿Qué ocurre si hackean el servidor IIS de la red local? Pues que el firewall no sirve de gran cosa, lo poco que podría hacer una vez se ha entrado en la red local es evitar escaneos hacia el exterior desde la máquina atacada, aunque para ello el firewall debiera tener una buena configuración con denegación por defecto.
Firewall de una LAN con salida a internet con DMZ
Vamos complicando la situación, ahora imaginemos que tenemos una red parecida a la anterior pero ahora hacemos las cosas bien y colocamos ese servidor IIS en una DMZ:
En esta configuración tenemos un servidor web expuesto (10.0.90.2/24) y una red LAN de clientes (10.0.80.0/24), por lo tanto, con este tipo de firewall hay que permitir.
Acceso de la red local a internet.
Acceso público al puerto tcp/80 y tcp/443 del servidor de la DMZ
Acceso del servidor de la DMZ a una BBDD mysql de la LAN
Obviamente bloquear el resto de acceso de la DMZ hacia la LAN.
Ten en cuenta que para filtrar el tráfico de la DMZ y la LAN solo podemos usar las reglas FORWARD, ya que estamos filtrando entre distintas redes, no son paquetes destinados al propio firewall, tienen que pasar a través de él, vamos con el script:
#!/bin/sh
## SCRIPT de IPTABLES − ejemplo del manual de iptables
## Ejemplo de script para firewall entre red−local e internet con DMZ
echo "Aplicando Reglas de Firewall..."
## FLUSH de reglas
iptables -F
iptables -X
iptables -Z
iptables -t nat -F
## Establecemos politica por defecto
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
## Empezamos a filtrar
# Todo lo que venga por el exterior y vaya al puerto 80 lo redirigimos al server
iptables -t nat -A PREROUTING -i enp0s3 -p tcp --dport 80 -j DNAT --to 10.0.90.2:80
# Los accesos de una IP determinada a HTTPS se redirigen a esa máquina también
iptables -t nat -A PREROUTING -i enp0s3 -p tcp --dport 443 -j DNAT --to 10.0.90.2:443
# El localhost se deja (por ejemplo conexiones locales a mysql)
iptables -A INPUT -i lo -j ACCEPT
# Al firewall tenemos acceso desde la red local
iptables -A INPUT -s 10.0.80.0/24 -i enp0s8 -j ACCEPT
# Ahora hacemos enmascaramiento de la red local y de la DMZ
iptables -t nat -A POSTROUTING -s 10.0.80.0/24 -o enp0s3 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 10.0.90.0/24 -o enp0s3 -j MASQUERADE
# Activamos el BIT DE FORWARDING (imprescindible)
echo 1 > /proc/sys/net/ipv4/ip_forward
## Permitimos el paso de la DMZ a una BBDD de la LAN:
iptables -A FORWARD -s 10.0.90.2 -d 10.0.80.5 -p tcp --dport 3306 -j ACCEPT
iptables -A FORWARD -s 10.0.80.5 -d 10.0.90.2 -p tcp --sport 3306 -j ACCEPT
## Permitimos abrir el Terminal Server de la DMZ desde la LAN
iptables -A FORWARD -s 10.0.80.0/24 -d 10.0.90.2 -p tcp --sport 1024:65535 --dport 3389 -j ACCEPT
iptables -A FORWARD -s 10.0.90.2 -d 10.0.80.0/24 -p tcp --sport 3389 --dport 1024:65535 -j ACCEPT
# Cerramos el acceso de la DMZ a la LAN
iptables -A FORWARD -s 10.0.90.0/24 -d 10.0.80.0/24 -j DROP
## Cerramos el acceso de la DMZ al propio firewall
iptables -A INPUT -s 10.0.90.0/24 -i enp0s9 -j DROP
## Y ahora cerramos los accesos indeseados del exterior:
iptables -A INPUT -s 0.0.0.0/0 -p tcp --dport 1:1024 -j DROP
iptables -A INPUT -s 0.0.0.0/0 -p udp --dport 1:1024 -j DROP
# Cerramos un puerto de gestión: webmin
iptables -A INPUT -s 0.0.0.0/0 -p tcp --dport 10000 -j DROP
echo "OK. Verifique que lo que se aplica con: iptables -L -n"
Con esto nos aseguramos de tener una DMZ aislada de la LAN y con las reglas correctas.
Hay que tener algo en cuenta, si el server de la DMZ tienen una ip pública hay que tener muchísimo cuidado de no permitir el FORWARD por defecto. Si en la DMZ hay ip pública NO ES NECESARIO HACER REDIRECCIONES de puerto, sino que basta con rutar los paquetes para llegar hasta la DMZ.
Este tipo de necesidades surgen cuando por ejemplo tenemos dos máquinas con servidor web (un apache y un IIS); ¿A cuál de las dos le redirigimos el puerto 80? No hay manera de saberlo (No, con servidores virtuales tampoco, piénsalo), por eso se deben asignar IPs públicas o en su defecto usar puertos distintos.
Por tanto hay que proteger convenientemente toda la DMZ. Tampoco haría falta enmascarar la salida hacia el exterior de la DMZ, si tiene una ip pública ya tiene una pata puesta en internet; obviamente hay que decirle al router como llegar hasta esa ip pública.
Firewall de LAN con DMZ con política de denegación por defecto
(imagen esquema)
Nos puede resultar interesante y útil ver y montar un esquema por defecto de denegación de paquetes pero, ¿Qué supone el hecho de establecer como política por defecto la denegación?
Se debe explicitar cada conexión permitida en los dos sentidos.
Se debe conocer perfectamente qué debe estar abierto y qué no.
Es muchos más difícil de mantener y si se hace conviene hacerlo desde el principio.
No todo es más trabajo: también supone un firewall mucho más seguro.
En el ejemplo de la DMZ ya se presentaba esta situación en las reglas forward de una a otra red. Para ilustrar el DROP por defecto, vamos a mostrar la configuración del ejemplo anterior de firewall entre redes pero con política por defecto DROP.
(pagina 22)
Otros ejemplos prácticos
Te dejo a continuación más ejemplos para ir practicando:
Ejemplo 1: Permitir conexiones SSH (puerto 22)
Permite el tráfico entrante a través del puerto 22, esencial para administrar el servidor de forma remota:
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Ejemplo 2: Bloquear todo el tráfico entrante y permitir solo conexiones establecidas y SSH
Este conjunto de reglas configura una política de “default deny” (rechazo por defecto) para el tráfico entrante, permitiendo únicamente conexiones ya establecidas y el acceso SSH:
# Permitir tráfico relacionado con conexiones ya establecidas o relacionadas
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Permitir conexiones SSH
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Bloquear el resto del tráfico entrante
sudo iptables -P INPUT DROP
Ejemplo 3: Redirigir el tráfico del puerto 80 al puerto 8080 (NAT)
Si tienes un servicio corriendo en el puerto 8080 y deseas que las conexiones al puerto 80 se redirijan automáticamente:
El objetivo es evitar que el ping funcione en el PC desde el que estamos. Para lograr esto en el nivel de protocolo, dejaremos caer todos los paquetes ICMP dentro y fuera de este PC. El diseño es:
Supongamos que la directiva predeterminada es ACCEPT
Supongamos que la tabla de filtros está vacía → Anexar (Append -A) una nueva regla
Paquetes recibidos → INPUT chain
Paquetes enviados → OUTPUT chain
El protocolo es ICMP
El objetivo (acción) es DROP
La implementación con iptables se logra con:
sudo iptables -A INPUT -p icmp -j DROP
iptables -A OUTPUT -p icmp -j DROP
La forma de leer el primer comando de iptables es: "Append una regla a la cadena INPUT. La regla coincide con los paquetes que utilizan el ICMP. Cuando un paquete coincide, entonces jump a la acción DROP".
Ejemplo 5: Eliminar una regla específica
Si has agregado una regla que ya no deseas, primero lista las reglas con número y luego elimina la deseada:
sudo iptables -L INPUT --line-numbers
# Supongamos que la regla a eliminar está en la línea 5:
sudo iptables -D INPUT 5
Consideraciones Adicionales
Persistencia de las Reglas:
Las reglas configuradas con iptables se pierden al reiniciar el sistema. Para mantenerlas, instala y configura iptables-persistent:
sudo apt-get install iptables-persistent
Durante la instalación, se te pedirá guardar las reglas actuales. Alternativamente, puedes guardar las reglas manualmente y restaurarlas en el arranque.
Pruebas y Monitoreo:Siempre es recomendable probar las nuevas reglas en una sesión que no desconecte inmediatamente la conexión remota, para evitar bloquearte. Además, puedes usar la opción LOG para registrar y monitorear tráfico sospechoso:
Muchos de los apuntes han sido sacados directamente de Pello Xabier Altadill Izura (www.pello.info)
POSTROUTING: Después de tomar la decisión de encaminamiento, es lo ultimo que se aplica, por ejemplo es donde se ponen las reglas de .
Esto es por que va a enviar paquetes de ida y la máquina deberá enviar los paquetes de vuelta (OUTPUT) que estos ya no se enviarán, se desecharán (DROP). Al terminar devuelvela a ACCEPT.