Volver al índice
root@vps-donweb:~/docs/firewall$

Firewall / UFW

herramienta UFW + iptables
SO Ubuntu 22.04 LTS
categoría Seguridad
¿QUÉ ES? UFW e iptables

iptables es el sistema de filtrado de paquetes del kernel Linux — potente pero con una sintaxis compleja. UFW (Uncomplicated Firewall) es una interfaz simplificada sobre iptables diseñada para ser usable por humanos. En Ubuntu, UFW es la herramienta recomendada para gestión diaria; iptables queda para casos avanzados.

# UFW actúa sobre iptables por debajo
# Lo que escribís en UFW se traduce a reglas iptables

# Ver las reglas iptables que UFW genera
iptables -L -n --line-numbers
iptables -L INPUT -n -v

UFW y iptables no son excluyentes — UFW gestiona las reglas principales y podés agregar reglas iptables manuales para casos que UFW no cubre.

POLÍTICA Cómo funcionan las reglas

UFW evalúa las reglas en orden, de arriba hacia abajo. La primera regla que coincide con el paquete gana. Al final se aplica la política por defecto.

Paquete entrante
      ↓
  Regla 1: ¿coincide? → ALLOW / DENY / REJECT / LIMIT
      ↓ (no coincide)
  Regla 2: ¿coincide? → ...
      ↓ (no coincide)
  Política por defecto (DEFAULT) → ALLOW / DENY

La política más segura para un servidor público:

# Denegar todo el tráfico entrante por defecto
ufw default deny incoming

# Permitir todo el tráfico saliente
ufw default allow outgoing

# Luego agregar reglas específicas de lo que SÍ se permite

Nunca activar UFW sin haber permitido el puerto SSH primero. De lo contrario te quedás sin acceso al servidor.

PUERTOS Referencia de puertos comunes
PuertoProtocoloServicio
22TCPSSH — acceso remoto al servidor
80TCPHTTP — sitios web sin cifrar
443TCPHTTPS — sitios web cifrados
3306TCPMySQL / MariaDB — base de datos
5432TCPPostgreSQL — base de datos
6379TCPRedis — caché en memoria
25 / 587 / 465TCPSMTP — envío de emails
143 / 993TCPIMAP — recepción de emails
53TCP/UDPDNS — resolución de nombres
21TCPFTP — transferencia de archivos (evitar)
8080 / 8443TCPHTTP/HTTPS alt — apps y paneles
60000-61000UDPMosh — SSH alternativo móvil

Regla de oro: mantener cerrado todo lo que no se use. MariaDB, Redis y PostgreSQL nunca deben estar abiertos a internet — accedelos vía túnel SSH o solo desde localhost.

SETUP Configuración inicial desde cero

El orden importa. Seguí esta secuencia para no quedar afuera del servidor.

# PASO 1: Verificar estado actual
ufw status verbose

# PASO 2: Establecer políticas por defecto
ufw default deny incoming
ufw default allow outgoing

# PASO 3: Permitir SSH ANTES de activar (crítico)
ufw allow 22/tcp
# Si usás puerto personalizado:
ufw allow 2222/tcp

# PASO 4: Agregar los demás servicios necesarios
ufw allow 80/tcp
ufw allow 443/tcp

# PASO 5: Activar UFW
ufw enable

# PASO 6: Verificar reglas activas
ufw status numbered

Si el proveedor (Donweb) tiene un firewall propio en el panel de control, coordiná las reglas — UFW actúa a nivel del OS, el firewall del panel actúa antes de llegar al servidor.

ESTADO Ver y gestionar UFW
# Estado resumido
ufw status

# Estado completo con políticas por defecto
ufw status verbose

# Ver reglas numeradas (para borrar por número)
ufw status numbered

# Habilitar / deshabilitar UFW
ufw enable
ufw disable

# Recargar reglas
ufw reload

# Resetear todo (borra TODAS las reglas)
ufw reset

ufw reset elimina todas las reglas y deshabilita UFW. El servidor queda sin firewall hasta que lo reconfigures.

ALLOW Permitir tráfico
# Por número de puerto
ufw allow 80              # TCP y UDP
ufw allow 80/tcp          # solo TCP
ufw allow 443/tcp

# Por nombre de servicio (de /etc/services)
ufw allow ssh
ufw allow http
ufw allow https

# Rango de puertos
ufw allow 8000:8100/tcp

# Desde una IP específica
ufw allow from 190.55.100.200
ufw allow from 190.55.100.200 to any port 22

# Desde una red (subred)
ufw allow from 192.168.1.0/24
ufw allow from 192.168.1.0/24 to any port 3306

# Hacia una interfaz específica
ufw allow in on eth0 to any port 80
DENY / REJECT Bloquear tráfico

deny descarta el paquete silenciosamente. reject descarta el paquete y notifica al emisor. Para seguridad, deny es mejor — no revela que el puerto existe.

# Denegar un puerto
ufw deny 3306
ufw deny 6379/tcp

# Denegar desde una IP (bloquear atacante)
ufw deny from 1.2.3.4
ufw deny from 1.2.3.4 to any

# Denegar una red completa
ufw deny from 10.0.0.0/8

# Reject (manda RST/ICMP al emisor)
ufw reject 23/tcp   # bloquear Telnet con aviso
ELIMINAR Borrar reglas
# Ver reglas numeradas
ufw status numbered
# Output ejemplo:
#      To                         Action      From
# [ 1] 22/tcp                     ALLOW IN    Anywhere
# [ 2] 80/tcp                     ALLOW IN    Anywhere
# [ 3] 443/tcp                    ALLOW IN    Anywhere

# Borrar por número
ufw delete 3

# Borrar por regla exacta
ufw delete allow 80/tcp
ufw delete allow from 1.2.3.4

# Borrar regla IPv6 también (si existe)
ufw delete allow 80/tcp
# UFW borra ambas versiones (v4 y v6) automáticamente
LIMIT Rate limiting integrado en UFW

limit bloquea automáticamente IPs que hacen más de 6 intentos de conexión en 30 segundos. Ideal para SSH sin Fail2ban.

# Limitar intentos de conexión al puerto SSH
ufw limit ssh
ufw limit 22/tcp
ufw limit 2222/tcp

# Ver la regla generada
ufw status verbose
# → 2222/tcp                  LIMIT IN    Anywhere

Para SSH es recomendable usar limit en vez de allow aunque tengas Fail2ban — son capas de protección complementarias.

INSERTAR Prioridad de reglas

UFW evalúa reglas en orden. Para que una regla específica tenga prioridad sobre una general, hay que insertarla antes.

# Ver reglas numeradas actuales
ufw status numbered

# Insertar regla en posición específica
# Ejemplo: bloquear una IP antes de la regla general que permite todo
ufw insert 1 deny from 5.6.7.8

# Resultado: la regla de deny queda primera
# → [1] DENY    5.6.7.8
# → [2] ALLOW   22/tcp
# → [3] ALLOW   80/tcp

Las reglas de deny de IPs específicas siempre deben ir antes que las reglas de allow generales, o serán ignoradas.

IPv6 Configuración dual stack
# Verificar que IPv6 está habilitado en UFW
grep IPV6 /etc/default/ufw
# → IPV6=yes  (debe estar en yes)

# Si está en no, editarlo
nano /etc/default/ufw
# IPV6=yes

ufw disable && ufw enable

# Las reglas con IPv6 activo se aplican a v4 y v6:
# [ 1] 22/tcp     ALLOW IN    Anywhere
# [ 2] 22/tcp (v6) ALLOW IN   Anywhere (v6)

Con IPv6 habilitado, cada regla que agregás aplica a ambas versiones automáticamente — no hay que duplicar reglas.

BEFORE.RULES Reglas que se cargan antes que UFW

Para casos que UFW no cubre directamente, se pueden agregar reglas iptables raw en /etc/ufw/before.rules. Se cargan antes que todas las reglas de UFW.

# /etc/ufw/before.rules
# Agregar ANTES de la línea: *filter

# Ejemplo: permitir ICMP (ping) — útil para diagnóstico
*filter
-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT

# Ejemplo: nat para reenviar puertos (port forwarding)
# Agregar al inicio del archivo, antes de *filter:
*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
COMMIT
# Recargar después de editar before.rules
ufw reload
PERFILES Ver y usar perfiles de aplicación

Las aplicaciones pueden registrar perfiles UFW que definen sus puertos. Así en vez de recordar números de puerto usás nombres.

# Ver perfiles disponibles
ufw app list
# → Available applications:
#      Nginx Full
#      Nginx HTTP
#      Nginx HTTPS
#      OpenSSH

# Ver detalles de un perfil
ufw app info "Nginx Full"
# → Profile: Nginx Full
#   Title: Web Server (Nginx, HTTP + HTTPS)
#   Description: ...
#   Ports: 80,443/tcp

# Usar perfil en regla
ufw allow "Nginx Full"
ufw allow "Nginx HTTP"
ufw allow "Nginx HTTPS"
ufw allow "OpenSSH"
ufw delete allow "Nginx HTTP"   # una vez que tenés SSL

Una vez configurado SSL, reemplazá Nginx Full por Nginx HTTPS y bloqueá el 80 (o dejá solo el redirect que maneja Nginx internamente).

CREAR Perfil personalizado

Cualquier app puede tener su perfil. Crear el archivo en /etc/ufw/applications.d/

# /etc/ufw/applications.d/mi-app
[MiApp]
title=Mi Aplicación Web
description=API y panel de administración
ports=3000,3001/tcp

[MiApp-Admin]
title=Mi App — Panel Admin
description=Solo panel admin
ports=9000/tcp
# Actualizar la lista de perfiles
ufw app update MiApp
ufw app list

# Usar el nuevo perfil
ufw allow "MiApp"
IPTABLES Conceptos y estructura

iptables organiza las reglas en tablas y cadenas. Para un VPS web el foco está en la tabla filter.

Tablas principales:
  filter   → filtrado de paquetes (INPUT, OUTPUT, FORWARD)
  nat      → traducción de direcciones (PREROUTING, POSTROUTING)
  mangle   → modificar paquetes

Cadenas de filter:
  INPUT    → paquetes que llegan al servidor
  OUTPUT   → paquetes que salen del servidor
  FORWARD  → paquetes que pasan por el servidor (router)

Acciones (targets):
  ACCEPT   → permitir el paquete
  DROP     → descartar silenciosamente
  REJECT   → descartar y notificar
  LOG      → registrar en syslog y continuar
  RETURN   → volver a la cadena anterior
LISTAR Ver reglas iptables activas
# Ver todas las reglas (tabla filter)
iptables -L -n -v

# Ver con números de línea
iptables -L INPUT -n -v --line-numbers

# Ver tabla NAT
iptables -t nat -L -n -v

# Formato más compacto (igual que las reglas se escriben)
iptables -S
iptables -S INPUT

# IPv6
ip6tables -L -n -v
REGLAS Agregar y eliminar reglas iptables
# Sintaxis básica
# iptables -A CADENA -p PROTOCOLO --dport PUERTO -j ACCIÓN

# Permitir SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Permitir HTTP y HTTPS
iptables -A INPUT -p tcp --dport 80  -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Permitir conexiones establecidas (tráfico de respuesta)
iptables -A INPUT -m state \
  --state ESTABLISHED,RELATED -j ACCEPT

# Permitir loopback (localhost)
iptables -A INPUT -i lo -j ACCEPT

# Bloquear IP específica
iptables -A INPUT -s 1.2.3.4 -j DROP

# Bloquear rango de IPs
iptables -A INPUT -s 1.2.3.0/24 -j DROP

# Eliminar regla por número de línea
iptables -D INPUT 3

# Insertar regla en posición específica
iptables -I INPUT 1 -s 1.2.3.4 -j DROP

# Política por defecto (DROP todo lo que no coincida)
iptables -P INPUT DROP
PERSISTENCIA Guardar reglas iptables

Las reglas iptables se pierden al reiniciar. Hay que persistirlas.

# Instalar el paquete de persistencia
apt install iptables-persistent

# Guardar reglas actuales
netfilter-persistent save
# Guarda en:
# /etc/iptables/rules.v4 (IPv4)
# /etc/iptables/rules.v6 (IPv6)

# Recargar reglas guardadas
netfilter-persistent reload

# Guardar manualmente
iptables-save  > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6

# Restaurar manualmente
iptables-restore  < /etc/iptables/rules.v4

Si usás UFW, él se encarga de persistir sus reglas. Solo necesitás iptables-persistent para reglas manuales que agregues fuera de UFW.

LOGGING Activar y configurar logs de UFW
# Activar logging (niveles: off, low, medium, high, full)
ufw logging on        # nivel low por defecto
ufw logging medium    # recomendado para producción
ufw logging high      # muy verboso, para debugging
ufw logging off       # deshabilitar

# Los logs van a syslog y al archivo:
tail -f /var/log/ufw.log

# Ver logs en tiempo real con journald
journalctl -f | grep UFW

# Filtrar solo los bloqueados
grep "UFW BLOCK" /var/log/ufw.log | tail -20

# Filtrar solo los permitidos
grep "UFW ALLOW" /var/log/ufw.log | tail -20
ANÁLISIS Leer e interpretar los logs

Un registro típico en /var/log/ufw.log:

May 28 14:23:11 vps kernel: [UFW BLOCK] IN=eth0 OUT=
MAC=... SRC=185.234.218.44 DST=192.168.1.10
PROTO=TCP SPT=54321 DPT=3306 ...

Campos importantes:
  UFW BLOCK / UFW ALLOW → acción tomada
  SRC=185.234.218.44    → IP origen (atacante)
  DST=192.168.1.10      → IP destino (tu servidor)
  DPT=3306              → puerto destino atacado
  PROTO=TCP             → protocolo
# IPs que más intentan conectar a puertos bloqueados
grep "UFW BLOCK" /var/log/ufw.log \
  | awk '{print $13}' \
  | cut -d= -f2 \
  | sort | uniq -c | sort -rn | head -15

# Puertos más atacados
grep "UFW BLOCK" /var/log/ufw.log \
  | grep -oP 'DPT=\K[0-9]+' \
  | sort | uniq -c | sort -rn | head -10

# Bloquear manualmente una IP muy activa
ufw insert 1 deny from 185.234.218.44
MONITOREO Ver conexiones activas en tiempo real
# Ver todas las conexiones activas
ss -tulnp
ss -tnp state established

# Ver conexiones agrupadas por estado
ss -s

# Ver quién está conectado al puerto 80/443
ss -tnp sport = :80
ss -tnp sport = :443

# Contar conexiones por IP (detectar DDoS básico)
ss -tn state established | awk '{print $5}' \
  | cut -d: -f1 | sort | uniq -c | sort -rn | head -10

# Alternativa con netstat
netstat -ntu | awk '{print $5}' \
  | cut -d: -f1 | sort | uniq -c | sort -rn
RECETA Configuración completa para VPS web típico

Configuración lista para un VPS que sirve sitios web con Nginx, SSH en puerto personalizado, y bases de datos solo en localhost.

# 1. Políticas por defecto
ufw default deny incoming
ufw default allow outgoing

# 2. SSH con rate limiting (puerto personalizado)
ufw limit 2222/tcp

# 3. Web
ufw allow 80/tcp
ufw allow 443/tcp

# 4. Activar
ufw enable
ufw status numbered

# Resultado esperado:
#      To             Action      From
# [ 1] 2222/tcp       LIMIT IN    Anywhere
# [ 2] 80/tcp         ALLOW IN    Anywhere
# [ 3] 443/tcp        ALLOW IN    Anywhere

MariaDB, Redis y cualquier base de datos se dejan SIN regla en UFW — solo escuchan en 127.0.0.1 en su configuración propia. Acceso solo vía túnel SSH.

RECETA Acceso a MariaDB solo desde tu IP

Si necesitás conectarte a la base de datos directamente sin túnel SSH (no recomendado, pero a veces necesario), restringilo a tu IP fija.

# Permitir MariaDB solo desde tu IP fija
ufw allow from TU_IP_FIJA to any port 3306

# Denegar cualquier otra conexión al 3306
ufw deny 3306

# También asegurate de que MariaDB escucha en 0.0.0.0
# /etc/mysql/mariadb.conf.d/50-server.cnf
# bind-address = 0.0.0.0  ← solo si necesitás acceso externo

# Verificar
ufw status numbered

La opción más segura sigue siendo el túnel SSH (ssh -L 3307:127.0.0.1:3306 donweb). Abrir el 3306 al exterior, aunque sea a una sola IP, aumenta la superficie de ataque.

RECETA Bloquear país o rango de IPs

Si los logs muestran ataques constantes desde un rango de IPs o región específica.

# Bloquear un rango de IPs conocido
ufw insert 1 deny from 185.234.0.0/16

# Bloquear múltiples rangos
ufw insert 1 deny from 45.155.204.0/24
ufw insert 1 deny from 193.32.162.0/24

# Para bloqueo por país, usar ipset (más eficiente)
apt install ipset

# Crear set de IPs
ipset create blocklist hash:net
ipset add blocklist 185.234.0.0/16
ipset add blocklist 1.2.0.0/16

# Bloquear el set con iptables
iptables -I INPUT 1 -m set --match-set blocklist src -j DROP

# Ver el set
ipset list blocklist
RECETA Protección básica contra DDoS
# Limitar nuevas conexiones por IP (en before.rules o iptables)

# Máximo 25 nuevas conexiones por IP en 60 segundos
iptables -A INPUT -p tcp --dport 80 \
  -m state --state NEW \
  -m recent --set --name HTTP_LIMIT

iptables -A INPUT -p tcp --dport 80 \
  -m state --state NEW \
  -m recent --update --seconds 60 --hitcount 25 \
  --name HTTP_LIMIT -j DROP

# Bloquear paquetes inválidos
iptables -A INPUT -m state --state INVALID -j DROP

# Proteger contra SYN flood
iptables -A INPUT -p tcp --syn \
  -m limit --limit 1/s --limit-burst 3 -j ACCEPT

# Bloquear pings excesivos
iptables -A INPUT -p icmp --icmp-type echo-request \
  -m limit --limit 1/s -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP

Para DDoS serio, estas reglas no son suficientes — necesitás un servicio como Cloudflare delante del servidor. Estas reglas protegen contra ataques pequeños y escaneos.

RECETA Recuperar acceso si te bloqueaste

Si por error bloqueaste tu propia IP o el puerto SSH, opciones de recuperación:

# OPCIÓN 1: Consola VNC del panel de Donweb
# Accedé al servidor por la consola web del panel
# (no usa SSH, no está afectada por UFW)
# Luego desde ahí:
ufw disable
ufw delete deny from TU_IP
ufw allow 22/tcp
ufw enable

# OPCIÓN 2: Si tenés otra IP (ej: hotspot del celu)
# Conectate desde esa IP diferente y corregí las reglas

# OPCIÓN 3: Si el VPS tiene otra interfaz de red
# ssh -i ~/.ssh/clave usuario@IP_ALTERNATIVA

# Para identificar qué regla te bloqueó
ufw status numbered
iptables -L INPUT -n --line-numbers

La consola VNC del panel de Donweb es tu red de seguridad para situaciones de lockout — siempre sabé cómo acceder a ella antes de hacer cambios de firewall.