🔎 Buscar

🔥 Firewalls de verdad

Qué es un firewall, iptables y nftables con reglas reales, UFW y firewalld, apertura de puertos para un servidor web, rate limiting, fail2ban y persistencia.

Wiki / Apuntes📖 Contenido

Firewalls de verdad

Un firewall es la frontera de red de tu servidor: decide qué tráfico entra, sale y se reenvía. Es tu primera línea de defensa y, mal configurado, es también la forma más rápida de encerrarte fuera de tu propio servidor. Esta guía cubre de lo más bajo (iptables/nftables) a lo más cómodo (UFW, firewalld), con ejemplos que puedes ejecutar hoy.

¿Qué es un firewall?

Filtra paquetes según sus atributos: IP origen/destino, puerto, protocolo (TCP/UDP), interfaz y estado de la conexión. Cada paquete pasa por un conjunto de reglas; la primera que coincida decide (ACEPTAR, RECHAZAR o IGNORAR).

💡 ACCEPT permite, DROP ignora el paquete en silencio (el cliente espera hasta el timeout), REJECT lo rechaza con un error (el cliente se entera al instante). Para servicios expuestos suele preferirse DROP; para puertos cerrados, REJECT.

iptables

iptables organiza las reglas en tablas (filtro, nat, mangle…) y dentro de cada tabla en cadenas. La tabla más usada es filter, con tres cadenas por defecto:

Cadena Filtra tráfico
INPUT Que entra al servidor
OUTPUT Que sale del servidor
FORWARD Que se reenvía a través del servidor (router)

Estructura de una regla

iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT
#         ^cadena  ^proto  ^puerto destino  ^origen     ^acción
  • -A añade al final, -I inserta al principio, -D borra.
  • -p protocolo, --dport puerto destino, -s/-d origen/destino, -i interfaz.
  • -j la acción (ACCEPT/DROP/REJECT).

Reglas para un servidor web

Solo abrimos SSH, HTTP y HTTPS; el resto se bloquea:

# 1. Permite tráfico ya establecido (respuestas de conexiones iniciadas)
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# 2. Permite loopback (lo) — siempre
iptables -A INPUT -i lo -j ACCEPT

# 3. Abre puertos de servicio
iptables -A INPUT -p tcp --dport 22  -j ACCEPT   # SSH
iptables -A INPUT -p tcp --dport 80  -j ACCEPT   # HTTP
iptables -A INPUT -p tcp --dport 443 -j ACCEPT   # HTTPS

# 4. Default policy: DROP todo lo demás que entra
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

⚠️ Orden importa: iptables evalúa en orden y aplica la primera coincidencia. Pon las excepciones (accept) antes de la política por defecto. Y nunca apliques una política DROP en INPUT sin haber abierto antes el puerto 22, o te quedarás sin SSH.

Ver y limpiar

iptables -L -n -v        # lista reglas (sin resolver nombres)
iptables -L INPUT --line-numbers   # con números de línea
iptables -D INPUT 3      # borra la regla 3
iptables -F              # vacía todas las reglas (¡cuidado!)

nftables: el sucesor

nftables (paquete nft) es el reemplazo moderno: sintaxis más limpia, una sola herramienta, y soporta tablas y cadenas sin la duplicación de iptables. Es el backend por defecto en distribuciones nuevas.

# Tabla y cadena base
nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }

# Reglas (mismo servidor web: 22, 80, 443)
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input iif lo accept
nft add rule inet filter input tcp dport { 22, 80, 443 } accept

# Ver
nft list ruleset

💡 iptables en kernels modernos es una capa de compatibilidad sobre nftables. Si empiezas un proyecto nuevo, escribe reglas en nft; si administras servidores viejos, iptables sigue perfectamente válido.

UFW: el firewall fácil

Uncomplicated Firewall es el frontend amigable sobre iptables/nftables de Ubuntu/Debian. Ideal para el día a día:

ufw default deny incoming      # bloquea todo lo que entra por defecto
ufw default allow outgoing     # permite todo lo que sale

ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow from 10.0.0.5 to any port 3306    # MySQL solo para una IP
ufw limit ssh                   # rate-limit SSH (anti fuerza bruta)

ufw enable                      # ACTIVA el firewall
ufw status verbose              # estado y reglas
ufw status numbered
ufw delete 3                    # borra la regla 3

⚠️ ufw enable activa el firewall de inmediato. Verifica que el puerto 22 (SSH) está permitido antes de habilitarlo, y hazlo desde una sesión donde no pierdas el acceso.

firewalld: zonas

firewalld (Fedora/RHEL/CentOS) organiza las reglas por zonas (niveles de confianza de la red). Un servidor web suele usar public, un servidor interno internal:

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --permanent --zone=public --add-port=22/tcp

firewall-cmd --reload               # aplica cambios (necesario tras --permanent)
firewall-cmd --list-all --zone=public
firewall-cmd --get-default-zone
Zona Confianza Uso típico
public Baja servidor expuesto a internet
internal Media red interna corporativa
trusted Alta red privada de confianza
drop Nula descarta todo

Rate limiting (anti fuerza bruta)

Limitar peticiones por IP evita que un atacante pruebe contraseñas miles de veces por segundo:

# iptables: máx. 5 conexiones SSH por minuto por IP
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
         -m recent --set --name ssh
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
         -m recent --update --seconds 60 --hitcount 5 --rttl \
         --name ssh -j REJECT

# UFW: igual pero en un comando
ufw limit ssh

fail2ban

fail2ban vigila los logs y banea IPs automáticamente tras demasiados intentos fallidos. Configuración real para SSH:

# /etc/fail2ban/jail.local
[DEFAULT]
bantime  = 10m            # duración del ban
findtime = 10m            # ventana de tiempo
maxretry = 5              # intentos fallidos antes de ban

[sshd]
enabled  = true
port     = ssh
logpath  = /var/log/auth.log    # Debian/Ubuntu
# logpath = /var/log/secure     # en RHEL/CentOS
systemctl enable --now fail2ban
fail2ban-client status sshd            # IPs baneadas
fail2ban-client set sshd unbanip 1.2.3.4   # desbanea manual

💡 fail2ban no sustituye a la política de acceso: sigue usando llaves SSH en vez de contraseñas y PasswordAuthentication no en sshd_config. fail2ban es una capa más, no la única.

Hacer la configuración persistente

Todo lo que configuras con iptables/nft se pierde al reiniciar si no lo guardas:

# iptables-persistent (Debian/Ubuntu)
apt install iptables-persistent
netfilter-persistent save
netfilter-persistent reload

# nftables
nft list ruleset > /etc/nftables.conf
systemctl enable nftables

# UFW y firewalld ya son persistentes por sí mismos (systemd)
systemctl enable ufw
systemctl enable firewalld

Cheatsheet

Necesito… Comando
Bloquear todo lo entrante por defecto ufw default deny incoming
Abrir un puerto ufw allow 80/tcp / firewall-cmd --add-port=80/tcp
Listar reglas iptables iptables -L -n -v
Rate limit SSH ufw limit ssh
Ban automático fail2ban (maxretry + bantime)
Guardar iptables netfilter-persistent save
Guardar nft nft list ruleset > /etc/nftables.conf

Para profundizar

Estudio · Recursos de todo el mundo (inglés, chino, japonés, español, francés, ruso…) curados y traducidos al español.