Una introducción a Firewalld: Gestión dinámica de firewall en Linux
Firewalld es un demonio de gestión de firewall en espacio de usuario para Linux que proporciona una interfaz dinámica basada en zonas sobre los backends de filtrado de paquetes a nivel de kernel iptables y nftables. A diferencia de las herramientas de firewall estáticas que requieren un reinicio completo del servicio para aplicar cambios de reglas, Firewalld modifica las reglas de netfilter sobre la marcha, preservando las sesiones TCP activas y eliminando el tiempo de inactividad durante las actualizaciones de políticas.
Esta guía cubre cada capa operativa de Firewalld: su modelo arquitectónico, abstracciones de zonas y servicios, reglas enriquecidas, configuración en tiempo de ejecución versus permanente, y los comandos exactos que necesita para gestionar un servidor de producción de forma segura.
Por qué Firewalld reemplazó los flujos de trabajo estáticos de iptables
La gestión tradicional de iptables implica escribir reglas en scripts de shell o archivos de configuración planos, luego vaciar y recargar todo el conjunto de reglas cada vez que se necesita un cambio. En un servidor ocupado, ese ciclo de vaciado y recarga interrumpe las conexiones en curso e introduce una breve ventana en la que no hay filtrado activo.
Firewalld resuelve esto mediante un demonio activado por D-Bus (firewalld) que mantiene el estado autorizado de las reglas y comunica los cambios al kernel de forma incremental. El resultado son actualizaciones atómicas de reglas sin interrupción de conexiones, algo crítico para cualquier servidor que ejecute cargas de trabajo persistentes como bases de datos, túneles VPN o conexiones API de larga duración.
Cuando aprovisiona un entorno de VPS Hosting y necesita reforzarlo sin reiniciar ni interrumpir servicios, Firewalld es la opción operativa natural en distribuciones de la familia RHEL y muchas de la familia Debian.
Arquitectura central: cómo Firewalld interactúa con el kernel
Comprender la pila subyacente de Firewalld previene configuraciones incorrectas y ayuda a depurar comportamientos inesperados.
User Space
┌─────────────────────────────────────────────┐
│ firewall-cmd / firewall-config / D-Bus API │
└────────────────────┬────────────────────────┘
│ D-Bus
┌────────────────────▼────────────────────────┐
│ firewalld daemon │
│ (zone engine, service definitions, rich │
│ rule parser, direct rule passthrough) │
└────────────────────┬────────────────────────┘
│ nftables / iptables backend
Kernel Space
┌────────────────────▼────────────────────────┐
│ netfilter (kernel module) │
└─────────────────────────────────────────────┘Desde RHEL 8 y Fedora 32, Firewalld utiliza por defecto el backend nftables. En sistemas más antiguos o entornos configurados explícitamente, utiliza el backend iptables. Puede inspeccionar o anular el backend activo en /etc/firewalld/firewalld.conf mediante la directiva FirewallBackend.
Trampa crítica: Nunca mezcle comandos directos de iptables o nft con Firewalld en la misma interfaz. Firewalld es propietario de las tablas de netfilter que crea; las reglas manuales insertadas fuera del demonio serán sobrescritas silenciosamente en la próxima recarga.
Conceptos clave en Firewalld
Zonas
Una zona es un nivel de confianza con nombre aplicado a una interfaz de red o rango de direcciones de origen. Cada paquete que entra al sistema se compara con la zona asignada a su interfaz de entrada, y el conjunto de reglas de la zona determina lo que está permitido.
Firewalld incluye las siguientes zonas predefinidas, ordenadas de mayor a menor permisividad:
| Zona | Política predeterminada | Caso de uso típico |
|---|---|---|
| — | — | — |
| `trusted` | Aceptar todo | Redes de laboratorio internas, loopback |
| `home` | Rechazar, servicios seleccionados permitidos | LAN doméstica con dispositivos conocidos |
| `internal` | Rechazar, servicios seleccionados permitidos | Segmento de red corporativa interna |
| `work` | Rechazar, servicios seleccionados permitidos | Red de oficina, confianza moderada |
| `public` | Rechazar, SSH/DHCPv6 permitidos | Interfaces orientadas a Internet |
| `external` | Rechazar, enmascaramiento habilitado | Pata externa de router/gateway NAT |
| `dmz` | Rechazar, SSH permitido | Servidores en zona desmilitarizada |
| `block` | Rechazar con ICMP admin-prohibited | Rechazo explícito con respuesta |
| `drop` | Descartar silenciosamente | Fuentes hostiles, máximo sigilo |
Matiz arquitectónico: Una zona puede estar vinculada a una interfaz de red (p. ej., eth0) o a un CIDR de origen (p. ej., 192.168.1.0/24). El enlace basado en origen tiene precedencia sobre el enlace basado en interfaz, lo que permite aplicar diferentes políticas al tráfico que llega por la misma interfaz física desde diferentes subredes, un patrón común en entornos multi-tenant o en contenedores.
Servicios
Un servicio en Firewalld es un archivo de definición XML almacenado en /usr/lib/firewalld/services/ (valores predeterminados del sistema) o /etc/firewalld/services/ (anulaciones del usuario). Cada archivo declara los puertos, protocolos y módulos auxiliares opcionales requeridos para una aplicación con nombre.
Por ejemplo, la definición del servicio https abre el puerto TCP 443 y no carga módulos auxiliares adicionales del kernel. El servicio ftp abre el puerto TCP 21 y carga el auxiliar nf_conntrack_ftp para gestionar la negociación de puertos dinámicos del canal de datos FTP.
Usar nombres de servicios en lugar de números de puerto sin procesar hace que su política de firewall sea autodocumentada y reduce el riesgo de errores tipográficos que dejen un puerto abierto o cerrado involuntariamente.
Para listar todas las definiciones de servicios disponibles en su sistema:
firewall-cmd --get-servicesPara inspeccionar la definición XML de un servicio específico:
cat /usr/lib/firewalld/services/https.xmlReglas enriquecidas
Las reglas enriquecidas amplían el modelo de zonas con lógica condicional que la abstracción simple de servicio/puerto no puede expresar. Admiten coincidencias en direcciones de origen y destino, rangos de puertos, protocolos, ventanas de tiempo y estado de conexión, y pueden desencadenar acciones que incluyen accept, drop, reject, log y audit.
La sintaxis de las reglas enriquecidas sigue una gramática estructurada:
rule [family="ipv4|ipv6"]
[source address="addr[/mask]" [invert="true"]]
[destination address="addr[/mask]" [invert="true"]]
[service name="service-name"] | [port port="port" protocol="tcp|udp"]
[log [prefix="prefix"] [level="level"] [limit value="rate/duration"]]
[audit]
[accept|drop|reject [type="reject-type"]]Un ejemplo práctico: limitar la tasa de intentos de inicio de sesión SSH a 3 por minuto desde cualquier origen IPv4 único, luego registrar y descartar el exceso:
firewall-cmd --zone=public --add-rich-rule='
rule family="ipv4"
service name="ssh"
log prefix="SSH_RATELIMIT " level="warning" limit value="3/m"
accept' --permanentfirewall-cmd --zone=public --add-rich-rule='
rule family="ipv4"
service name="ssh"
drop' --permanentCaso límite: El orden de las reglas enriquecidas importa. Firewalld evalúa las reglas enriquecidas en el orden en que fueron añadidas dentro de una zona. Si añade una regla drop amplia antes que una regla accept específica, el accept nunca se alcanzará. Añada siempre primero las reglas más específicas.
Configuración en tiempo de ejecución vs. permanente
Esta es la distinción operativamente más importante en Firewalld y la fuente de los errores de producción más comunes.
| Dimensión | Tiempo de ejecución | Permanente |
|---|---|---|
| — | — | — |
| Ubicación de almacenamiento | En memoria (estado del demonio) | Archivos XML en `/etc/firewalld/` |
| Cuándo se aplica | Inmediatamente | Tras `–reload` o reinicio |
| Sobrevive al reinicio | No | Sí |
| Seguro para pruebas | Sí | Requiere recarga para verificar |
| Riesgo | Se pierde al reiniciar | Persiste entre reinicios |
Flujo de trabajo recomendado para cambios en producción:
- Aplique la regla solo en tiempo de ejecución (sin el indicador
--permanent) y verifique que se comporta como se espera. - Si es correcto, aplique la misma regla con
--permanentpara escribirla en disco. - Ejecute
firewall-cmd --reloadpara sincronizar la configuración permanente en el estado en tiempo de ejecución y confirmar la paridad.
Este flujo de trabajo previene el escenario clásico en el que un administrador añade una regla --permanent, recarga y descubre que se ha bloqueado el acceso SSH, porque la prueba en tiempo de ejecución habría revelado el problema antes de que se volviera permanente.
Instalación y habilitación de Firewalld
Firewalld está instalado por defecto en RHEL, CentOS Stream, Fedora, AlmaLinux y Rocky Linux. En Debian y Ubuntu debe instalarse explícitamente.
RHEL / CentOS Stream / AlmaLinux / Rocky Linux:
sudo dnf install firewalldDebian / Ubuntu:
sudo apt-get update && sudo apt-get install firewalldNota para usuarios de Ubuntu: Si ufw está activo, desactívelo antes de habilitar Firewalld para evitar conflictos en las reglas de netfilter:
sudo ufw disable
sudo systemctl disable ufwInicie y habilite el demonio:
sudo systemctl start firewalld
sudo systemctl enable firewalldVerifique que el demonio está en ejecución y el backend del kernel está activo:
sudo firewall-cmd --state
sudo firewall-cmd --info-zone=publicComandos esenciales de Firewalld
Inspeccionar el estado actual
Verificar el estado del demonio:
sudo firewall-cmd --stateListar todas las zonas activas con sus interfaces y fuentes asignadas:
sudo firewall-cmd --get-active-zonesMostrar el conjunto de reglas completo para una zona específica:
sudo firewall-cmd --zone=public --list-allMostrar el conjunto de reglas completo para todas las zonas simultáneamente:
sudo firewall-cmd --list-all-zonesGestionar la zona predeterminada
La zona predeterminada se aplica a cualquier interfaz no asignada explícitamente a otra zona:
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --set-default-zone=publicAsignar una interfaz a una zona
sudo firewall-cmd --zone=internal --change-interface=eth1 --permanent
sudo firewall-cmd --reloadTrampa: En sistemas que usan NetworkManager, las asignaciones de interfaz a zona realizadas mediante firewall-cmd pueden ser anuladas por el perfil de conexión de NetworkManager al reconectarse. Establezca la zona de forma persistente en la conexión de NetworkManager:
nmcli connection modify "Wired connection 1" connection.zone internalAñadir y eliminar servicios
Permitir HTTP en la zona pública en tiempo de ejecución:
sudo firewall-cmd --zone=public --add-service=httpHacerlo permanente:
sudo firewall-cmd --zone=public --add-service=http --permanentEliminar un servicio:
sudo firewall-cmd --zone=public --remove-service=http --permanentAbrir y cerrar puertos específicos
Abrir el puerto TCP 8080 en tiempo de ejecución:
sudo firewall-cmd --zone=public --add-port=8080/tcpAbrir un rango de puertos UDP de forma permanente:
sudo firewall-cmd --zone=public --add-port=60000-61000/udp --permanentEliminar un puerto:
sudo firewall-cmd --zone=public --remove-port=8080/tcp --permanentLista de permitidos y bloqueados de direcciones IP
Permitir todo el tráfico desde una subred de gestión de confianza:
sudo firewall-cmd --zone=trusted --add-source=10.0.0.0/24 --permanentBloquear todo el tráfico desde una IP específica (descarte basado en origen):
sudo firewall-cmd --zone=drop --add-source=203.0.113.45/32 --permanentReenvío de puertos
Reenviar el puerto TCP externo 2222 al puerto SSH interno 22 (útil para ocultar el puerto SSH predeterminado sin cambiar sshd_config):
sudo firewall-cmd --zone=public --add-forward-port=port=2222:proto=tcp:toport=22 --permanent
sudo firewall-cmd --reloadEnmascaramiento IP (NAT)
Habilitar el enmascaramiento en la zona externa para permitir que un VPS que actúa como gateway aplique NAT al tráfico de una subred privada:
sudo firewall-cmd --zone=external --add-masquerade --permanent
sudo firewall-cmd --reloadRecargar y sincronizar la configuración
Aplicar todos los cambios permanentes al estado en ejecución sin interrumpir conexiones:
sudo firewall-cmd --reloadRealizar un reinicio completo (interrumpe todas las conexiones; úselo solo en emergencias):
sudo systemctl restart firewalldCreación de zonas y definiciones de servicios personalizados
Zona personalizada
sudo firewall-cmd --new-zone=management --permanent
sudo firewall-cmd --zone=management --add-source=10.10.0.0/16 --permanent
sudo firewall-cmd --zone=management --add-service=ssh --permanent
sudo firewall-cmd --zone=management --add-service=cockpit --permanent
sudo firewall-cmd --reloadDefinición de servicio personalizado
Crear un archivo de servicio para una aplicación personalizada que escucha en TCP 9200 (p. ej., Elasticsearch):
sudo nano /etc/firewalld/services/elasticsearch.xml<?xml version="1.0" encoding="utf-8"?>
<service>
<short>Elasticsearch</short>
<description>Elasticsearch HTTP API and transport port</description>
<port protocol="tcp" port="9200"/>
<port protocol="tcp" port="9300"/>
</service>sudo firewall-cmd --reload
sudo firewall-cmd --zone=internal --add-service=elasticsearch --permanent
sudo firewall-cmd --reloadFirewalld vs. alternativas: elegir la herramienta adecuada
| Característica | Firewalld | UFW | iptables (directo) | nftables (directo) |
|---|---|---|---|---|
| — | — | — | — | — |
| Actualizaciones dinámicas de reglas | Sí | No (requiere recarga) | No | No |
| Modelo basado en zonas | Sí | No | No | No |
| Integración D-Bus / API | Sí | No | No | No |
| Reglas enriquecidas / lógica condicional | Sí | Limitado | Sí | Sí |
| Predeterminado en familia RHEL | Sí | No | Heredado | Sí (backend) |
| Predeterminado en Ubuntu | No | Sí | Heredado | Sí (backend) |
| Curva de aprendizaje | Moderada | Baja | Alta | Alta |
| Adecuado para scripting | Sí | Sí | Sí | Sí |
| Herramienta de gestión con GUI | Sí (firewall-config) | No | No | No |
Para equipos que gestionan Servidores Dedicados a escala, la API D-Bus de Firewalld permite la gestión programática de reglas desde herramientas de gestión de configuración como Ansible (módulo ansible.posix.firewalld) o Puppet, lo que supone una ventaja operativa significativa frente al mantenimiento de scripts iptables sin procesar.
Patrones prácticos de refuerzo de seguridad
Reforzar un servidor web
Una configuración típica para un servidor que ejecuta HTTPS con SSH restringido a una IP de gestión:
# Set the default zone
sudo firewall-cmd --set-default-zone=public --permanent
# Allow HTTPS globally
sudo firewall-cmd --zone=public --add-service=https --permanent
# Allow HTTP only to redirect to HTTPS (optional)
sudo firewall-cmd --zone=public --add-service=http --permanent
# Restrict SSH to a specific management IP only
sudo firewall-cmd --zone=public --remove-service=ssh --permanent
sudo firewall-cmd --zone=public --add-rich-rule='
rule family="ipv4"
service name="ssh"
source address="198.51.100.10/32"
accept' --permanent
sudo firewall-cmd --reloadSi está ejecutando un servidor web junto con un despliegue de Certificados SSL, asegurarse de que el puerto 443 esté abierto en la zona correcta antes de la emisión del certificado (especialmente para los desafíos ACME HTTP-01 o TLS-ALPN-01) es un paso previo que se pasa por alto con frecuencia.
Proteger un servidor de correo
Para servidores que ejecutan pilas de Alojamiento de Correo Electrónico (Postfix, Dovecot), el conjunto de servicios requerido es:
sudo firewall-cmd --zone=public --add-service=smtp --permanent
sudo firewall-cmd --zone=public --add-service=smtps --permanent
sudo firewall-cmd --zone=public --add-service=imap --permanent
sudo firewall-cmd --zone=public --add-service=imaps --permanent
sudo firewall-cmd --zone=public --add-service=pop3s --permanent
sudo firewall-cmd --reloadRegistrar paquetes descartados para análisis forense
sudo firewall-cmd --zone=public --add-rich-rule='
rule family="ipv4"
log prefix="DROPPED_PUBLIC " level="warning" limit value="10/m"
drop' --permanent
sudo firewall-cmd --reloadLos registros aparecen en /var/log/messages o en el diario de systemd (journalctl -k -g DROPPED_PUBLIC). Limite la tasa de registro (como se muestra arriba) para evitar la saturación de registros en un escenario de DDoS.
Firewalld en un VPS gestionado con cPanel
Si está utilizando un VPS con cPanel, tenga en cuenta que cPanel instala y gestiona su propia capa de firewall (CSF/LFD por defecto). Ejecutar Firewalld junto con CSF sin coordinación explícita producirá reglas de netfilter en conflicto. El enfoque recomendado es elegir una capa de gestión de firewall por servidor y deshabilitar la otra, o utilizar la interfaz de paso directo de reglas de Firewalld para integrarse con los requisitos de cPanel.
Solución de problemas comunes de Firewalld
Problema: La regla añadida con --permanent no está en vigor.
Causa: Las reglas permanentes requieren una recarga para entrar en el estado en tiempo de ejecución.
Solución:
sudo firewall-cmd --reloadProblema: La conexión SSH se interrumpió tras el cambio de firewall.
Causa: El servicio SSH fue eliminado de la zona activa, o se añadió una regla enriquecida drop antes de la regla accept.
Solución: Acceda al servidor mediante la consola fuera de banda (la consola VNC/KVM de su proveedor de alojamiento) y restaure el servicio SSH:
sudo firewall-cmd --zone=public --add-service=ssh --permanent
sudo firewall-cmd --reloadProblema: firewall-cmd devuelve FirewallD is not running.
Causa: El demonio se bloqueó o nunca se inició.
Solución:
sudo systemctl start firewalld
sudo journalctl -u firewalld -n 50Problema: Las reglas parecen correctas pero el tráfico sigue bloqueado.
Causa: Existe una regla iptables o nft en conflicto fuera de las tablas gestionadas por Firewalld, o SELinux/AppArmor está bloqueando la conexión en la capa de aplicación.
Solución: Compruebe las reglas manuales y las denegaciones de SELinux:
sudo iptables -L -n -v
sudo ausearch -m avc -ts recentProblema: La interfaz no está asignada a la zona esperada tras el reinicio.
Causa: El perfil de conexión de NetworkManager anula la asignación de interfaz de Firewalld.
Solución: Establezca la zona en el perfil de NetworkManager como se describe en la sección de asignación de interfaces anterior.
Matriz de decisión y lista de verificación técnica
Utilice esta lista de verificación antes de desplegar Firewalld en un servidor de producción:
- Confirme que el backend de firewall activo (
FirewallBackenden/etc/firewalld/firewalld.conf) coincide con el soporte de nftables/iptables de su kernel. - Verifique que no hay herramientas de firewall en conflicto (UFW, CSF, scripts
iptablesdirectos) activas en las mismas interfaces. - Asigne cada interfaz de red explícitamente a una zona; nunca dependa únicamente de la zona predeterminada para servidores con múltiples interfaces.
- Aplique todos los cambios en tiempo de ejecución primero, verifique la conectividad y luego confirme con
--permanenty--reload. - Restrinja el acceso SSH a IPs de origen específicas mediante reglas enriquecidas antes de eliminar el servicio SSH de la zona pública.
- Añada reglas enriquecidas de limitación de tasa para todos los servicios de autenticación expuestos públicamente (SSH, SMTP, endpoints de inicio de sesión HTTPS).
- Habilite el registro para la zona
dropcon un límite de tasa para capturar inteligencia de amenazas sin saturar el almacenamiento. - Para servidores gestionados mediante Paneles de Control VPS, confirme que los puertos requeridos por el panel de control están en la lista de permitidos antes de aplicar una política predeterminada restrictiva.
- Pruebe la configuración permanente ejecutando
firewall-cmd --reloady verifique inmediatamente que todos los servicios críticos siguen siendo accesibles. - Documente cada zona personalizada, regla enriquecida y definición de servicio en control de versiones junto con su infraestructura como código.
Preguntas frecuentes
¿Cuál es la diferencia entre --reload y sudo systemctl restart firewalld?
--reload aplica los cambios de configuración permanente al demonio en ejecución sin interrumpir las conexiones establecidas. systemctl restart reinicia completamente el proceso del demonio, lo que vacía todas las reglas de netfilter e interrumpe brevemente las conexiones activas. Prefiera siempre --reload en sistemas de producción.
¿Pueden coexistir Firewalld e iptables en el mismo servidor?
No de forma segura en la misma interfaz. Firewalld gestiona sus propias cadenas de netfilter; los comandos directos de iptables que modifiquen las mismas cadenas serán sobrescritos en la próxima recarga de Firewalld. Si necesita inyectar reglas personalizadas, utilice la interfaz --direct de Firewalld o las reglas enriquecidas en su lugar.
¿Cómo hago permanente una regla en tiempo de ejecución sin volver a escribirla?
No existe un comando integrado para promover todas las reglas en tiempo de ejecución a permanentes en un solo paso. El flujo de trabajo correcto es aplicar cada regla dos veces: una sin --permanent para pruebas, y luego con --permanent para persistencia, seguido de --reload. Alternativamente, use firewall-cmd --runtime-to-permanent (disponible en Firewalld 0.9+) para capturar el estado en tiempo de ejecución actual en disco.
¿Por qué se restablece la asignación de zona tras una reconexión de NetworkManager?
NetworkManager almacena las asignaciones de zona en sus propios perfiles de conexión. Una asignación firewall-cmd --change-interface es una anulación en tiempo de ejecución que NetworkManager puede sobrescribir. Persista la asignación con nmcli connection modify <profile-name> connection.zone <zone>.
¿Firewalld es compatible con IPv6?
Sí. Firewalld gestiona simultáneamente las reglas de netfilter para IPv4 e IPv6. Las reglas enriquecidas requieren el atributo family="ipv6" para dirigirse específicamente al tráfico IPv6. Las reglas de zona y servicio se aplican a ambas familias de direcciones por defecto, a menos que la definición del servicio o la regla enriquecida restrinja el alcance.
