Problema
Muchos entornos de homelab o servidores de bajo consumo se entregan con una pila de red sin políticas restrictivas: todas las cadenas de iptables están en ACCEPT, no existe un conjunto de reglas nftables y herramientas como UFW no están instaladas. Cuando el host ejecuta servicios que escuchan en 0.0.0.0 (SMB, NFS, rpcbind, VNC, etc.) o lanza contenedores Docker con puertos publicados, esos puertos quedan expuestos a la LAN sin filtro alguno. El síntoma típico es que cualquier máquina en la red local puede conectar a esos servicios sin autenticación adicional, lo que rompe la premisa de “solo los servicios que yo configure”. Además, aplicar reglas de iptables a través de una sesión SSH puede dejar al administrador fuera si la regla bloquea la propia conexión.
Causa
- Configuración predeterminada abierta – Distribuciones minimalistas o imágenes de hardware embebido suelen dejar
policy ACCEPTenINPUT,FORWARDyOUTPUT. Sin una política de denegación, cualquier socket que se abra es accesible. - Ignorar la cadena DOCKER‑USER – Docker inserta reglas de NAT en
FORWARD. Los firewalls que solo filtranINPUTno interceptan el tráfico DNAT que llega a contenedores publicados, por lo que los puertos siguen abiertos aunque la política deINPUTseaDROP. - Falta de mecanismo de prueba/rollback – Los administradores aplican cambios directamente, sin validar que la nueva regla no interfiere con la sesión activa. Cuando la regla es errónea, la única salida es reiniciar el host o perder la conexión.
- Ausencia de gestión centralizada – Sin una UI o archivo de configuración, cada regla se escribe a mano, lo que genera inconsistencias y dificulta auditorías.
Solución
Implementar un firewall de host que:
- Cambie la política por defecto a
DROPenINPUT. - Utilice la cadena
DOCKER‑USERpara filtrar tráfico hacia contenedores publicados. - Mantenga una lista blanca de interfaces de gestión (loopback, interfaces VPN como
tailscale0ozerotier0). - Aplique cambios mediante un proceso “Safe‑Apply”: carga temporal de reglas, espera de confirmación y rollback automático si no se confirma dentro de un plazo.
Paso a paso
-
Crear archivo de reglas base
Un script que defina la política y las excepciones estáticas. Se guarda, por ejemplo, en/etc/firewall/base.rules. -
Añadir regla de Docker
Insertar una regla al principio deDOCKER‑USERque redirija todo el tráfico a una política deDROPy luego permita explícitamente los puertos que el administrador desea exponer. -
Implementar Safe‑Apply
Un wrapper que:- Carga las nuevas reglas con
iptables-restore --noflush. - Inicia un temporizador (120 s) que, al expirar, restaura la copia anterior usando
iptables-restore. - Permite confirmar la aplicación mediante
zfw commito una petición HTTP a una UI ligera.
- Carga las nuevas reglas con
-
Persistencia
Configurarsystemdpara ejecutar el script de carga en arranque y para restaurar la última configuración confirmada. -
Auditoría básica
Añadir una regla de logging enINPUTyDOCKER‑USERque registre paquetes descartados conLOG --log-prefix "[FW DROP]". Los logs pueden ser enviados ajournalctlo a un syslog central.
Cuándo aplicar esta solución
- Entornos sin firewall – Servidores que arrancan con
policy ACCEPTy que ejecutan servicios expuestos. - Uso intensivo de Docker – Cuando se publican puertos de contenedores y se necesita que el tráfico pase por el mismo control que el host.
- Acceso remoto por SSH – Si la única vía de gestión es SSH, el mecanismo Safe‑Apply evita bloqueos accidentales.
- No se requiere router/edge firewall – La solución actúa solo en la frontera del host; para filtrado de tráfico entre subredes se necesita un dispositivo dedicado.
No es adecuada cuando se busca inspección profunda de paquetes (IDS/IPS) o gestión de políticas entre varios hosts simultáneamente.
Código
#!/usr/bin/env bash
# firewall-apply.sh – carga segura de reglas iptables
RULES_NEW="/etc/firewall/rules.new"
RULES_OLD="/etc/firewall/rules.backup"
TIMEOUT=120
# Guardar estado actual
iptables-save > "$RULES_OLD"
# Intentar cargar nuevas reglas sin flush
if ! iptables-restore --noflush < "$RULES_NEW"; then
echo "Error al cargar reglas nuevas"
exit 1
fi
# Iniciar temporizador de rollback
(
sleep "$TIMEOUT"
echo "Rollback automático: restaurando reglas anteriores"
iptables-restore < "$RULES_OLD"
) &
ROLLBACK_PID=$!
# Esperar confirmación del usuario
read -p "Confirmar aplicación de reglas (s/N): " -r CONFIRM
if [[ "$CONFIRM" =~ ^[Ss]$ ]]; then
kill "$ROLLBACK_PID" 2>/dev/null
echo "Reglas confirmadas"
else
echo "No se confirmó, ejecutando rollback"
iptables-restore < "$RULES_OLD"
fi
Verificación
-
Comprobar política
iptables -L INPUT -v -nLa columna
policydebe mostrarDROP. -
Probar puerto de Docker
Desde otra máquina, intenta conectar al puerto publicado. Si el puerto no está en la whitelist, la conexión debe ser rechazada y aparecer una entrada en el log con el prefijo[FW DROP]. -
Validar rollback
Ejecutafirewall-apply.shy no confirmes. Después de 120 s, verifica que la tabla vuelva a la configuración anterior coniptables-save. -
Revisar logs
journalctl -u firewall-apply -k | grep "\[FW DROP\]"
Notas adicionales
- Orden de reglas – En
DOCKER‑USERla regla deDROPdebe estar antes que cualquier regla de aceptación, de lo contrario Docker insertará sus propias reglas por encima. - IPv6 – Si el host usa IPv6, replica la misma lógica en
ip6tables. La ausencia de reglas IPv6 es una fuente frecuente de fugas. - Backup de reglas – Programar una tarea cron que copie
iptables-savea/var/backups/iptables-$(date +%F).bakfacilita la recuperación después de un error inesperado. - Compatibilidad con nftables – En sistemas que prefieren nftables, la lógica es idéntica: usar la tabla
filter, cadenainputconpolicy dropy la cadenadocker-user(creada connft add chain ip filter docker-user { type filter hook prerouting priority 0 \; }). - Limitaciones de Safe‑Apply – El temporizador solo protege la sesión que ejecuta el script. Si la regla bloquea todo el tráfico entrante, incluso el propio proceso de rollback seguirá activo porque se ejecuta en el mismo espacio de red. Por eso se usa
--noflushy se guarda el estado previo antes de aplicar cambios.