🐋
Apuntes Sistemas
  • ⚓Presentación
  • 📊Sistemas y Servidores
    • Personalizar el prompt de Windows
    • Utilidad de manejo de apps para Windows
    • PRACTICA: Arranque dual Windows y Ubuntu
    • 🚧SysLinuxOS: el SO para ASIX
    • Comandos Linux
      • PRACTICA - Ejercicio de práctica comandos
      • 🚧Instalación de paquetes
      • Apuntes Linux: blue/red team
      • Ejemplos de bash
      • Listado de comandos de Linux
    • Comandos Windows
      • 🚧Apuntes Powershell
      • Bucles FOR con batch
      • Scripts de práctica de Windows
    • Prácticas con Windows 10
    • Configuración de netplan
    • Terminal shell
      • SSH
      • 🚧Ghostty
      • 🚧Warp: la terminal inteligente
      • tmux: paneles de terminal
      • Tabby: Mejorar terminal
      • Conexión SSH en red NAT con VirtualBox
      • TheFuck!: Corrección de comandos
      • Wave: Mejorar terminal Linux
      • 🚧Registros de sesiones
    • Instalación manual de Wordpress en CDMON
    • 🏗️Proxmox
    • 🚧TrueNAS
    • Docker
      • Instalación de Docker
      • Dockerfiles
      • Volúmenes de docker
      • Deployment web con Docker con ejemplos
        • 🚧PRACTICA: Node.js con docker
      • Docker Compose
        • Ejemplo 1: Implantación de Wordpress
        • Ejemplo 2: Implementación de servidor con Nginx, Flask y mySQL
        • Ejemplo 3: Implantación de onlyoffice
        • 🚧Ejemplo 4: Passbolt
        • 🚧PRACTICA: Creando una web de emulación de juegos con docker-compose
      • Monitorización con Grafana en Docker
      • Pi-hole con docker
      • Actividad clase: Deployment app
      • Proyectos self-hosted de docker
    • 🚧Ansible
      • Configuración de laboratorio de ansible
    • 🚧Monitorización de servicios y redes
      • Servicios y cronjobs
      • 1Panel
      • 🚧WatchYourLAN
      • 🚧Uptime-kuma
      • 🚧Netdata
      • 🚧Prometheus + Grafana + Loki
    • LDAP
      • 🚧Gestión gráfica de LDAP
      • Carpetas compartidas NFS
      • PRACTICA: Infraestructura LDAP
  • 🗃️Servicios
    • 🚧Servidor hosting público
    • DHCP
      • DHCP con Ubuntu
      • 🦖DHCP & DNS script
      • DHCP con Alpine
        • Alpine - configuración de red
    • DNS
      • 😡Comprobación DNS
      • Script para enumeración DNS
      • DNS con ubuntu server
      • 🏗️DNSmasq
      • 🚧Securizar servidor DNS
    • Web
      • IIS con Windows server
      • Apache
        • Instalación de LAMP en Ubuntu
          • Prueba de servidor LAMP
          • 🚧Configuración de seguridad de Ubuntu
          • Creación de un VirtualHost en LAMP
          • Creación de varios VirtualHosts en LAMP
          • 🚧Instalación por script de LAMP
        • Aplicaciones con LAMP
          • Instalación de WP en entorno LAMP
          • 🚧Instalación de MantisBT en LAMP
            • 👷Guía de MantisBT
          • 🚧Instalación de QDPM con LAMP
      • Nginx
        • Virtualhosts
        • Instalando Wordpress en nginx
      • 👷MEAN stack
      • 👷‍♂️Caddy
      • 🚧Plesk
      • 🚧Ajenti -Web interface
    • 🏗️Proxy
      • Nginx como proxy inverso y balanceador
      • 🚧Zoraxy
    • Mailing
      • 🚧Servidor Mail con cloudfare
      • 🚧Reenvío de correos de root
      • 🚧Roundcube como MUA
      • Comprobación ESMTP
      • 🚧Seguridad en mailing
      • 🚧Mailhog
    • 🏗️File transfer
      • 🚧FTP
      • Git
    • Sistemas de comunicación instantánea
      • Comunicación mediante CLI
      • Ejabberd - XMPP
        • 🚧Ejabberd con docker
      • 🚧Openfire - XMPP
      • 🚧Comunicaciones servidor-móvil
    • 🏗️Multimedia services
      • Stremio
      • Ver anime por CLI
      • Jellyfin
      • 🚧HLS sobre Apache
      • 🚧Servicio autohospedado de videoconferencia
      • 🚧Morphos: Conversor docs
      • 🚧Reproductores de música en CLI
      • 🚧Icecast - música en streaming
      • 🚧RTMP-HLS server
      • 🚧Guacamole
  • 🖱️Hardware
    • 🚧Identificando conectores
    • Curso de electrónica analógica
    • Alcanzar los 3200MHz con la RAM
    • Calculadora de cuellos de botella
    • 🚧PXE: Bootear sistemas en red
    • 🚧PRÁCTICA - Clonación de disco con Clonezilla
    • Logitech iFixit
  • 🕸️Redes
    • Apuntes IPv4 Alina
    • ¿Cómo diferenciar tantos elementos de red?
    • 🚧IPv6
    • PRÁCTICA - Subneteo con IPcalc en Linux
    • PRÁCTICA - Comandos de red en Windows
    • 🚧PRÁCTICA - Comandos de red en Linux
    • Herramientas de red
      • 🚧TCPDump: analizado de paquetes en red
      • PRÁCTICA - Netsh
      • 🚧PRÁCTICA - mtr.ping.pe
      • 🚧Netcat
    • Wireshark
    • VPN y escritorio remoto
      • Comunicación punto a punto con ngrok
      • 🚧VPN
    • Escaneo de red
      • PRÁCTICA - Mapeado de red con Draw.io
      • 🚧PRÁCTICA - Nmap/Zenmap
    • Redes inalámbricas
      • Wi-fi
        • 🚧PRÁCTICA - Configuración de router
        • 🚧PRÁCTICA - Como hacer un Wifi Heatmap
        • 🚧Seguridad de redes inalámbricas
        • PRÁCTICA - Crackear la contraseña del Wifi con WPA/WPA2
    • PRÁCTICA - Usar SSH en Cisco packet tracer
  • 🛑Ciberseguridad
    • 🚧Securizando un servidor Linux
      • Protégete de ataques de fuerza bruta con Fail2ban
      • Firewall
        • UFW (uncomplicated firewall)
          • GUFW - Interfaz gráfica de ufw
        • 🚧IPTables
        • 🚧PFsense
          • 🚧DMZ con PFsense
      • 🚧Passbolt: gestor de contraseñas autohospedado
      • 🚧Hashes y encriptación
      • 🚧Certificados SSL/TLS
      • Copias de seguridad
    • 🚧Alerta de escaneo de puertos
    • 🚧Google dorks
    • 🚧Enumeración DNS
    • Comandos destructivos de linux
    • Webs enseñanza cyber
    • Wireless Pentesting CheatSheet Github
    • The password game!
    • Personal Security Checklist
  • 🔌Arduino
    • Termómetro e higrómetros digitales y online con Arduino
    • Construyendo un coche multipropósito
      • Multi
      • Montaje del auto
    • Arduino con Sigfox para IoT
    • 10 proyectos de Arduino
  • 📚Recursos y libros
    • Media library: libros varios
    • Herramientas básicas de sysadmin
  • 🌍Sostenibilidad y digitalización
    • Portfolio curso digitalización MOOC
    • 🚧Explotación de recursos por IA
    • 🚧Nuevas tecnologias y comunicaciones
    • 🚧Enlaces sobre Inteligencia artificial
Con tecnología de GitBook
En esta página
  • Tablas y cadenas (chains)
  • Comandos Básicos de iptables
  • Depuración de reglas
  • Escenario de configuración
  • PRÁCTICA: protegiendo la máquina con un script
  • Firewall de una LAN con salida a internet
  • Firewall de una LAN con salida a internet con DMZ
  • Firewall de LAN con DMZ con política de denegación por defecto
  • Otros ejemplos prácticos
  • Consideraciones Adicionales
  • Resumen
  1. Ciberseguridad
  2. Securizando un servidor Linux
  3. Firewall

IPTables

AnteriorGUFW - Interfaz gráfica de ufwSiguientePFsense

Última actualización hace 1 mes

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:

  1. Reglas por tráfico

  2. Las reglas se agrupan en cadenas

  3. 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:

iptables -A INPUT -p icmp -s 10.0.80.0/24 -i enp0s8 -j ACCEPT

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
  • Para aceptar tráfico mysql en la cadena INPUT:

sudo iptables -A INPUT -s 10.0.0.100 -p tcp --dport 3306 -j ACCEPT

Cuando hablamos de políticas DROP, debemos tener en cuenta:

  • Que cada regla INPUT le suele corresponder una regla OUTPUT, por pares (Para cortafuegos personales).

  • Que cuando las reglas son FORWARD también deben ser dobles (Para cortafuegos perimetrales):

iptables -I FORWARD -p tcp --dport 8080 -s 0.0.0.0/0 -d 192.168.0.10/32 -i eth0 -o eth1 -j DROP
iptables -I FORWARD -p tcp --sport 8080 -d 0.0.0.0/0 -s 192.168.0.10/32 -o eth0 -i eth1 -j DROP

Ejemplo de cortafuegos personal

La configuración básica es la siguiente.

Empezamos borrando las reglas:

iptables -F 
iptables -t nat -F

Establecemos todo trafico de entrada o salida:

iptables -P OUTPUT DROP
iptables -P INPUT DROP

Permitimos que si se haga ping:

iptables -A OUTPUT -o enp0s3 -p icmp -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 -A OUTPUT -o enp0s3 -d IPDNS -p udp --dport 53 -j ACCEPT
iptables -A INPUT -i enp0s3 -s IPDNS -p udp --sport 53 -j ACCEPT

Puedo ahora comprobarlo con un dig o nslookup con la IP que hayamos puesto, pero la web no funcionará obviamente, vamos a añadirlo:

iptables -A OUTPUT -o enp0s3 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -i enp0s3 -p tcp --sport 80 -j ACCEPT

Lo mismo para el tráfico seguro:

iptables -A OUTPUT -o enp0s3 -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -i enp0s3 -p tcp --sport 443 -j ACCEPT

Si ahora vamos al navegador a revisar una pagina web cualquier y listamos las reglas veremos que ya se cargan los paquetes.

En función del protocolo o puerto deberemos ir pensando en ir añadiendo reglas dobles.

Siguiendo con mas comandos:

  • Insertar una regla en una posición específica:

    sudo iptables -I [CHAIN] [NÚMERO] [CONDICIONES...] -j [TARGET]

    Esto es útil para que una regla se procese antes que otras, recuerda que el orden es importante.

  • Eliminar una regla: Puedes eliminar una regla especificándola exactamente o mediante su número:

    sudo iptables -D [CHAIN] [CONDICIONES] -j [TARGET]

    O bien, listar las reglas con numeración y eliminarlas por posición:

    sudo iptables -L --line-numbers
    sudo iptables -D INPUT 3

  • Comprobar la existencia de una regla:

    sudo iptables -C [CHAIN] [CONDICIONES...] -j [TARGET]

    Esto nos permite comprobar la existencia de una regla así.

  • Limpiar reglas: Podemos limpiar directamente todas las reglas con:

    sudo iptables -F [CADENA]

    O también nos puede interesar poner los contadores de paquetes a 0:

    sudo iptables -Z [CADENA]
    sudo iptables -Z INPUT
    sudo iptables -Z 

  • Guardar y restaurar reglas:

    • Para guardar las reglas en un archivo:

      sudo iptables-save > /etc/iptables/rules.v4
    • Para restaurar:

      sudo iptables-restore < /etc/iptables/rules.v4
    • Para empezar de cero, ejecuta este script:

      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):

  1. Uno o dos en "Red Interna" para conectarse con la LAN interna (donde se ubica el servidor interno) y posteriormente la DMZ.

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

    1. Aunque también se podría conectar en modo adaptador puente si te es más fácil.

El escenario será el siguiente finalmente:

Esquema de netplan:
network:
  version: 2
  renderer: networkd
  ethernets:
    enp0s3:
      dhcp4: true

    enp0s8:
      dhcp4: false
      addresses:
        - 10.0.80.1/24

    enp0s9:
      dhcp4: false
      addresses:
        - 10.0.90.1/24

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:

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

Ejemplo 4: Limitar conexiones ICMP (ping)

Para evitar ataques de ping o reducir la carga, puedes limitar la cantidad de paquetes ICMP:

sudo iptables -A INPUT -p icmp -m limit --limit 1/s -j ACCEPT

Ejemplo 5: Evitar que el ping funcione

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:

    sudo iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH attempt: "

Resumen

Referencias:

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

proyecto netfilter
nftables
bpfilter
https://rlworkman.net/howtos/iptables/chunkyhtml/c962.html
NAT
icmp
https://sandilands.info/nsl/Firewallswithiptables.html#x19-25000013.1.1
🛑
🚧
🚧
Page cover image
Diagrama de las tablas filter y nat con sus cadenas. Falta el input de nat (naranja) que va junto antes del input de filter (rojo).
Paquetes contabilizados
Sigue contabilizándolos por que llegan pero se desechan.
Esquema de red
Esquema de red del ejemplo
Configuración de red con DMZ