Uncomplicated Firewall en Linux
UFW (Uncomplicated Firewall) es la interfaz de gestión de firewall por defecto en Ubuntu, Debian y sus derivados. Es una capa de abstracción sobre iptables que hace que configurar reglas de firewall sea simple y legible. Un servidor Linux sin firewall configurado es un servidor expuesto — UFW es lo primero que se configura al montar cualquier servidor.
ufw enable.UFW vs iptables vs nftables
| Herramienta | Nivel | Curva de aprendizaje | Uso recomendado |
|---|---|---|---|
| UFW | Frontend de alto nivel | Fácil | Servidores Ubuntu/Debian, uso cotidiano |
| iptables | Interfaz del kernel (legacy) | Media-Alta | Configuraciones complejas, scripts legacy |
| nftables | Interfaz del kernel (moderno) | Media-Alta | Reemplaza iptables en sistemas modernos |
| firewalld | Frontend dinámico | Media | Fedora, RHEL, CentOS |
iptables -L. Son completamente compatibles — puedes usar ambos en el mismo sistema, aunque no es recomendable mezclarlos sin cuidado.UFW viene preinstalado en Ubuntu 18.04+. En otras distribuciones Debian-based se instala con apt. El proceso de activación inicial requiere cuidado para no perder el acceso SSH.
# Verificar si está instalado which ufw && ufw --version ufw 0.36.2 # Instalar si no está disponible sudo apt update && sudo apt install ufw -y ## SECUENCIA SEGURA DE ACTIVACIÓN ## (NUNCA hacer ufw enable antes de permitir SSH) # PASO 1: Establecer política por defecto sudo ufw default deny incoming # bloquear todo lo que entra sudo ufw default allow outgoing # permitir todo lo que sale # PASO 2: Permitir SSH ANTES de activar sudo ufw allow ssh # equivale a: ufw allow 22/tcp # PASO 3: Activar UFW sudo ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup # PASO 4: Verificar sudo ufw status Status: active To Action From -- ------ ---- 22/tcp ALLOW Anywhere 22/tcp (v6) ALLOW Anywhere (v6) # Habilitar UFW al inicio del sistema (ya lo hace enable, pero por si acaso) sudo systemctl enable ufw # Desactivar UFW (desactiva también al inicio) sudo ufw disable # Resetear todas las reglas a cero sudo ufw reset
Consultar el estado de UFW y las reglas activas es la operación más frecuente en el trabajo diario. Hay varias formas de verlas con distintos niveles de detalle.
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
3306/tcp ALLOW IN 192.168.1.0/24
23/tcp DENY IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
80/tcp (v6) ALLOW IN Anywhere (v6)
443/tcp (v6) ALLOW IN Anywhere (v6)
# Estado básico sudo ufw status # Estado detallado (políticas por defecto + todas las reglas) sudo ufw status verbose # Reglas numeradas (necesario para borrar por número) sudo ufw status numbered Status: active To Action From -- ------ ---- [ 1] 22/tcp ALLOW IN Anywhere [ 2] 80/tcp ALLOW IN Anywhere [ 3] 443/tcp ALLOW IN Anywhere [ 4] 3306/tcp ALLOW IN 192.168.1.0/24 # Ver las reglas reales en iptables que genera UFW sudo iptables -L -n -v --line-numbers # Ver los archivos de configuración de UFW cat /etc/ufw/ufw.conf # configuración general cat /etc/default/ufw # política por defecto y opciones ls /etc/ufw/ # todos los archivos de configuración
UFW soporta cuatro acciones para cada regla. Entender la diferencia entre ellas es fundamental para diseñar una política de firewall correcta.
La forma más común de usar UFW: abrir o cerrar puertos específicos con distintos niveles de granularidad — puerto único, rango, protocolo TCP/UDP o ambos.
## PUERTO ÚNICO sudo ufw allow 80 # puerto 80 TCP y UDP sudo ufw allow 80/tcp # solo TCP sudo ufw allow 53/udp # solo UDP (DNS) sudo ufw deny 23/tcp # bloquear telnet sudo ufw limit 22/tcp # SSH con rate limiting anti-fuerza bruta ## RANGO DE PUERTOS sudo ufw allow 6000:6007/tcp # puertos 6000 al 6007 TCP sudo ufw allow 9000:9100/udp # rango UDP ## DIRECCIÓN: INCOMING, OUTGOING, ROUTED sudo ufw allow in 80/tcp # tráfico entrante al puerto 80 (por defecto) sudo ufw allow out 53 # tráfico saliente al puerto 53 (DNS) sudo ufw deny out 25/tcp # bloquear SMTP saliente (evitar spam) ## BORRAR REGLAS sudo ufw delete allow 80/tcp # borrar por la regla exacta sudo ufw delete deny 23/tcp # o por número (ver con: ufw status numbered) sudo ufw delete 3 # borrar la regla número 3 ## PUERTOS COMUNES 20,21/tcp → FTP (datos y control) 22/tcp → SSH 25/tcp → SMTP 53/tcp,udp → DNS 80/tcp → HTTP 110/tcp → POP3 143/tcp → IMAP 443/tcp → HTTPS 3306/tcp → MySQL/MariaDB 5432/tcp → PostgreSQL 6379/tcp → Redis 27017/tcp → MongoDB 8080/tcp → HTTP alternativo 8443/tcp → HTTPS alternativo
UFW reconoce nombres de servicios estándar definidos en /etc/services y perfiles de aplicación instalados. Usar nombres es más legible y menos propenso a errores.
## NOMBRES DE SERVICIO ESTÁNDAR (/etc/services) sudo ufw allow ssh # equivale a allow 22/tcp sudo ufw allow http # equivale a allow 80/tcp sudo ufw allow https # equivale a allow 443/tcp sudo ufw allow ftp # equivale a allow 21/tcp sudo ufw allow smtp # equivale a allow 25/tcp sudo ufw allow dns # equivale a allow 53 sudo ufw allow imaps # equivale a allow 993/tcp (IMAP sobre SSL) ## PERFILES DE APLICACIÓN UFW # Ver perfiles disponibles (instalados con paquetes del sistema) sudo ufw app list Available applications: Apache Apache Full Apache Secure Nginx Full Nginx HTTP Nginx HTTPS OpenSSH # Ver detalles de un perfil sudo ufw app info "Nginx Full" Profile: Nginx Full Title: Web Server (Nginx, HTTP + HTTPS) Description: This profile opens both 80 and 443. Ports: 80,443/tcp # Usar un perfil sudo ufw allow "Nginx Full" # abre 80 y 443 a la vez sudo ufw allow "Nginx HTTPS" # solo 443 sudo ufw allow "Apache Full" # Apache 80 y 443 sudo ufw allow "OpenSSH" # SSH # Borrar por perfil sudo ufw delete allow "Nginx Full" # Verificar nombres en /etc/services grep "^http" /etc/services http 80/tcp www www-http https 443/tcp
Restringir el acceso por dirección IP o rango de red es una de las medidas de seguridad más efectivas. Se usa para proteger servicios sensibles (bases de datos, paneles de admin) que solo deben ser accesibles desde IPs conocidas.
## PERMITIR UNA IP ESPECÍFICA sudo ufw allow from 203.0.113.10 # todo el tráfico desde esa IP sudo ufw allow from 203.0.113.10 to any port 22 # esa IP solo al puerto 22 sudo ufw allow from 203.0.113.10 to any port 3306 proto tcp ## PERMITIR UNA SUBRED sudo ufw allow from 192.168.1.0/24 # toda la red local /24 sudo ufw allow from 10.0.0.0/8 # toda la red 10.x.x.x sudo ufw allow from 192.168.1.0/24 to any port 3306 # MySQL solo accesible desde la red local ## BLOQUEAR UNA IP (por ejemplo, atacante activo) sudo ufw deny from 203.0.113.100 # bloquear esa IP completamente sudo ufw deny from 203.0.113.0/24 # bloquear toda esa subred sudo ufw insert 1 deny from 203.0.113.100 # insertar al inicio (mayor prioridad) ## REGLAS CON INTERFAZ ESPECÍFICA sudo ufw allow in on eth0 to any port 80 # HTTP solo por eth0 sudo ufw allow in on lo # todo el tráfico por loopback sudo ufw deny in on eth1 to any port 22 # bloquear SSH en eth1 ## REGLAS CON ORIGEN Y DESTINO # Sintaxis completa: from IP to IP port PUERTO proto PROTO sudo ufw allow from 10.0.0.5 to 10.0.0.1 port 5432 proto tcp # Solo el host 10.0.0.5 puede conectar a PostgreSQL en 10.0.0.1 ## CASO PRÁCTICO: Base de datos solo accesible localmente sudo ufw deny 3306 # bloquear MySQL desde todo sudo ufw allow from 127.0.0.1 to any port 3306 # permitir solo localhost sudo ufw allow from 192.168.1.0/24 to any port 3306 # y red local
El orden de las reglas en UFW importa: se evalúan de arriba hacia abajo y se aplica la primera que coincide. Las reglas numeradas permiten insertar reglas en posiciones específicas y borrar por número.
# Ver reglas con números sudo ufw status numbered To Action From -- ------ ---- [ 1] 22/tcp ALLOW IN Anywhere [ 2] 80/tcp ALLOW IN Anywhere [ 3] 443/tcp ALLOW IN Anywhere [ 4] 3306/tcp ALLOW IN 192.168.1.0/24 [ 5] 22/tcp (v6) ALLOW IN Anywhere (v6) # Borrar por número (borra la regla 4 — MySQL) sudo ufw delete 4 Deleting: allow from 192.168.1.0/24 to any port 3306 Proceed with operation (y|n)? y Rule deleted # Insertar una regla en una posición específica (antes de la regla 2) sudo ufw insert 2 deny from 203.0.113.100 # Queda en posición 2, empujando las demás hacia abajo ## POR QUÉ IMPORTA EL ORDEN # Ejemplo: bloquear una IP pero con excepción para un puerto sudo ufw insert 1 allow from 203.0.113.10 to any port 443 # excepción PRIMERO sudo ufw insert 2 deny from 203.0.113.10 # regla general DESPUÉS # Así 203.0.113.10 puede entrar por 443 pero está bloqueada en todo lo demás ## BORRAR TODAS LAS REGLAS (conserva la config pero borra las reglas) sudo ufw reset Resetting all rules to installed defaults. Proceed with operation (y|n)? y
UFW gestiona IPv4 e IPv6 de forma simultánea. Por defecto, cuando añades una regla se crea tanto para IPv4 como para IPv6. También soporta reglas para protocolos específicos como ICMP.
## HABILITAR IPv6 EN UFW sudo nano /etc/default/ufw IPV6=yes ← debe estar en yes (viene por defecto) sudo ufw reload ## REGLAS IPv6 ESPECÍFICAS # Por defecto, ufw allow 80 crea reglas para IPv4 e IPv6 a la vez # Para especificar solo una familia: sudo ufw allow proto tcp from ::/0 to any port 443 # solo IPv6 sudo ufw allow proto tcp from 0.0.0.0/0 to any port 443 # solo IPv4 ## ICMP (ping) — por defecto UFW permite ping saliente pero bloquea entrante # Permitir ping (ICMP) entrante — editar antes/after rules sudo nano /etc/ufw/before.rules # Buscar la sección -A ufw-before-input -p icmp y cambiar DROP por ACCEPT: -A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT sudo ufw reload # Verificar reglas IPv6 sudo ip6tables -L -n --line-numbers ## PROTOCOLOS TCP vs UDP sudo ufw allow 53/tcp # DNS sobre TCP (transferencias de zona) sudo ufw allow 53/udp # DNS sobre UDP (consultas normales) sudo ufw allow 53 # ambos a la vez sudo ufw allow 1194/udp # OpenVPN sudo ufw allow 51820/udp # WireGuard
UFW puede registrar los paquetes bloqueados y permitidos. Analizar los logs es fundamental para detectar ataques, diagnosticar problemas de conectividad y auditar el tráfico.
## NIVELES DE LOGGING sudo ufw logging off # sin logs sudo ufw logging on # logs básicos (por defecto: low) sudo ufw logging low # solo paquetes bloqueados sudo ufw logging medium # bloqueados + algunos permitidos sudo ufw logging high # todo (muy verboso — puede llenar /var/log) sudo ufw logging full # máximo detalle ## DÓNDE SE GUARDAN LOS LOGS /var/log/ufw.log ← logs de UFW /var/log/syslog ← también aparecen aquí /var/log/kern.log ← y aquí (mensajes del kernel) ## CONSULTAR LOS LOGS sudo tail -f /var/log/ufw.log Jan 15 14:32:01 servidor kernel: [UFW BLOCK] IN=eth0 OUT= MAC=... SRC=203.0.113.100 DST=192.168.1.1 PROTO=TCP DPT=22 SPT=54321 # Ver solo paquetes bloqueados sudo grep "UFW BLOCK" /var/log/ufw.log | tail -20 # Ver las IPs que más intentos bloqueados generan sudo grep "UFW BLOCK" /var/log/ufw.log | \ grep -oP 'SRC=\S+' | sort | uniq -c | sort -rn | head -20 342 SRC=203.0.113.100 ← posible escaneo o ataque 87 SRC=185.220.101.5 23 SRC=45.33.32.156 # Ver los puertos más atacados sudo grep "UFW BLOCK" /var/log/ufw.log | \ grep -oP 'DPT=\d+' | sort | uniq -c | sort -rn | head -10 1234 DPT=22 ← SSH es el más atacado 567 DPT=3389 ← RDP 234 DPT=23 ← Telnet # Con journalctl (si los logs van al journal) sudo journalctl -k | grep "UFW BLOCK" | tail -20
Los perfiles de aplicación UFW son archivos de configuración que definen los puertos de un servicio con nombre. Los paquetes del sistema los instalan automáticamente. También se pueden crear perfiles propios.
## VER PERFILES DISPONIBLES sudo ufw app list sudo ufw app info Nginx # detalles de un perfil ls /etc/ufw/applications.d/ # ver los archivos de perfil ## CREAR UN PERFIL PROPIO sudo tee /etc/ufw/applications.d/mi-app << 'EOF' [Mi App] title=Mi Aplicación Web description=Servidor Node.js con API y WebSockets ports=3000/tcp|3001/tcp|3002/tcp EOF sudo ufw app update mi-app # recargar el perfil sudo ufw allow "Mi App" sudo ufw app info "Mi App" Profile: Mi App Title: Mi Aplicación Web Description: Servidor Node.js con API y WebSockets Ports: 3000,3001,3002/tcp ## ESTRUCTURA DE UN PERFIL [Nombre del Perfil] ← nombre entre corchetes title=Título corto ← descripción corta description=Descripción ← descripción larga ports=80/tcp|443/tcp ← puertos separados por | ← formato: PUERTO/PROTOCOLO ## ACTUALIZAR TODOS LOS PERFILES sudo ufw app update all
Opciones avanzadas de UFW: NAT y forwarding para routers, reglas personalizadas en iptables dentro del ecosistema UFW, y gestión de la política por defecto.
## POLÍTICA POR DEFECTO sudo ufw default deny incoming # bloquear todo lo entrante (recomendado) sudo ufw default allow outgoing # permitir todo lo saliente sudo ufw default deny outgoing # bloquear saliente (modo muy restrictivo) sudo ufw default deny forward # bloquear forwarding (por defecto) sudo ufw default allow forward # necesario para routing/NAT ## HABILITAR IP FORWARDING (para routers y VPNs) sudo nano /etc/ufw/sysctl.conf net/ipv4/ip_forward=1 net/ipv6/conf/default/forwarding=1 sudo nano /etc/default/ufw DEFAULT_FORWARD_POLICY="ACCEPT" sudo ufw reload ## REGLAS BEFORE Y AFTER (iptables directo dentro de UFW) # /etc/ufw/before.rules: se ejecutan ANTES de las reglas UFW # /etc/ufw/after.rules: se ejecutan DESPUÉS de las reglas UFW # Útil para NAT, MASQUERADE, REDIRECT y reglas iptables complejas # Ejemplo: NAT/MASQUERADE para compartir internet (en /etc/ufw/before.rules) sudo nano /etc/ufw/before.rules # Añadir al INICIO del archivo, antes de *filter: *nat :POSTROUTING ACCEPT [0:0] -A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE COMMIT ## RELOAD vs DISABLE+ENABLE sudo ufw reload # recargar reglas sin perder las conexiones activas sudo ufw disable # desactivar completamente (permite todo) sudo ufw enable # activar (puede cortar conexiones) ## VER LAS REGLAS IPTABLES REALES QUE GENERA UFW sudo iptables -L -n -v --line-numbers 2>/dev/null | head -40 sudo iptables-save 2>/dev/null | grep -v "^#"
Configuración completa de UFW para un servidor web con Nginx — la configuración estándar para un servidor que sirve HTTP/HTTPS y permite acceso SSH solo desde IPs conocidas.
## PARTIMOS DE CERO — resetear y configurar desde el principio # 1. Resetear UFW (si ya tenía reglas) sudo ufw reset # 2. Política por defecto: denegar todo lo entrante, permitir saliente sudo ufw default deny incoming sudo ufw default allow outgoing # 3. SSH con rate limiting (anti fuerza bruta) # Si solo accedemos desde nuestra IP, mejor restringirlo: sudo ufw allow from TU_IP_PUBLICA to any port 22 proto tcp # Si necesitas SSH desde cualquier IP: sudo ufw limit ssh # 4. HTTP y HTTPS para el servidor web sudo ufw allow "Nginx Full" # abre 80 y 443 # O equivalente: sudo ufw allow 80/tcp sudo ufw allow 443/tcp # 5. Base de datos: SOLO desde localhost o red interna sudo ufw deny 3306/tcp # bloquear MySQL desde internet sudo ufw deny 5432/tcp # bloquear PostgreSQL desde internet # Si tienes un servidor de base de datos separado: sudo ufw allow from 10.0.0.5 to any port 3306 proto tcp # 6. Habilitar logging sudo ufw logging on # 7. Activar UFW sudo ufw enable # 8. Verificar la configuración final sudo ufw status verbose Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) To Action From -- ------ ---- 22/tcp LIMIT IN Anywhere 80/tcp ALLOW IN Anywhere 443/tcp ALLOW IN Anywhere 3306/tcp DENY IN Anywhere 5432/tcp DENY IN Anywhere
Configuración de UFW para un VPS de producción con múltiples servicios: web, email, base de datos y acceso administrativo restringido. Configuración lista para copiar y adaptar.
#!/bin/bash # Script de configuración UFW para VPS de producción # Adaptar las variables antes de ejecutar ADMIN_IP="203.0.113.10" # IP del administrador (la tuya) DB_SERVER="10.0.0.5" # IP del servidor de base de datos MONITOR_IP="10.0.0.10" # IP del servidor de monitorización # Reset sudo ufw --force reset # Políticas por defecto sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw default deny forward # SSH: solo desde la IP del administrador sudo ufw allow from $ADMIN_IP to any port 22 proto tcp # Web pública sudo ufw allow 80/tcp sudo ufw allow 443/tcp # Email (si es servidor de correo) sudo ufw allow 25/tcp # SMTP (recibir correo) sudo ufw allow 587/tcp # SMTP submission (enviar autenticado) sudo ufw allow 993/tcp # IMAPS sudo ufw allow 995/tcp # POP3S # Base de datos: solo desde el servidor de app sudo ufw allow from $DB_SERVER to any port 5432 proto tcp # Monitorización (Prometheus, Zabbix, etc.) sudo ufw allow from $MONITOR_IP to any port 9100 proto tcp # node_exporter sudo ufw allow from $MONITOR_IP to any port 9090 proto tcp # Prometheus # Bloquear puertos peligrosos (aunque la política default deny los bloquea, # hacerlo explícito ayuda a detectarlos en los logs) sudo ufw deny 23/tcp # Telnet sudo ufw deny 21/tcp # FTP (usar SFTP en su lugar) sudo ufw deny 111/tcp # RPC sudo ufw deny 135/tcp # MS RPC sudo ufw deny 445/tcp # SMB # Logging activo sudo ufw logging on # Activar sudo ufw enable sudo ufw status numbered # Verificar que SSH sigue funcionando ANTES de cerrar la sesión actual echo "UFW configurado. Abre una NUEVA conexión SSH para verificar antes de cerrar esta."
Referencia rápida de todos los comandos UFW más usados.
Comandos de control
- Activar:
ufw enable - Desactivar:
ufw disable - Estado:
ufw status verbose - Estado numerado:
ufw status numbered - Recargar:
ufw reload - Resetear todo:
ufw reset
Reglas más usadas
## POLÍTICAS POR DEFECTO sudo ufw default deny incoming sudo ufw default allow outgoing ## PUERTOS HABITUALES sudo ufw allow ssh # SSH (22/tcp) sudo ufw limit ssh # SSH con anti-fuerza bruta sudo ufw allow http # HTTP (80/tcp) sudo ufw allow https # HTTPS (443/tcp) sudo ufw allow "Nginx Full" # HTTP + HTTPS con perfil Nginx ## RESTRINGIR POR IP sudo ufw allow from IP to any port 22 proto tcp sudo ufw allow from 192.168.1.0/24 to any port 3306 sudo ufw deny from IP # bloquear IP completamente sudo ufw insert 1 deny from IP # bloquear con prioridad máxima ## BORRAR REGLAS sudo ufw delete allow 80/tcp # por la regla exacta sudo ufw delete 3 # por número (ver con status numbered) ## RANGO DE PUERTOS sudo ufw allow 6000:6007/tcp ## LOGGING sudo ufw logging on # activar logs sudo tail -f /var/log/ufw.log # ver logs en tiempo real sudo grep "UFW BLOCK" /var/log/ufw.log | grep -oP 'SRC=\S+' | sort | uniq -c | sort -rn | head ## PERFILES sudo ufw app list # ver perfiles disponibles sudo ufw app info Nginx # detalles de un perfil sudo ufw allow "Nginx Full" # usar un perfil
Checklist de servidor nuevo
- Establecer política:
ufw default deny incoming && ufw default allow outgoing - Permitir SSH ANTES de activar:
ufw allow sshoufw limit ssh - Activar UFW:
ufw enable - Verificar acceso SSH desde otra terminal antes de cerrar la sesión actual
- Abrir solo los puertos necesarios para los servicios del servidor
- Restringir por IP los servicios sensibles (BBDD, paneles de admin)
- Activar logging:
ufw logging on - Revisar el estado final:
ufw status verbose - Verificar que UFW arranca con el sistema:
systemctl is-enabled ufw
Puertos de referencia rápida
| Puerto | Protocolo | Servicio | Recomendación |
|---|---|---|---|
22 | TCP | SSH | limit o restringir por IP |
80 | TCP | HTTP | allow si es servidor web público |
443 | TCP | HTTPS | allow si es servidor web público |
25 | TCP | SMTP | allow solo si es servidor de correo |
3306 | TCP | MySQL | deny público — solo desde IPs conocidas |
5432 | TCP | PostgreSQL | deny público — solo desde IPs conocidas |
6379 | TCP | Redis | deny público — solo localhost o red interna |
27017 | TCP | MongoDB | deny público — solo localhost o red interna |
23 | TCP | Telnet | deny siempre — protocolo inseguro |
21 | TCP | FTP | deny — usar SFTP (puerto 22) en su lugar |