Alex Sarmiento
ES / EN

UFW (Uncomplicated Firewall) es una interfaz simplificada para iptables o nftables. Aunque su nombre sugiere sencillez, es una herramienta extremadamente potente si se configura con una mentalidad de “Zero Trust” (Confianza Cero).

En este post pasaremos de una instalación limpia a una configuración de seguridad grado producción.

1. La Estrategia: “Default Deny”

Antes de abrir nada, debemos establecer la política base. La regla de oro en seguridad es: Cierra todo, abre solo lo imprescindible.

Por defecto, UFW debería rechazar cualquier intento de conexión entrante y permitir que tu servidor salga a internet (para actualizaciones, curl, etc.).

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

# Permite todo el tráfico saliente
sudo ufw default allow outgoing

2. La Regla de la Supervivencia: SSH

ADVERTENCIA: Si activas UFW ahora mismo sin configurar SSH, te quedarás fuera de tu servidor para siempre (si es remoto).

2.1 SSH Básico

Si usas el puerto estándar (22):

sudo ufw allow ssh

2.2 Rate Limiting (Protección contra fuerza bruta)

En lugar de simplemente “permitir” SSH, vamos a usar limit. Esto bloqueará la IP atacante si intenta conectarse y falla 6 veces en 30 segundos. Es tu primera línea de defensa contra bots.

sudo ufw limit ssh

2.3 SSH en puerto personalizado

Si has cambiado tu puerto SSH (ej. 2222) en /etc/ssh/sshd_config, debes especificarlo explícitamente:

sudo ufw allow 2222/tcp

3. Activación y Verificación

Solo ahora que tienes garantizado el acceso SSH, procedemos a activar el firewall.

sudo ufw enable

Verifica el estado detallado:

sudo ufw status verbose

Deberías ver Default: deny (incoming), allow (outgoing) y tus reglas de SSH.

4. Segmentación de Tráfico (Reglas Avanzadas)

Abrir puertos a “todo el mundo” (Anywhere) es peligroso. Vamos a ser quirúrgicos.

4.1 Permitir servicios web públicos

Para un servidor web, generalmente quieres que todo el mundo acceda:

# HTTP y HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

4.2 Restringir bases de datos a la red local

Nunca expongas una base de datos (MySQL 3306, Postgres 5432, Redis 6379) a internet. Si necesitas acceder desde tu red local (LAN), especifica el rango de IP.

Supongamos que tu red es 192.168.1.x:

# Permitir acceso al puerto 5432 SOLO desde la red doméstica
sudo ufw allow from 192.168.1.0/24 to any port 5432

4.3 Confianza total entre servidores (VPN/VLAN)

Si tienes una VPN (como WireGuard o Tailscale) o una red privada entre servidores, puedes permitir todo el tráfico que venga de una IP específica.

# Permitir todo el tráfico desde mi servidor de backups (10.0.0.5)
sudo ufw allow from 10.0.0.5

5. Gestión de Interfaces

A veces quieres reglas que solo apliquen a una tarjeta de red específica (por ejemplo, eth0 vs wg0).

# Permitir tráfico DNS (53) solo en la interfaz de la VPN (wg0)
sudo ufw allow in on wg0 to any port 53

6. Mantenimiento y Depuración

6.1 Borrado seguro de reglas

Nunca intentes borrar escribiendo la regla de memoria. Podrías borrar la incorrecta. Usa el listado numerado:

sudo ufw status numbered
Salida:

Plaintext

[ 1] 22/tcp (LIMIT)    ALLOW IN    Anywhere
[ 2] 80/tcp            ALLOW IN    Anywhere
[ 3] 3306/tcp          ALLOW IN    Anywhere  <-- PELIGROSO

Para eliminar la regla 3:

sudo ufw delete 3

6.2 Logs y Auditoría

Si algo no funciona, necesitas saber si el firewall lo está bloqueando.

# Activar logs (se guardan en /var/log/ufw.log o dmesg)
sudo ufw logging on
sudo ufw logging medium

Para ver los bloqueos en tiempo real:

tail -f /var/log/ufw.log

7. Nota importante sobre Docker

Debo advertir que Docker manipula iptables directamente.

Por defecto, si publicas un puerto en Docker (-p 8080:80), Docker insertará reglas en iptables que se saltan UFW. Tu puerto 8080 quedará expuesto al mundo aunque UFW diga lo contrario.

Si usas Docker, no confíes ciegamente en sudo ufw status. Verifica siempre desde fuera de tu red con herramientas como nmap o escáneres de puertos online.

Resumen de comandos

Básicos: allow, deny, delete, status numbered.

Avanzados: limit (anti-bruteforce), from (whitelist).

Diagnóstico: logging on.

Bonus: Script de configuración automática

Como regalo final adjunto un script para securizar un servidor recién instalado con una sola ejecución:

#!/bin/bash

# ==========================================
# HARDENING EXPRESS - SERVIDOR NUEVO
# ==========================================
# Este script realiza una configuración de seguridad mínima viable:
# 1. Actualiza el sistema
# 2. Instala herramientas básicas (curl, git, htop, ufw, fail2ban)
# 3. Configura el Firewall (UFW) con política Default Deny
# 4. Configura Fail2Ban para proteger SSH
# ==========================================

echo "[1/4] Actualizando repositorios y sistema..."
apt update && apt upgrade -y

echo "[2/4] Instalando utilidades base..."
apt install -y curl git htop ufw fail2ban

echo "[3/4] Configurando Firewall (UFW)..."
# Reseteamos por si acaso
ufw --force reset

# Política base: Cerrado por defecto
ufw default deny incoming
ufw default allow outgoing

# Reglas SSH (Limit protege contra fuerza bruta simple)
ufw limit ssh

# Reglas Web (Descomentar si es un servidor web)
# ufw allow 80/tcp
# ufw allow 443/tcp

# Activación (sin pedir confirmación interactiva)
ufw --force enable

echo "[4/4] Configurando Fail2Ban..."
# Creamos una copia local de la configuración
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Reiniciamos el servicio para aplicar cambios
systemctl restart fail2ban
systemctl enable fail2ban

echo "=========================================="
echo " ESTADO FINAL DEL FIREWALL"
echo "=========================================="
ufw status verbose

echo ""
echo "¡Listo! Tu servidor tiene ahora una capa de seguridad básica activa."

¡Ahora tienes un perímetro de seguridad robusto y segmentado!