Reglas del firewall de Proxmox no se aplican: conflictos entre iptables y nftables explicados

¿Te fue útil?

Activas el firewall de Proxmox, añades una regla clara de “denegar todo excepto SSH” y… nada. La VM sigue respondiendo en puertos que acabas de bloquear, o peor, tus cambios parecen funcionar durante un minuto y luego desaparecen. Mientras tanto, la interfaz gráfica muestra una confianza orgullosa, como si ya hubiera resuelto el problema.

Nueve de cada diez veces, esto no es que Proxmox te esté “ignorando”. Es Linux haciendo exactamente lo que le pediste—solo que no en el lenguaje de firewall que crees estar usando. iptables y nftables pueden coexistir de una forma que parece cooperación pero se comporta como una guerra fría.

Qué estás depurando realmente (la tubería de Netfilter, no la GUI)

Las reglas del firewall de Proxmox terminan en el filtrado de paquetes del kernel de Linux (Netfilter). El servicio de Proxmox (pve-firewall) genera reglas y las aplica usando las herramientas disponibles en el host. Si el host usa nftables y tu memoria muscular de resolución de problemas usa iptables (o viceversa), puedes mirar cadenas vacías durante una hora mientras el tráfico fluye felizmente.

Aquí está lo clave: “iptables” es tanto (a) una interfaz de línea de comandos como (b) un formato de reglas heredado. En Debian/Proxmox modernos, el comando iptables puede ser un frontend de compatibilidad que escribe reglas en nftables (“iptables-nft”). Así que cuando dices “muéstrame las reglas de iptables”, podrías estar mirando una vista diferente a la que está realmente activa.

Conclusión para producción: cuando las reglas del firewall “no se aplican”, normalmente estás tratando con una de estas situaciones:

  • Las reglas se instalan en nftables, pero las estás inspeccionando con iptables-legacy (o al revés).
  • Las reglas están instaladas, pero se aplican en un hook/cadena que no esperabas (puente vs ruta; prioridades raw/mangle/filter).
  • Conntrack permite que los flujos existentes continúen, haciendo que tu nueva regla parezca inútil.
  • Otro gestor de firewall (ufw, firewalld, docker, kube-proxy, un script “útil”) está reescribiendo las tablas después de que Proxmox aplica sus reglas.
  • Diferencias de configuración del clúster: la GUI edita un nodo, otro nodo aplica ajustes locales distintos.

Un firewall es como una reunión: la mitad del drama es quién habló primero. (Broma 1/2.)

Datos históricos y contexto interesante (para que lo raro tenga sentido)

  1. Netfilter está en el kernel; iptables y nftables son planos de control en espacio de usuario. Ambos finalmente programan los mismos hooks del kernel, pero con representaciones y semánticas de reglas diferentes.
  2. nftables fue diseñado para reemplazar iptables y reducir la duplicación entre tablas IPv4/IPv6/ARP, añadiendo sets, maps y una sintaxis más limpia.
  3. Debian cambió la implementación por defecto de iptables a “iptables-nft”. Esto significa que iptables puede manipular reglas de nftables a menos que selecciones explícitamente iptables-legacy.
  4. iptables-legacy y nftables pueden ejecutarse al mismo tiempo sin errores obvios. Eso no es una característica; es un impuesto de depuración.
  5. El filtrado en puentes es especial. Los paquetes que atraviesan puentes Linux pueden filtrarse mediante br_netfilter y sysctls como net.bridge.bridge-nf-call-iptables, lo que cambia lo que “INPUT” y “FORWARD” significan en la práctica.
  6. El comportamiento por defecto de conntrack sorprende a la gente. Las nuevas denegaciones no matan necesariamente conexiones ya establecidas a menos que bloquees o reinicies explícitamente; a menudo necesitas vaciar conntrack para una prueba limpia.
  7. Docker históricamente usó mucho iptables y puede insertar reglas NAT/FORWARD que contravienen las expectativas locales—especialmente cuando se mezcla con frontends nftables.
  8. El orden de las reglas y la prioridad de cadenas importan más en nftables porque múltiples cadenas base pueden enganchar la misma etapa con prioridades explícitas.
  9. El firewall de Proxmox está centrado en el host pero también administra reglas a nivel de VM; esas pueden implementarse vía iptables/nftables en el host, no dentro del huésped, lo cual sorprende a quienes esperan “el firewall corre donde corre la aplicación”.

Una idea de confiabilidad que me gusta parafraseada—“esperanza no es una estrategia”—es común en pensamiento de operaciones. Trata el estado del firewall como algo que mides, no como algo que sientes.

Guía rápida de diagnóstico

Cuando las reglas del firewall de Proxmox no se aplican, quieres el camino más corto hacia la primera pista real. Aquí está el orden que gana en incidentes reales.

1) Confirma qué backend estás usando realmente (nft vs legacy)

  • Si el host usa nftables (nft list ruleset muestra cadenas activas), deja de mirar las salidas de iptables -S del backend equivocado.
  • Si ambos están presentes, decide cuál es el autoritativo y elimina la ambigüedad.

2) Confirma el estado del servicio pve-firewall y la última aplicación

  • ¿Está pve-firewall en ejecución y aplicando reglas sin errores?
  • ¿Estás editando el ámbito correcto (Datacenter vs node vs VM)?

3) Confirma que los paquetes recorren la ruta que crees

  • Ruta por puente vs ruta enrutada cambia cadenas y hooks.
  • Revisa los sysctls de br_netfilter y que la interfaz correcta esté siendo filtrada.

4) Busca cambios continuos de reglas por otros actores

  • ufw/firewalld, docker, kube-proxy, scripts personalizados.
  • Mira marcas temporales en logs y deltas de reglas.

5) Haz que tu prueba sea válida

  • Vacía conntrack (con cuidado) o prueba con conexiones nuevas.
  • Usa contadores/logs para demostrar que la regla se alcanza.

Cómo funciona el firewall de Proxmox por debajo

El firewall de Proxmox no es un escudo mágico de paquetes. Es un generador de reglas y un gestor de ciclo de vida. Declaras la intención en la GUI o en la configuración en /etc/pve/, y pve-firewall traduce eso a reglas del kernel.

Las reglas típicamente se aplican en el host, afectando:

  • Tráfico del host (plano de gestión): SSH, GUI, tráfico de clúster, tráfico de almacenamiento.
  • Tráfico de VM y contenedores: dependiendo del puente/enrutamiento y de la configuración del firewall, el host filtra el tráfico que cruza puentes o interfaces tap.

Proxmox también tiene múltiples ámbitos:

  • Firewall del Datacenter: reglas globales; útil para patrones “negar por defecto”.
  • Firewall del nodo: reglas específicas del host (piensa en acceso IPMI, redes de administración locales).
  • Firewall de VM/CT: permitir/denegar por huésped, útil cuando equipos comparten el mismo dominio L2 y quieres segmentación sin rearquitecturar la red.

Si las reglas “no se aplican”, una razón común es simplemente que el firewall está habilitado en un ámbito pero no en otros, o habilitado pero no en la interfaz real usada por el tráfico (clásico con múltiples puentes).

iptables vs nftables: patrones de conflicto que rompen reglas de Proxmox

Patrón de conflicto 1: “iptables no muestra nada, así que no hay reglas”

Si iptables es el frontend de nft, te mostrará una vista compatible con iptables de reglas almacenadas en nftables. Pero si estás ejecutando iptables-legacy (o tus scripts lo hacen), puedes acabar con dos realidades diferentes:

  • Proxmox aplica reglas vía nftables (directamente o mediante iptables-nft)
  • Tu comando de depuración lee tablas legacy
  • Concluyes “no hay reglas” y comienzas a “arreglar” lo equivocado

Patrón de conflicto 2: nftables y iptables-legacy están activos

Este es el modo de fallo más costoso porque puede funcionar a medias. Parte del tráfico se filtra; otro no. NAT se comporta de forma inconsistente. Un reinicio cambia el comportamiento dependiendo de qué servicio arranque primero.

Si quieres un sistema estable, elige uno. En Proxmox moderno sobre Debian, eso normalmente significa nftables como mecanismo del kernel, con compatibilidad iptables-nft si es necesario. Pero no dejes que las reglas de iptables-legacy permanezcan como solicitudes de cambio viejas que nadie quiere asumir.

Patrón de conflicto 3: El tráfico de puente no llega a las cadenas que esperas

En Proxmox, el tráfico de VM a menudo cruza puentes Linux (vmbr0) y dispositivos tap (tapX) o interfaces veth (contenedores). Si ese tráfico de puente es evaluado por iptables/nftables depende de br_netfilter y de los sysctls.

Si esos sysctls están apagados, tu regla “FORWARD drop” podría no ver paquetes bridged. Jurarás que el firewall está roto; Linux seguirá conmutando en L2 como le pediste.

Patrón de conflicto 4: Conntrack hace que pienses que tu nueva regla no funcionó

Bloqueas el puerto 443, pero tu sesión curl existente continúa. Eso es conntrack. Muchas reglas hacen match con ct state established,related temprano, lo cual es correcto por rendimiento y para no romper sesiones de larga duración—pero confunde al probar.

Patrón de conflicto 5: Otro componente reescribe reglas después de Proxmox

Los sospechosos habituales: docker, kube-proxy, ufw, firewalld, scripts personalizados en cron o timers de systemd, y algunos agentes de automatización de red. A ellos no les importa tu GUI. Les importa su propio estado deseado.

Si las reglas “se aplican” y luego revierten, este es tu primer sospechoso. Las herramientas de firewall son como niños pequeños: si dos comparten los mismos juguetes, uno va a llorar. (Broma 2/2.)

Tareas prácticas: comandos, salidas y decisiones (12+)

Estas son las comprobaciones que ejecuto cuando alguien dice “las reglas del firewall de Proxmox no se aplican”. Cada una incluye una salida realista y la decisión que tomas a partir de ella.

Task 1: Verificar si el firewall de Proxmox está habilitado en todos los ámbitos

cr0x@server:~$ pve-firewall status
Status: enabled
Running: yes
Log level: info

Qué significa: El servicio está en ejecución y el firewall está habilitado. Si ves Status: disabled, para aquí—habilítalo en la GUI o en la configuración antes de perseguir fantasmas de iptables.

Decisión: Si está deshabilitado, habilita y vuelve a probar. Si está habilitado, continúa con las comprobaciones del backend de reglas.

Task 2: Confirmar la salud del servicio pve-firewall y errores recientes

cr0x@server:~$ systemctl status pve-firewall --no-pager
● pve-firewall.service - PVE Firewall
     Loaded: loaded (/lib/systemd/system/pve-firewall.service; enabled)
     Active: active (running) since Thu 2025-12-26 10:12:33 UTC; 2h 8min ago
   Main PID: 1321 (pve-firewall)
      Tasks: 1 (limit: 154850)
     Memory: 21.4M
        CPU: 4.102s

Qué significa: Si esto muestra “failed” o reinicios rápidos, tus reglas pueden no estar aplicándose o aplicarse parcialmente.

Decisión: Si falla, inspecciona logs y arregla errores del servicio/runtime antes de sumergirte en nftables.

Task 3: Leer los logs de pve-firewall por fallos al aplicar reglas

cr0x@server:~$ journalctl -u pve-firewall -n 60 --no-pager
Dec 26 10:12:33 server pve-firewall[1321]: starting PVE firewall
Dec 26 10:12:34 server pve-firewall[1321]: status update OK
Dec 26 10:12:35 server pve-firewall[1321]: ruleset applied

Qué significa: “ruleset applied” es tu línea base. Errores sobre “iptables-restore failed” o “nft: syntax error” acotan inmediatamente la búsqueda al tooling/backends.

Decisión: Si ves errores de restore/apply, comprueba el backend iptables/nftables y la sintaxis de reglas a continuación.

Task 4: Determinar si iptables usa backend nft o legacy

cr0x@server:~$ update-alternatives --display iptables
iptables - auto mode
  link best version is /usr/sbin/iptables-nft
  link currently points to /usr/sbin/iptables-nft
  link iptables is /usr/sbin/iptables
/usr/sbin/iptables-legacy - priority 10
/usr/sbin/iptables-nft - priority 20

Qué significa: En este host, el comando iptables programa nftables. Si tus scripts llaman explícitamente a iptables-legacy, puedes tener un firewall con cerebro dividido.

Decisión: Estandariza: elige iptables-nft (común en Debian/Proxmox) a menos que tengas una razón convincente para lo contrario.

Task 5: Inspeccionar el ruleset de nftables (la fuente de la verdad en hosts nft)

cr0x@server:~$ nft list ruleset | sed -n '1,80p'
table inet filter {
  chain input {
    type filter hook input priority 0; policy accept;
    ct state established,related accept
    iifname "lo" accept
  }
  chain forward {
    type filter hook forward priority 0; policy accept;
  }
}

Qué significa: Tienes una tabla inet filter mínima con accept por defecto. Si Proxmox firewall está “habilitado” pero no ves cadenas/tablas generadas por Proxmox, o bien no se está aplicando a nftables o otra herramienta lo borró.

Decisión: Si faltan reglas de Proxmox, confirma si Proxmox está configurado para usar nftables/iptables correctamente y si un servicio competidor está reemplazando rulesets.

Task 6: Inspeccionar reglas de iptables (pero asegúrate de saber qué backend ves)

cr0x@server:~$ iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT

Qué significa: Esto casi no te dice nada por sí solo. En iptables-nft es una vista de compatibilidad. Si está vacío mientras nft muestra reglas, probablemente estés mezclando herramientas o mirando la familia de tablas equivocada.

Decisión: Usa nft para inspección autoritativa si tu iptables está respaldado por nft. Usa iptables-legacy solo si te has estandarizado en legacy (raro y cada vez más doloroso).

Task 7: Comprobar si iptables-legacy también está poblado (detección de cerebro dividido)

cr0x@server:~$ iptables-legacy -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N PVEFW-INPUT
-A INPUT -j PVEFW-INPUT

Qué significa: Si legacy muestra cadenas de Proxmox pero nft no, o viceversa, tienes una coincidencia de backend. El tráfico seguirá las reglas activas del kernel, no tu narrativa preferida.

Decisión: Alinea las alternativas y vuelve a aplicar las reglas de Proxmox. Elimina las reglas del otro backend para evitar confusión.

Task 8: Confirmar módulos del kernel y sysctls para filtrado de puentes

cr0x@server:~$ lsmod | grep br_netfilter || true
br_netfilter           32768  0
bridge                311296  1 br_netfilter
cr0x@server:~$ sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1

Qué significa: Los paquetes bridged recorrerán hooks de netfilter, permitiendo que tu firewall del host filtre tráfico de VM en puentes.

Decisión: Si estos son 0, el tráfico bridged puede evitar los hooks esperados. Decide si quieres filtrado de puente activado (común para firewall de VM en Proxmox) y configúralo de forma persistente si es necesario.

Task 9: Confirmar qué interfaces y puentes llevan el tráfico

cr0x@server:~$ ip -br link
lo               UNKNOWN        00:00:00:00:00:00
eno1             UP             3c:ec:ef:11:22:33
vmbr0            UP             3c:ec:ef:11:22:33
tap100i0         UP             fe:1a:2b:3c:4d:5e

Qué significa: Si tu regla se aplica a vmbr1 pero el tráfico fluye por vmbr0, tu regla “no hace nada” porque nunca ve los paquetes.

Decisión: Mapea la ruta del servicio: cliente → NIC física → puente → tap/veth → huésped. Filtra en el límite correcto.

Task 10: Usar contadores para demostrar que una regla se alcanza (nft)

cr0x@server:~$ nft -a list chain inet filter input
table inet filter {
  chain input { # handle 1
    type filter hook input priority 0; policy accept;
    ct state established,related accept # handle 2
    iifname "lo" accept # handle 3
  }
}

Qué significa: Si existieran reglas generadas por Proxmox, las verías aquí, idealmente con contadores. Sin contadores significa que ni siquiera estás mirando la cadena/tabla correcta o que las reglas no están instaladas.

Decisión: Si no puedes encontrar la regla, deja de probar tráfico y empieza a encontrar quién posee el ruleset.

Task 11: Monitorizar cambios de reglas en tiempo real (captura al culpable)

cr0x@server:~$ watch -n 1 'nft list ruleset | sha256sum | cut -d" " -f1'
3b26b25bbf6b613c6b6be8e5d2f1c8d0f50e3b0c6c1b86e3e9c6a2d4b9c7e012

Qué significa: Si el hash cambia cada pocos segundos o justo después de aplicar reglas de Proxmox, algo más está reescribiendo el ruleset.

Decisión: Identifica y deshabilita el gestor competidor, o intégralo correctamente. “Dos controladores” no es un patrón de diseño.

Task 12: Identificar otros gestores de firewall y escritores de reglas

cr0x@server:~$ systemctl list-unit-files | egrep 'ufw|firewalld|nftables|docker|kube|netfilter' || true
docker.service                         enabled
nftables.service                       enabled
pve-firewall.service                   enabled

Qué significa: Si nftables.service está habilitado y carga su propio /etc/nftables.conf, puede sobrescribir el estado deseado de Proxmox, dependiendo del orden de inicio y la configuración.

Decisión: O deja que Proxmox sea el propietario (común en hosts PVE) o asegúrate de que nftables.service sea compatible y no haga flush/replace de tablas que Proxmox necesita.

Task 13: Comprobar si el servicio nftables vacía reglas al recargar

cr0x@server:~$ sed -n '1,120p' /etc/nftables.conf
#!/usr/sbin/nft -f

flush ruleset

table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;
  }
}

Qué significa: flush ruleset es un borrado completo. Si esto se ejecuta después de pve-firewall, las reglas de Proxmox “no se aplicarán” porque se están eliminando.

Decisión: Elimina el flush completo, o deshabilita nftables.service, o integra explícitamente las tablas gestionadas por Proxmox. No ejecutes dos configuraciones autoritativas que compitan.

Task 14: Confirmar que la configuración del filesystem del clúster de Proxmox coincide con lo esperado

cr0x@server:~$ grep -R "enable:" -n /etc/pve/firewall | head
/etc/pve/firewall/cluster.fw:2:enable: 1
/etc/pve/firewall/server.fw:2:enable: 1

Qué significa: Las banderas de habilitación del firewall se almacenan en la configuración del clúster. Pero las peculiaridades locales del nodo (alternativas, servicios, sysctls) pueden seguir difiriendo y causar aplicación inconsistente.

Decisión: Si solo un nodo se comporta mal, compara la selección de backend y otros servicios en ese nodo primero, no la configuración de la GUI.

Task 15: Comprobar conntrack para situaciones de “la regla parece ignorada”

cr0x@server:~$ conntrack -L 2>/dev/null | head
tcp      6 431999 ESTABLISHED src=10.10.10.50 dst=10.10.10.21 sport=51522 dport=443 src=10.10.10.21 dst=10.10.10.50 sport=443 dport=51522 [ASSURED] mark=0 use=1

Qué significa: Los flujos establecidos pueden continuar pasando si tus reglas aceptan conexiones establecidas temprano (común y correcto).

Decisión: Para probar, abre una conexión completamente nueva desde un puerto de origen distinto o vacía conntrack para tuplas específicas (más quirúrgico que borrar todo).

Task 16: Vaciar un flujo específico de conntrack (prueba quirúrgica)

cr0x@server:~$ conntrack -D -p tcp --orig-src 10.10.10.50 --orig-dst 10.10.10.21 --dport 443
1 flow entries have been deleted.

Qué significa: Ahora un nuevo SYN debe atravesar tus reglas actuales. Si el bloqueo funciona solo después de esto, tus reglas estaban bien; tu prueba no lo estaba.

Decisión: Ajusta tu método de validación y considera si necesitas resets/drops explícitos para flujos establecidos durante eventos de seguridad.

Task 17: Verificar que el enrutamiento de políticas / VRFs no esté evitando la interfaz esperada

cr0x@server:~$ ip rule show
0:	from all lookup local
32766:	from all lookup main
32767:	from all lookup default

Qué significa: Si tienes reglas adicionales aquí, el tráfico puede tomar una ruta de salida distinta a la que esperas, lo que cambia qué reglas de firewall son relevantes (especialmente para OUTPUT y FORWARD).

Decisión: Si existe enrutamiento por políticas, asegúrate de que las reglas de firewall coincidan con la ruta real, no con el diagrama en la presentación de alguien.

Tres mini-historias del mundo corporativo (anonimizadas, precisas, algo dolorosas)

Mini-historia 1: El incidente causado por una suposición equivocada

Una empresa mediana operaba un clúster Proxmox que soportaba herramientas internas: runners de CI, almacenamiento de artefactos y un puñado de VMs “temporales” que habían sido temporales desde el año fiscal anterior. Una revisión de seguridad señaló que varias VMs eran alcanzables en puertos que no deberían. El equipo de infra respondió rápido: habilitar el firewall de Proxmox a nivel de datacenter, aplicar un deny por defecto entrante a la subred de VMs y luego abrir agujeros para SSH desde el jump box.

Probaron ejecutando iptables -S y vieron las cadenas esperadas. Perfecto. Hicieron un escaneo de puertos y seguían viendo puertos abiertos. No tan perfecto. La conclusión, entregada con plena confianza, fue que el firewall de Proxmox “no funciona de forma fiable” y el cambio se revirtió.

La suposición equivocada: estaban leyendo reglas de iptables-legacy, mientras el filtrado real vivía en nftables. El host había sido actualizado en sitio. Algunos scripts antiguos estaban anclados a herramientas legacy, y con el tiempo el nodo había derivado a un cerebro dividido: las tablas legacy contenían las reglas “correctas”, nftables era básicamente permisivo y el tráfico en vivo seguía los hooks de nftables. Su “verificación” solo verificó un lenguaje muerto.

Una vez estandarizaron las alternativas a iptables-nft, deshabilitaron scripts legacy y forzaron que pve-firewall reaplicara, el firewall se comportó perfectamente—porque en realidad había estado bien todo el tiempo. El incidente no fue “el firewall de Proxmox es inestable.” El incidente fue “estábamos mirando el plano de control equivocado y luego confiamos en nosotros mismos.”

La solución duradera fue aburrida: una comprobación de bootstrap de nodo que hace fallar el build si las alternativas de iptables difieren a través del clúster. Esa única barrera evitó el mismo drama en la siguiente ventana de actualización.

Mini-historia 2: La optimización que salió mal

Otra organización gestionaba entornos multi-tenant de desarrollo en Proxmox. Querían “aplicar el firewall más rápido” porque los desarrolladores se quejaban de que aprovisionar una VM tardaba demasiado. Alguien notó que pve-firewall reaplicaba muchas reglas con frecuencia, especialmente con churn de configuración frecuente. La “optimización”: introducir una configuración base de nftables con flush ruleset y una lista mínima de permitidos, luego dejar que Proxmox agregara sus propias tablas después.

En laboratorio parecía limpio. En producción creó una carrera: nftables.service recargaba durante eventos de red y borraba el ruleset. Proxmox volvía a aplicar eventualmente, pero “eventualmente” no es un control de seguridad. Entre el flush y el reapply, las VMs quedaron brevemente expuestas. No por horas, pero lo suficiente para que los logs fueran feos y los auditores tuvieran opiniones.

El problema no fue solo el flush. Fue la existencia de dos autoridades compitiendo sobre el mismo objeto del kernel. nftables.service creía que era dueño de la verdad. Proxmox creía que era dueño de la verdad. El kernel ejecutó la verdad que se escribió por última vez.

El equipo volvió a un modelo de propietario único: Proxmox genera el estado del firewall; nftables.service está deshabilitado; cualquier endurecimiento base del host se expresa como reglas de datacenter/nodo de Proxmox. “Aplicación rápida” se logró reduciendo el churn de reglas innecesarias (menos micro-reglas por VM, más uso de sets y grupos) en lugar de construir un segundo plano de control.

La lección: si tu optimización depende de vaciar un ruleset en vivo, no optimizaste; introdujiste apuestas con pasos extra.

Mini-historia 3: La práctica aburrida pero correcta que salvó el día

Una empresa regulada operaba tres clústeres Proxmox con roles idénticos. Tenían una política de cambios: antes de habilitar el firewall globalmente, lo desplegaban en modo “solo registro”, validaban contadores y luego imponían. La gente se quejaba de que era lento y burocrático. También fue exactamente la razón por la que el despliegue no se convirtió en un incidente nocturno.

En staging notaron algo sutil: el tráfico VM-a-VM en el mismo puente no estaba alcanzando la ruta de filtro esperada en un clúster. Los contadores no se movían. Los logs no mostraban drops. Las reglas estaban ahí—pero eran irrelevantes.

Porque midieron antes de imponer, encontraron que los sysctls de br_netfilter estaban desactivados en ese clúster. Un perfil de tuning del kernel bienintencionado había deshabilitado netfilter de puente años atrás para “reducir overhead”. La reducción de overhead era real. También lo era la omisión de seguridad.

Arreglaron los sysctls, confirmaron que los contadores incrementaban para tráfico de prueba y luego procedieron con la imposición. Sin sorpresas, sin “por qué está todo caído” y sin excepciones de emergencia que perduran. La práctica aburrida—instrumentar primero, imponer después—les ahorró enviar un firewall placebo.

Errores comunes: síntoma → causa raíz → solución

  • Síntoma: La GUI de Proxmox muestra el firewall habilitado; el tráfico no se bloquea.
    Causa raíz: Reglas aplicadas en nftables pero las inspeccionas con iptables-legacy (o viceversa).
    Solución: Estandariza las alternativas (se recomienda iptables-nft), luego reinicia pve-firewall y valida con nft list ruleset.
  • Síntoma: Las reglas se aplican y luego desaparecen después de minutos o tras recargar la red.
    Causa raíz: nftables.service carga /etc/nftables.conf con flush ruleset, u otro gestor reescribe tablas.
    Solución: Deshabilita el servicio competidor o elimina el comportamiento de flush/replace; elige un único propietario del ruleset.
  • Síntoma: Las reglas de VM no afectan tráfico VM-a-VM en el mismo puente.
    Causa raíz: Sysctls de bridge netfilter deshabilitados (net.bridge.bridge-nf-call-iptables=0).
    Solución: Habilita br_netfilter y los sysctls persistentes; vuelve a probar con contadores/logging.
  • Síntoma: “Bloqueé el puerto X, pero mi sesión sigue abierta.”
    Causa raíz: Conntrack permite flujos establecidos; tu regla afecta solo conexiones nuevas.
    Solución: Prueba con conexiones nuevas, o vacía entradas específicas de conntrack, o ajusta el orden de reglas si debes matar flujos establecidos.
  • Síntoma: Solo un nodo del clúster aplica reglas; otros no.
    Causa raíz: Deriva de nodo: alternativas diferentes (legacy vs nft), sysctls distintos, servicios habilitados distintos.
    Solución: Compara nodos: alternativas, sysctls, módulos cargados, servicios habilitados; estandariza vía gestión de configuración.
  • Síntoma: NAT/forwarding se comportan distinto tras habilitar el firewall.
    Causa raíz: Mescla de tablas NAT iptables/nft; docker u otros insertan reglas NAT; diferencias de orden.
    Solución: Consolida la propiedad de NAT; inspecciona la tabla nat de nft y asegúrate de que las reglas de Proxmox no conflijan con runtimes de contenedores.
  • Síntoma: El acceso de gestión del host queda bloqueado inesperadamente.
    Causa raíz: Aplicar un “deny inbound” a nivel de datacenter sin allow explícito para SSH/GUI/clúster/almacenamiento, o aplicarlo en la interfaz equivocada.
    Solución: Siempre desplegar en modo solo-logs; añade allows explícitos para el plano de gestión primero; valida los bindings de interfaz.
  • Síntoma: Los logs del firewall muestran drops, pero el tráfico sigue pasando.
    Causa raíz: Estás registrando una ruta (por ejemplo INPUT) mientras el tráfico circula por FORWARD/puente, o el camino IPv6 es distinto.
    Solución: Identifica el hook real con interfaz y dirección; revisa reglas de la familia inet; asegúrate de incluir IPv6 si se usa.

Listas de verificación / plan paso a paso

Checklist A: Estandarizar un nodo Proxmox a un solo backend de firewall

  1. Elige tu backend: en Proxmox/Debian modernos, elige iptables-nft/nftables a menos que un requisito del proveedor obligue legacy.
  2. Revisa alternativas para iptables/ip6tables/ebtables/arptables.
  3. Elimina o deshabilita scripts exclusivos legacy que llamen a iptables-legacy.
  4. Deshabilita gestores de firewall competidores (ufw/firewalld) a menos que los integres deliberadamente.
  5. Reinicia pve-firewall y verifica las reglas activas vía nft.

Checklist B: Validar que el tráfico de VM golpea realmente netfilter

  1. Confirma ruta de puente: el tráfico usa vmbrX y dispositivos tap/veth que esperas.
  2. Asegura que el módulo br_netfilter esté cargado.
  3. Habilita sysctls de puente para iptables/ip6tables si dependes de filtrado a nivel host para tráfico bridged.
  4. Usa contadores/reglas de log para demostrar que los paquetes hacen match.

Checklist C: Probar cambios de firewall sin engañarte

  1. Usa una nueva conexión TCP (puerto de origen nuevo) o un cliente distinto.
  2. Revisa contadores para la regla/cadena específica.
  3. Si es necesario, elimina entradas específicas de conntrack para pruebas limpias.
  4. Valida comportamiento tanto IPv4 como IPv6; “funciona en v4” no es igual a “es seguro”.

Plan de remediación paso a paso (el que ejecutaría en producción)

  1. Congelar escritores de reglas: parar/ deshabilitar temporalmente gestores no-Proxmox (nftables.service, ufw, firewalld) para evitar churn mientras diagnosticas.
  2. Confirmar backend: comprobar update-alternatives --display iptables y acordar nft vs legacy en todos los nodos.
  3. Inspeccionar el ruleset activo: usar nft list ruleset y asegurar que las estructuras generadas por Proxmox aparecen y los contadores incrementan bajo prueba.
  4. Corregir visibilidad de puentes: asegurar que br_netfilter + sysctls están alineados con tu modelo de filtrado.
  5. Rehabilitar solo lo necesario: permitir que Proxmox sea el propietario del estado del firewall; reintroducir otras herramientas solo si son estrictamente necesarias y no solapan.
  6. Fijar consistencia: codifica alternativas/sysctls/servicios en gestión de configuración; añade una comprobación de deriva en la validación de salud del nodo.

Preguntas frecuentes

1) ¿Por qué las reglas del firewall de Proxmox “no se aplican” aunque la GUI diga habilitado?

Porque la GUI es una interfaz de configuración, no el kernel. La causa más común es desajuste de backend: las reglas se aplican a nftables mientras inspeccionas iptables legacy, o bien otro servicio hace flush/overwrite de reglas después de que Proxmox las aplica.

2) ¿Es nftables mejor que iptables para Proxmox?

En 2025: sí, operativamente, porque es el predeterminado moderno en sistemas basados en Debian y evita la deriva de tooling legacy. La respuesta equivocada es “ambos”, a menos que disfrutes depurar pilas de reglas con cerebro dividido.

3) ¿Pueden iptables y nftables ejecutarse al mismo tiempo?

Desgraciadamente, sí. Puedes tener reglas de iptables-legacy y reglas de nftables simultáneamente. Así es como obtienes “veo la regla pero no funciona”. Elige un backend y estandariza.

4) ¿Cómo sé si iptables está usando nftables por debajo?

Usa update-alternatives --display iptables. Si apunta a /usr/sbin/iptables-nft, tus comandos iptables están programando reglas compatibles con nftables.

5) Mi tráfico VM-a-VM no se filtra. ¿Está roto el firewall de Proxmox?

Usualmente no. VM-a-VM en el mismo puente es comportamiento de switching L2. Si los sysctls de bridge netfilter están deshabilitados, netfilter no verá esos paquetes. Habilita br_netfilter y los sysctls relevantes si tu modelo de seguridad depende del filtrado en el host.

6) ¿Por qué bloquear un puerto no desconectó sesiones existentes?

Conntrack. Muchas reglas aceptan established,related temprano por rendimiento y estabilidad. Tu nuevo bloqueo afecta conexiones nuevas. Prueba con una conexión nueva o elimina la entrada específica de conntrack si necesitas validación limpia.

7) ¿Debería ejecutar nftables.service en un host Proxmox?

Si Proxmox firewall es tu gestor autoritativo, típicamente no. Ejecutar nftables.service con una configuración que hace flush o reemplaza reglas entrará en conflicto. Si debes ejecutarlo, asegúrate de que no borre ni sobrescriba tablas gestionadas por Proxmox y de que el orden de inicio sea determinista.

8) ¿Por qué funciona en un nodo pero no en otro del mismo clúster?

La configuración del clúster puede ser idéntica mientras que el estado local del nodo difiere: selección de alternativas, servicios habilitados, sysctls, módulos del kernel o agentes de terceros. Compara configuraciones locales del nodo; no asumas que el clúster uniformiza todo.

9) ¿Necesito preocuparme por IPv6 si mi red es “solo IPv4”?

Si IPv6 está habilitado en interfaces, servicios pueden enlazarse en IPv6 y volverse alcanzables. Maneja reglas IPv6 explícitamente (preferible) o deshabilita IPv6 de forma deliberada y consistente. “No usamos IPv6” suele ser “no monitoreamos IPv6”.

Conclusión: próximos pasos que realmente funcionan

Cuando las reglas del firewall de Proxmox no se aplican, trátalo como cualquier otro problema de fiabilidad en producción: establece el plano de control real, confirma la propiedad y demuestra la ruta de paquete con contadores—no con sensaciones.

Pasos prácticos siguientes:

  1. Decide tu backend de firewall (nftables/iptables-nft es la opción sensata por defecto) y estandariza update-alternatives en todos los nodos.
  2. Haz de Proxmox la única fuente de verdad para el filtrado host/VM, a menos que tengas una razón cuidadosamente diseñada para dividir la propiedad.
  3. Audita y elimina churn de reglas: deshabilita nftables.service/ufw/firewalld en hosts PVE salvo que estén integrados; vigila inserciones de reglas por docker/kube.
  4. Valida el comportamiento de puentes con los sysctls de br_netfilter y contadores reales, especialmente para tráfico VM-a-VM.
  5. Mejora tus pruebas: conexiones nuevas, conciencia de conntrack y verificación explícita de IPv4/IPv6.

Haz esto una vez, escríbelo y tu yo futuro no tendrá que “redescubrir” la diferencia entre que una regla exista y que una regla se haga cumplir.

← Anterior
3dfx Voodoo: la tarjeta que popularizó el 3D
Siguiente →
GPU de Docker en contenedores: por qué falla y cómo solucionarlo

Deja un comentario