Skip to content

Configuración de Firewall UFW - Servidor de Medios

Fecha de implementación: 2026-01-09 Aplicado por: Claude Code Servidor: 192.168.0.208 (VM Ubuntu en Proxmox)


¿Qué es UFW?

UFW (Uncomplicated Firewall) es una interfaz simplificada para iptables, el firewall de Linux.

  • iptables: Firewall del kernel de Linux (complejo, muchas opciones)
  • UFW: Wrapper "amigable" sobre iptables (fácil de usar)

Estado ANTES de los cambios

$ sudo ufw status
Status: inactive

# NO había firewall activo
# TODOS los puertos accesibles desde cualquier IP

¿Qué estamos haciendo?

Configuración aplicada:

# 1. Política por defecto: DENEGAR todo tráfico entrante
sudo ufw default deny incoming

# 2. Política por defecto: PERMITIR todo tráfico saliente
sudo ufw default allow outgoing

# 3. Permitir TODO desde la red local (192.168.0.0/24)
sudo ufw allow from 192.168.0.0/24

# 4. Permitir SSH (puerto 22) desde CUALQUIER IP, con rate-limiting anti brute-force
sudo ufw limit 22/tcp

# 5. Activar el firewall
sudo ufw enable

¿Qué significa cada regla?

Regla 1: default deny incoming

  • Qué hace: Bloquea TODAS las conexiones entrantes por defecto
  • Excepción: Solo permite lo que explícitamente autorizamos (reglas 3 y 4)
  • Ejemplos bloqueados:
  • Escaneo de puertos desde internet
  • Intentos de conexión SSH desde IPs no permitidas
  • Acceso directo a puertos de Docker desde internet

Regla 2: default allow outgoing

  • Qué hace: Permite que el servidor inicie conexiones hacia afuera
  • Ejemplos permitidos:
  • Actualizaciones de paquetes (apt update)
  • Descarga de imágenes Docker (docker pull)
  • Conexiones a APIs externas (Put.io, Jellyseerr, etc.)
  • Cloudflare Tunnel (conexión saliente al edge de Cloudflare)

Regla 3: allow from 192.168.0.0/24

  • Qué hace: Permite TODO el tráfico desde tu red local
  • Rango cubierto: 192.168.0.1 - 192.168.0.254
  • Dispositivos incluidos:
  • 192.168.0.1 → Router
  • 192.168.0.171 → Home Assistant
  • 192.168.0.208 → Este servidor (a sí mismo)
  • Cualquier PC, móvil, TV en tu WiFi
  • Puertos permitidos: TODOS (Jellyfin:8096, Dockge:5001, etc.)
  • Protocolos: TCP y UDP

Regla 4: limit 22/tcp

  • Qué hace: Permite SSH desde CUALQUIER IP (incluso fuera de tu red) en modo LIMIT (rate-limiting): bloquea IPs que intenten >6 conexiones en 30 s
  • Por qué: Para poder acceder remotamente si estás fuera de casa, mitigando brute-force en el borde (defensa en profundidad junto a fail2ban)
  • Seguridad adicional recomendada:
  • Usa autenticación por clave SSH (no password)
  • Considera cambiar puerto (ej: 2222) para evitar bots
  • O restringe a tu IP pública: ufw allow from TU_IP_PUBLICA to any port 22

Regla 5: allow from 172.16.0.0/12

  • Qué hace: Permite todo el tráfico desde el rango privado 172.16.0.0/12
  • Por qué: El bridge Docker por defecto docker0 (172.17.0.0/16) cae en este rango. ⚠️ Las redes Docker personalizadas usan 10.200.0.0/14 (default-address-pools en daemon.json), no 172.16/12 — esta regla solo cubre docker0, no las redes custom.
  • Rango cubierto: 172.16.0.0 - 172.31.255.255

¿Qué NO cambia?

✅ Cloudflare Tunnels seguirán funcionando

  • Los tunnels usan conexiones salientes (regla 2)
  • El daemon cloudflared conecta HACIA Cloudflare, no recibe conexiones entrantes
  • Todos tus subdominios *.monxas.casa funcionarán igual

✅ Acceso desde tu red local (192.168.0.x)

  • Todos tus dispositivos pueden acceder a todos los servicios
  • Jellyfin desde TV → ✓
  • Dockge desde tu PC → ✓
  • Home Assistant hablando con el servidor → ✓

✅ Docker networking interno

  • Los contenedores se comunican entre sí sin problemas
  • Prometheus → cAdvisor → ✓
  • Sonarr → Prowlarr → ✓
  • Las redes Docker (bridges) NO se ven afectadas

✅ Servicios que inician conexiones

  • Watchtower descargando actualizaciones → ✓
  • Sonarr/Radarr descargando de indexers → ✓
  • ntfy enviando notificaciones → ✓

¿Qué SÍ bloquea?

❌ Conexiones directas desde internet a puertos Docker

Si alguien desde internet (sin Cloudflare Tunnel) intenta:

# Escanear puertos (desde IP 8.8.8.8 por ejemplo)
nmap 192.168.0.208
> Host seems down (filtered)

# Conectar directamente a Jellyfin
curl http://TU_IP_PUBLICA:8096
> Connection timeout (bloqueado por UFW)

Nota: Esto ya estaba protegido porque: 1. Tu router NO hace port-forwarding (asumo) 2. Usas Cloudflare Tunnels (IP del servidor oculta)

Beneficio: Protección adicional en caso de: - Misconfigración de router (port-forward accidental) - Vulnerabilidad en Cloudflare - Ataque desde otra VM en Proxmox


Verificación post-implementación

Comprobar estado del firewall:

sudo ufw status verbose

Salida esperada:

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
8082/tcp                   ALLOW       Anywhere
Anywhere                   ALLOW       192.168.0.0/24
22/tcp                     LIMIT       Anywhere
Anywhere                   ALLOW       172.16.0.0/12
8082/tcp (v6)              ALLOW       Anywhere (v6)
22/tcp (v6)                LIMIT       Anywhere (v6)

Probar conectividad desde tu PC (192.168.0.x):

# Debe funcionar
curl http://192.168.0.208:8096  # Jellyfin
curl http://192.168.0.208:5001  # Dockge
ssh [email protected]        # SSH

Verificar que servicios siguen funcionando:

sudo docker ps --filter "status=running" --format "{{.Names}}: {{.Status}}"

Cómo desactivar el firewall (si algo falla)

Opción 1: Desactivar temporalmente (para debug)

sudo ufw disable
# Probar cosas...
sudo ufw enable

Opción 2: Modo permisivo (permitir todo)

sudo ufw default allow incoming
sudo ufw reload

Opción 3: Ver logs de conexiones bloqueadas

sudo tail -f /var/log/ufw.log
# Busca líneas con [UFW BLOCK] para ver qué se está bloqueando

Reglas adicionales y mejoras de seguridad

✅ Protección SSH con fail2ban (IMPLEMENTADO)

fail2ban está activo y monitoreando intentos de login SSH:

# Ver estado
sudo fail2ban-client status sshd

# Ver IPs baneadas
sudo fail2ban-client get sshd banip

# Desbanear una IP
sudo fail2ban-client set sshd unbanip <IP>

Configuración: - Banea IPs después de 5 intentos fallidos - Duración del ban: 10 minutos - Monitorea: /var/log/auth.log

Limitar intentos de SSH con UFW (APLICADO 2026-07-12)

sudo ufw limit 22/tcp
# Bloquea IPs que intenten >6 conexiones en 30 segundos
# APLICADO: la regla 22/tcp está en modo LIMIT (no ALLOW). Se mantiene como
# defensa en profundidad junto a fail2ban, no en su lugar.

Permitir solo tu IP pública para SSH

sudo ufw delete allow 22/tcp
sudo ufw allow from TU_IP_PUBLICA to any port 22
# Obtén tu IP: curl ifconfig.me

Permitir conexiones específicas desde internet (ejemplo)

# Si necesitas abrir un puerto específico (NO recomendado)
sudo ufw allow 8096/tcp  # Jellyfin directo desde internet

Bloquear rango de IPs específico

sudo ufw deny from 192.168.0.100/32
# Útil si un dispositivo IoT está comprometido

Archivos de configuración

Ubicación de configuración de UFW:

  • /etc/ufw/ufw.conf - Configuración principal
  • /etc/ufw/user.rules - Reglas IPv4 generadas
  • /etc/ufw/user6.rules - Reglas IPv6 generadas
  • /var/log/ufw.log - Logs de actividad

Backup de configuración:

# Crear backup manual
sudo cp -r /etc/ufw /etc/ufw.backup.$(date +%Y%m%d)

# Ver reglas actuales (formato exportable)
sudo ufw status numbered

Troubleshooting

Problema: No puedo conectar a un servicio desde mi PC

# 1. Verificar que UFW está activo
sudo ufw status

# 2. Ver si la regla de 192.168.0.0/24 existe
sudo ufw status | grep 192.168.0

# 3. Verificar IP de tu PC está en el rango
ip addr | grep inet

# 4. Probar conexión directa (bypass Docker)
telnet 192.168.0.208 8096

Problema: Cloudflare Tunnel dejó de funcionar

# Verificar que cloudflared está corriendo
sudo docker logs cloudflared -f

# Cloudflare Tunnel usa conexiones SALIENTES (no afectadas por UFW incoming)
# Si falla, el problema es otro (certificado, configuración CF, etc.)

Problema: Docker no puede descargar imágenes

# Verificar política outgoing
sudo ufw status verbose | grep "Default:"
# Debe decir: allow (outgoing)

# Probar conectividad
ping 8.8.8.8
curl https://hub.docker.com

Monitoreo continuo

Ver actividad del firewall en tiempo real:

# Ver logs de UFW
sudo tail -f /var/log/ufw.log

# Ver solo bloqueos
sudo grep BLOCK /var/log/ufw.log | tail -20

# Estadísticas de conexiones
sudo ufw status numbered

Integración con Prometheus (opcional futuro):

# Exportar métricas de UFW a Prometheus
# https://github.com/cablespaghetti/ufw_exporter

Referencias

  • UFW Manual: man ufw
  • Documentación Ubuntu: https://help.ubuntu.com/community/UFW
  • Cloudflare Tunnel docs: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/

Changelog

Fecha Cambio Motivo
2026-01-09 Implementación inicial UFW Mejora de seguridad - pentesting
Reglas: deny incoming, allow 192.168.0.0/24, allow SSH Protección contra acceso externo no autorizado
2026-01-10 Instalado fail2ban para SSH Protección contra brute-force SSH
Instalado smartmontools, lm-sensors Monitoreo de hardware
Configurado swap 4GB (swappiness=10) Protección contra OOM
2026-07-12 Aplicado ufw limit 22/tcp (22/tcp ALLOW → LIMIT) Rate-limiting SSH en el borde (defensa en profundidad)
Documentada regla allow from 172.16.0.0/12 Cubre docker0 (172.17/16); redes custom usan 10.200.0.0/14