Configuración de Firewall con firewalld (CentOS/Rocky Linux)
Firewalld es la solución predeterminada de gestión dinámica de firewall para distribuciones basadas en Red Hat Enterprise Linux, proporcionando seguridad de red basada en zonas con una interfaz fácil de usar. Esta guía exhaustiva te lleva a través de la configuración de firewalld en sistemas CentOS, Rocky Linux, AlmaLinux y RHEL, cubriendo todo desde configuración básica hasta reglas avanzadas de firewall y fortalecimiento de seguridad.
Tabla de Contenidos
- Prerrequisitos
- Entendiendo Firewalld
- Paso 1: Instalación e Inicio de Firewalld
- Paso 2: Entendiendo las Zonas
- Paso 3: Gestión de Servicios
- Paso 4: Gestión de Puertos
- Paso 5: Trabajando con Reglas Enriquecidas
- Paso 6: Reenvío de Puertos y NAT
- Paso 7: Gestión de Conjuntos de IP
- Paso 8: Reglas Directas e iptables
- Paso 9: Bloqueo de Firewalld
- Paso 10: Configuración Avanzada
- Verificación
- Resolución de Problemas
- Mejores Prácticas
- Conclusión
- Recursos Adicionales
Prerrequisitos
Antes de configurar firewalld, asegúrate de tener:
- CentOS Stream 8/9, Rocky Linux 8/9, AlmaLinux 8/9, o RHEL 8/9
- Acceso root o privilegios sudo
- Acceso SSH o de consola al servidor
- Entendimiento básico de conceptos de redes (TCP/UDP, puertos, protocolos)
- Entendimiento de las interfaces de red de tu servidor
- Lista de servicios/puertos que necesitan ser accesibles
- Método de acceso de respaldo (consola) en caso de mala configuración del firewall
Advertencia crítica: La configuración incorrecta del firewall puede bloquearte fuera de tu servidor. Mantén siempre acceso por consola y prueba las reglas cuidadosamente antes de hacerlas permanentes.
Entendiendo Firewalld
¿Qué es Firewalld?
Firewalld es un firewall gestionado dinámicamente con soporte para zonas de red/firewall que definen niveles de confianza de conexiones o interfaces de red. Proporciona una interfaz D-Bus para gestionar reglas de firewall y soporta tanto IPv4 como IPv6.
Características clave:
- Gestión dinámica: Los cambios pueden hacerse sin reiniciar el servicio
- Basado en zonas: Interfaces de red asignadas a zonas con diferentes niveles de confianza
- Configuraciones runtime y permanentes: Probar reglas antes de hacerlas permanentes
- Definiciones de servicios: Configuraciones predefinidas para servicios comunes
- Lenguaje enriquecido: Sintaxis de reglas avanzada para escenarios complejos
- Integración: Funciona perfectamente con NetworkManager
- Flexibilidad de backend: Usa nftables (predeterminado en RHEL 8+) o iptables
Firewalld vs iptables
Ventajas de Firewalld:
- Nivel más alto, más fácil de gestionar
- Cambios de reglas dinámicos sin reinicio del servicio
- Modelo conceptual basado en zonas
- Definiciones de servicios integradas
- Mejor integración con NetworkManager
Cuándo usar iptables directamente:
- Sistemas legacy (RHEL 6 y anteriores)
- Requisitos personalizados complejos
- Escenarios críticos de rendimiento
- Scripts existentes de iptables
Arquitectura de Firewalld
User Commands
↓
firewall-cmd / GUI
↓
firewalld (daemon)
↓
nftables / iptables (backend)
↓
Netfilter (kernel)
Archivos de configuración:
/etc/firewalld/- Configuraciones de usuario (persistentes)/usr/lib/firewalld/- Predeterminados del sistema (no modificar)/etc/firewalld/firewalld.conf- Configuración principal/etc/firewalld/zones/- Configuraciones de zonas/etc/firewalld/services/- Definiciones de servicios personalizados
Paso 1: Instalación e Inicio de Firewalld
Instalación
Firewalld típicamente viene preinstalado en distribuciones basadas en RHEL.
# Check if firewalld is installed
rpm -q firewalld
# Install firewalld if not present
sudo dnf install firewalld -y
# Install firewall-config GUI (optional)
sudo dnf install firewall-config -y
Iniciando y Habilitando Firewalld
# Start firewalld service
sudo systemctl start firewalld
# Enable firewalld to start at boot
sudo systemctl enable firewalld
# Check firewalld status
sudo systemctl status firewalld
# Verify firewalld is running
sudo firewall-cmd --state
# Should output: running
Información Básica de Estado
# Get firewalld version
firewall-cmd --version
# Display default zone
firewall-cmd --get-default-zone
# List all active zones
firewall-cmd --get-active-zones
# Display all available zones
firewall-cmd --get-zones
# Get current configuration
firewall-cmd --list-all
# Check if firewalld is running
firewall-cmd --state
Entendiendo Configuración Runtime vs Permanente
Firewalld mantiene dos configuraciones:
Configuración runtime:
- Reglas activas en memoria
- Se pierden después de reiniciar firewalld
- Usar para probar antes de hacer permanente
Configuración permanente:
- Almacenada en archivos de configuración
- Aplicada después de recargar firewalld
- Usar flag
--permanentpara persistencia
# Runtime change (temporary, for testing)
sudo firewall-cmd --add-service=http
# Permanent change (survives reboot)
sudo firewall-cmd --permanent --add-service=http
# Reload to apply permanent changes
sudo firewall-cmd --reload
# Make runtime configuration permanent
sudo firewall-cmd --runtime-to-permanent
Paso 2: Entendiendo las Zonas
Las zonas son el concepto central en firewalld, definiendo niveles de confianza para conexiones de red.
Zonas Predeterminadas
Firewalld incluye zonas predefinidas (de más a menos restrictiva):
1. drop
- Paquetes entrantes descartados sin notificación
- Solo conexiones salientes permitidas
- Más restrictiva
2. block
- Entrantes rechazados con icmp-host-prohibited
- Solo conexiones salientes permitidas
3. public (predeterminada)
- Para redes públicas no confiables
- Conexiones entrantes selectivas permitidas
- Recomendada para la mayoría de servidores
4. external
- Para redes externas con masquerading
- Usada para sistemas router/gateway
5. dmz
- Para sistemas DMZ (zona desmilitarizada)
- Acceso público limitado
6. work
- Para redes de trabajo
- Más confianza que public
7. home
- Para redes domésticas
- Confía en la mayoría de sistemas
8. internal
- Para redes internas
- Alto nivel de confianza
9. trusted
- Todas las conexiones aceptadas
- Menos restrictiva (usar con cuidado)
Trabajando con Zonas
# List all zones
firewall-cmd --get-zones
# View specific zone configuration
firewall-cmd --zone=public --list-all
# View all zones configuration
firewall-cmd --list-all-zones
# Get default zone
firewall-cmd --get-default-zone
# Set default zone
sudo firewall-cmd --set-default-zone=public
# Get active zones (zones with interfaces assigned)
firewall-cmd --get-active-zones
Asignando Interfaces a Zonas
# List network interfaces
ip addr show
# Get zone of specific interface
firewall-cmd --get-zone-of-interface=eth0
# Assign interface to zone (runtime)
sudo firewall-cmd --zone=public --add-interface=eth0
# Assign interface to zone (permanent)
sudo firewall-cmd --permanent --zone=public --add-interface=eth0
sudo firewall-cmd --reload
# Change interface zone
sudo firewall-cmd --zone=dmz --change-interface=eth0
# Remove interface from zone
sudo firewall-cmd --zone=public --remove-interface=eth0
Creando Zonas Personalizadas
# Create new zone
sudo firewall-cmd --permanent --new-zone=custom_zone
# Set zone description
sudo firewall-cmd --permanent --zone=custom_zone --set-description="Custom security zone"
# Set zone target (default, ACCEPT, REJECT, DROP)
sudo firewall-cmd --permanent --zone=custom_zone --set-target=default
# Add services to custom zone
sudo firewall-cmd --permanent --zone=custom_zone --add-service=ssh
sudo firewall-cmd --permanent --zone=custom_zone --add-service=http
# Reload to apply
sudo firewall-cmd --reload
# Verify custom zone
firewall-cmd --zone=custom_zone --list-all
Archivos de Configuración de Zonas
# View zone configuration file
cat /usr/lib/firewalld/zones/public.xml
# Custom zone configurations
ls -la /etc/firewalld/zones/
# Copy zone for customization
sudo cp /usr/lib/firewalld/zones/public.xml /etc/firewalld/zones/custom.xml
Paso 3: Gestión de Servicios
Firewalld incluye definiciones de servicios predefinidos para aplicaciones comunes.
Listando Servicios
# List all available services
firewall-cmd --get-services
# List services in default zone
firewall-cmd --list-services
# List services in specific zone
firewall-cmd --zone=public --list-services
# View service details
firewall-cmd --info-service=ssh
firewall-cmd --info-service=http
firewall-cmd --info-service=https
Agregando y Eliminando Servicios
# Add service (runtime)
sudo firewall-cmd --add-service=http
sudo firewall-cmd --add-service=https
# Add service (permanent)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
# Add service to specific zone
sudo firewall-cmd --zone=public --add-service=ssh
# Add multiple services at once
sudo firewall-cmd --permanent --add-service={http,https,ssh}
# Remove service
sudo firewall-cmd --remove-service=http
sudo firewall-cmd --permanent --remove-service=http
# Remove service from specific zone
sudo firewall-cmd --zone=public --remove-service=cockpit
Configuraciones Comunes de Servicios
# Web server
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
# SSH (usually already enabled)
sudo firewall-cmd --permanent --add-service=ssh
# Mail server
sudo firewall-cmd --permanent --add-service=smtp
sudo firewall-cmd --permanent --add-service=smtps
sudo firewall-cmd --permanent --add-service=imap
sudo firewall-cmd --permanent --add-service=imaps
# Database servers
sudo firewall-cmd --permanent --add-service=mysql
sudo firewall-cmd --permanent --add-service=postgresql
# DNS server
sudo firewall-cmd --permanent --add-service=dns
# NFS
sudo firewall-cmd --permanent --add-service=nfs
sudo firewall-cmd --permanent --add-service=mountd
sudo firewall-cmd --permanent --add-service=rpc-bind
# FTP
sudo firewall-cmd --permanent --add-service=ftp
# Reload after changes
sudo firewall-cmd --reload
Creando Servicios Personalizados
# Create new service definition
sudo firewall-cmd --permanent --new-service=myapp
# Set service description
sudo firewall-cmd --permanent --service=myapp --set-description="My Application"
# Set short name
sudo firewall-cmd --permanent --service=myapp --set-short="MyApp"
# Add ports to service
sudo firewall-cmd --permanent --service=myapp --add-port=8080/tcp
sudo firewall-cmd --permanent --service=myapp --add-port=8443/tcp
# Add protocol
sudo firewall-cmd --permanent --service=myapp --add-protocol=tcp
# Add source port
sudo firewall-cmd --permanent --service=myapp --add-source-port=5000/tcp
# View service configuration
firewall-cmd --info-service=myapp
# Reload and use service
sudo firewall-cmd --reload
sudo firewall-cmd --add-service=myapp
Formato de archivo de definición de servicio:
# View custom service file
cat /etc/firewalld/services/myapp.xml
Ejemplo XML:
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>MyApp</short>
<description>My Application Service</description>
<port protocol="tcp" port="8080"/>
<port protocol="tcp" port="8443"/>
</service>
Paso 4: Gestión de Puertos
Para servicios sin definiciones predefinidas o configuraciones de puertos personalizados.
Agregando y Eliminando Puertos
# Add single port (runtime)
sudo firewall-cmd --add-port=8080/tcp
# Add single port (permanent)
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload
# Add multiple ports
sudo firewall-cmd --permanent --add-port={80/tcp,443/tcp,8080/tcp}
# Add port range
sudo firewall-cmd --permanent --add-port=8000-9000/tcp
# Add UDP port
sudo firewall-cmd --permanent --add-port=53/udp
# Add to specific zone
sudo firewall-cmd --zone=public --permanent --add-port=3306/tcp
# Remove port
sudo firewall-cmd --permanent --remove-port=8080/tcp
# List open ports
firewall-cmd --list-ports
# List ports in specific zone
firewall-cmd --zone=public --list-ports
Configuraciones Comunes de Puertos
# Web applications
sudo firewall-cmd --permanent --add-port=8080/tcp # Alternative HTTP
sudo firewall-cmd --permanent --add-port=8443/tcp # Alternative HTTPS
sudo firewall-cmd --permanent --add-port=3000/tcp # Node.js default
# Databases
sudo firewall-cmd --permanent --add-port=3306/tcp # MySQL/MariaDB
sudo firewall-cmd --permanent --add-port=5432/tcp # PostgreSQL
sudo firewall-cmd --permanent --add-port=27017/tcp # MongoDB
sudo firewall-cmd --permanent --add-port=6379/tcp # Redis
# Development tools
sudo firewall-cmd --permanent --add-port=9000/tcp # PHP-FPM
sudo firewall-cmd --permanent --add-port=9200/tcp # Elasticsearch
# Monitoring
sudo firewall-cmd --permanent --add-port=9090/tcp # Prometheus
sudo firewall-cmd --permanent --add-port=3000/tcp # Grafana
# Game servers
sudo firewall-cmd --permanent --add-port=25565/tcp # Minecraft
sudo firewall-cmd --permanent --add-port=27015/udp # Source Engine
# Always reload after changes
sudo firewall-cmd --reload
Consulta y Verificación de Puertos
# Check if specific port is open
firewall-cmd --query-port=8080/tcp
# Check service status
firewall-cmd --query-service=http
# List all configuration
firewall-cmd --list-all
Paso 5: Trabajando con Reglas Enriquecidas
Las reglas enriquecidas proporcionan sintaxis avanzada de reglas de firewall para escenarios complejos.
Sintaxis de Reglas Enriquecidas
Estructura básica de regla enriquecida:
rule [family="<ipv4|ipv6>"]
[source [address="<address>"] [invert="true"]]
[destination [address="<address>"] [invert="true"]]
[service name="<service>"]
[port port="<port>" protocol="<tcp|udp>"]
[forward-port port="<port>" protocol="<tcp|udp>" to-port="<port>" to-addr="<address>"]
[log [prefix="<prefix>"] [level="<level>"]]
[audit]
[accept|reject|drop]
Ejemplos Comunes de Reglas Enriquecidas
Permitir IP específica a puerto específico:
# Allow specific IP to SSH
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.50" service name="ssh" accept'
# Allow specific IP to port
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.50" port port="3306" protocol="tcp" accept'
# Allow subnet to service
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="http" accept'
Bloquear IP específica:
# Drop all traffic from IP
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.100" drop'
# Reject with message
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.100" reject'
# Block subnet
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" drop'
Limitación de tasa:
# Limit SSH connections (3 per minute from same IP)
sudo firewall-cmd --permanent --add-rich-rule='rule service name="ssh" limit value="3/m" accept'
# Limit HTTP connections
sudo firewall-cmd --permanent --add-rich-rule='rule service name="http" limit value="100/s" accept'
# Advanced rate limit with burst
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" port port="80" protocol="tcp" limit value="10/s" burst="20" accept'
Logging:
# Log dropped packets
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" log prefix="FIREWALL-BLOCKED: " level="info" drop'
# Log and accept
sudo firewall-cmd --permanent --add-rich-rule='rule service name="ssh" log prefix="SSH-ACCESS: " level="info" accept'
# Log rate limited
sudo firewall-cmd --permanent --add-rich-rule='rule service name="http" log prefix="HTTP: " level="warning" limit value="5/m" accept'
Reglas basadas en tiempo:
Las reglas enriquecidas no soportan tiempo directamente, pero puedes usar cron:
# Create script to enable/disable rule
cat << 'EOF' | sudo tee /usr/local/bin/time-firewall.sh
#!/bin/bash
# Enable rule at 9 AM
if [ "$(date +%H)" -eq 9 ]; then
firewall-cmd --add-rich-rule='rule service name="http" accept'
fi
# Disable rule at 5 PM
if [ "$(date +%H)" -eq 17 ]; then
firewall-cmd --remove-rich-rule='rule service name="http" accept'
fi
EOF
sudo chmod +x /usr/local/bin/time-firewall.sh
Gestionando Reglas Enriquecidas
# List rich rules
firewall-cmd --list-rich-rules
# List rich rules in specific zone
firewall-cmd --zone=public --list-rich-rules
# Remove rich rule
sudo firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="203.0.113.50" service name="ssh" accept'
# Reload to apply permanent rules
sudo firewall-cmd --reload
# Test rule before making permanent
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="203.0.113.50" port port="8080" protocol="tcp" accept'
# If works, make permanent:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.50" port port="8080" protocol="tcp" accept'
Ejemplos Complejos de Reglas Enriquecidas
# Allow SSH only from specific subnet during business hours (via cron)
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'
# Allow HTTP/HTTPS from anywhere, limit connections
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" service name="http" limit value="100/s" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" service name="https" limit value="100/s" accept'
# Database access only from application servers
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.10.10" port port="5432" protocol="tcp" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.10.11" port port="5432" protocol="tcp" accept'
# Log and block suspicious activity
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port port="23" protocol="tcp" log prefix="TELNET-ATTEMPT: " level="warning" reject'
# Reload
sudo firewall-cmd --reload
Paso 6: Reenvío de Puertos y NAT
Habilitando Masquerading (NAT)
# Enable masquerading in zone
sudo firewall-cmd --zone=external --add-masquerade
# Make permanent
sudo firewall-cmd --permanent --zone=external --add-masquerade
# Check if masquerading is enabled
firewall-cmd --zone=external --query-masquerade
# Disable masquerading
sudo firewall-cmd --zone=external --remove-masquerade
Reenvío de Puertos
Reenviar puerto externo a servidor interno:
# Forward port 80 to 8080 on same server
sudo firewall-cmd --zone=external --add-forward-port=port=80:proto=tcp:toport=8080
# Forward to different server
sudo firewall-cmd --zone=external --add-forward-port=port=80:proto=tcp:toport=80:toaddr=192.168.1.10
# Forward HTTPS to internal web server
sudo firewall-cmd --permanent --zone=external --add-forward-port=port=443:proto=tcp:toport=443:toaddr=192.168.1.10
# Forward range of ports
sudo firewall-cmd --permanent --zone=external --add-forward-port=port=8000-8100:proto=tcp:toport=9000-9100:toaddr=192.168.1.20
Reenvío de puertos con reglas enriquecidas:
# Forward with source restriction
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" forward-port port="3389" protocol="tcp" to-port="3389" to-addr="192.168.1.100"'
# Reload
sudo firewall-cmd --reload
Eliminando Reenvío de Puertos
# Remove forward rule
sudo firewall-cmd --zone=external --remove-forward-port=port=80:proto=tcp:toport=8080
# Remove permanent rule
sudo firewall-cmd --permanent --zone=external --remove-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.1.10
# List forward ports
firewall-cmd --zone=external --list-forward-ports
Paso 7: Gestión de Conjuntos de IP
Los conjuntos de IP permiten gestión eficiente de listas grandes de direcciones IP.
Creando y Gestionando Conjuntos de IP
# Create IP set
sudo firewall-cmd --permanent --new-ipset=allowed_ips --type=hash:ip
# Add IPs to set
sudo firewall-cmd --permanent --ipset=allowed_ips --add-entry=203.0.113.10
sudo firewall-cmd --permanent --ipset=allowed_ips --add-entry=203.0.113.20
sudo firewall-cmd --permanent --ipset=allowed_ips --add-entry=203.0.113.30
# Add subnet to IP set
sudo firewall-cmd --permanent --ipset=allowed_ips --add-entry=192.168.1.0/24
# List IP sets
firewall-cmd --get-ipsets
# View IP set entries
firewall-cmd --ipset=allowed_ips --get-entries
# Remove entry from IP set
sudo firewall-cmd --permanent --ipset=allowed_ips --remove-entry=203.0.113.30
# Delete IP set
sudo firewall-cmd --permanent --delete-ipset=allowed_ips
Usando Conjuntos de IP en Reglas
# Allow SSH from IP set
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source ipset="allowed_ips" service name="ssh" accept'
# Block IP set
sudo firewall-cmd --permanent --new-ipset=blocked_ips --type=hash:ip
sudo firewall-cmd --permanent --ipset=blocked_ips --add-entry=10.0.0.100
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source ipset="blocked_ips" drop'
# Reload
sudo firewall-cmd --reload
Conjunto de IP desde Archivo
# Create IP list file
cat << EOF | sudo tee /etc/firewalld/ipsets/whitelist.xml
<?xml version="1.0" encoding="utf-8"?>
<ipset type="hash:ip">
<entry>203.0.113.10</entry>
<entry>203.0.113.20</entry>
<entry>192.168.1.0/24</entry>
</ipset>
EOF
# Reload to load IP set
sudo firewall-cmd --reload
Paso 8: Reglas Directas e iptables
Para usuarios avanzados que necesitan acceso directo a iptables/nftables.
Agregando Reglas Directas
# Add direct rule (iptables syntax)
sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 9999 -j ACCEPT
# Make permanent
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 9999 -j ACCEPT
# List direct rules
firewall-cmd --direct --get-all-rules
# Remove direct rule
sudo firewall-cmd --direct --remove-rule ipv4 filter INPUT 0 -p tcp --dport 9999 -j ACCEPT
Cadenas Directas
# Add custom chain
sudo firewall-cmd --permanent --direct --add-chain ipv4 filter CUSTOM_CHAIN
# Add rule to custom chain
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter CUSTOM_CHAIN 0 -j ACCEPT
# Pass traffic to custom chain
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -j CUSTOM_CHAIN
Advertencia: Las reglas directas evitan la gestión de zonas de firewalld. Usar solo cuando sea necesario.
Paso 9: Bloqueo de Firewalld
El modo de bloqueo previene que aplicaciones no autorizadas cambien reglas de firewall.
Habilitando Bloqueo
# Enable lockdown mode
sudo firewall-cmd --lockdown-on
# Check lockdown status
firewall-cmd --query-lockdown
# Disable lockdown
sudo firewall-cmd --lockdown-off
Configurando Lista Blanca de Bloqueo
# Edit lockdown whitelist
sudo nano /etc/firewalld/lockdown-whitelist.xml
Configuración de ejemplo:
<?xml version="1.0" encoding="utf-8"?>
<whitelist>
<command name="/usr/bin/python3 -s /usr/bin/firewall-config"/>
<command name="/usr/libexec/platform-python -s /usr/sbin/firewall-config"/>
<selinux context="system_u:system_r:NetworkManager_t:s0"/>
<user id="0"/>
<user name="root"/>
</whitelist>
Paso 10: Configuración Avanzada
Modo Pánico
Deshabilitar todo el tráfico de red instantáneamente (uso de emergencia):
# Enable panic mode (drops all traffic)
sudo firewall-cmd --panic-on
# Check panic mode status
firewall-cmd --query-panic
# Disable panic mode
sudo firewall-cmd --panic-off
Gestión de ICMP
# List available ICMP types
firewall-cmd --get-icmptypes
# Block ICMP ping
sudo firewall-cmd --permanent --add-icmp-block=echo-request
# Allow specific ICMP
sudo firewall-cmd --permanent --remove-icmp-block=echo-request
# Block all ICMP except specific types
sudo firewall-cmd --permanent --add-icmp-block-inversion
sudo firewall-cmd --permanent --add-icmp-block=echo-reply
# List blocked ICMP
firewall-cmd --list-icmp-blocks
Protocolos
# Add protocol
sudo firewall-cmd --permanent --add-protocol=igmp
sudo firewall-cmd --permanent --add-protocol=gre
# Remove protocol
sudo firewall-cmd --permanent --remove-protocol=igmp
# List protocols
firewall-cmd --list-protocols
Puertos de Origen
# Add source port
sudo firewall-cmd --permanent --add-source-port=5000/tcp
# Remove source port
sudo firewall-cmd --permanent --remove-source-port=5000/tcp
# List source ports
firewall-cmd --list-source-ports
Módulos Helper
# List available helpers
firewall-cmd --get-helpers
# Add helper
sudo firewall-cmd --permanent --add-helper=ftp
# Remove helper
sudo firewall-cmd --permanent --remove-helper=ftp
# List active helpers
firewall-cmd --list-helpers
Verificación
Verificación Exhaustiva del Estado del Firewall
# Full firewall status
sudo firewall-cmd --list-all
# Check all zones
sudo firewall-cmd --list-all-zones
# Verify service is running
sudo systemctl status firewalld
# Check if specific service is allowed
firewall-cmd --query-service=ssh
# Check if specific port is open
firewall-cmd --query-port=8080/tcp
# View runtime configuration
firewall-cmd --list-all
# View permanent configuration
firewall-cmd --permanent --list-all
Probando Reglas de Firewall
# From external machine, test port access
nc -zv server_ip 80
telnet server_ip 80
nmap server_ip
# Check listening services on server
sudo ss -tlnp
sudo netstat -tlnp
# View active connections
sudo ss -tan
# Monitor firewall logs
sudo journalctl -u firewalld -f
sudo tail -f /var/log/messages | grep -i firewall
Script de Verificación de Firewall
# Create verification script
cat << 'EOF' | sudo tee /usr/local/bin/firewall-status.sh
#!/bin/bash
echo "=== Firewalld Status ==="
echo ""
echo "Service Status:"
systemctl is-active firewalld
echo ""
echo "Default Zone:"
firewall-cmd --get-default-zone
echo ""
echo "Active Zones:"
firewall-cmd --get-active-zones
echo ""
echo "Public Zone Configuration:"
firewall-cmd --zone=public --list-all
echo ""
echo "Open Ports:"
sudo ss -tlnp | grep LISTEN
echo ""
echo "Recent Firewall Logs:"
sudo journalctl -u firewalld -n 20 --no-pager
EOF
sudo chmod +x /usr/local/bin/firewall-status.sh
sudo /usr/local/bin/firewall-status.sh
Resolución de Problemas
Servicio No Accesible Después de Configurar el Firewall
Problema: No se puede acceder al servicio a pesar de las reglas del firewall.
Solución:
# 1. Verify service is running
sudo systemctl status service_name
# 2. Check if service is listening
sudo ss -tlnp | grep :80
# 3. Verify firewall allows service
firewall-cmd --list-services
firewall-cmd --list-ports
# 4. Check if rule is in correct zone
firewall-cmd --get-active-zones
firewall-cmd --zone=public --list-all
# 5. Test from localhost
curl http://localhost
# 6. Check for SELinux denials
sudo ausearch -m AVC -ts recent
# 7. Temporarily disable firewall for testing
sudo systemctl stop firewalld
# Test service
# Re-enable firewall
sudo systemctl start firewalld
Firewalld No Inicia
Problema: El servicio Firewalld falla al iniciar.
Solución:
# Check service status
sudo systemctl status firewalld -l
# View detailed logs
sudo journalctl -u firewalld -n 50 --no-pager
# Check for configuration errors
sudo firewall-cmd --check-config
# Verify no conflicting services
sudo systemctl status iptables
sudo systemctl status nftables
# Reset to default configuration
sudo cp -r /usr/lib/firewalld/* /etc/firewalld/
sudo systemctl restart firewalld
Reglas No Tienen Efecto
Problema: Se agregaron reglas pero no funcionan.
Solución:
# 1. Check if rules are in runtime or permanent
firewall-cmd --list-all # Runtime
firewall-cmd --permanent --list-all # Permanent
# 2. Reload to apply permanent rules
sudo firewall-cmd --reload
# 3. Make runtime rules permanent
sudo firewall-cmd --runtime-to-permanent
# 4. Verify rule syntax for rich rules
firewall-cmd --check-config
# 5. Check zone assignment
firewall-cmd --get-active-zones
firewall-cmd --get-zone-of-interface=eth0
Reenvío de Puertos No Funciona
Problema: Las reglas de reenvío de puertos no reenvían tráfico.
Solución:
# 1. Verify masquerading is enabled
firewall-cmd --zone=external --query-masquerade
# 2. Enable masquerading if needed
sudo firewall-cmd --permanent --zone=external --add-masquerade
# 3. Check forward rules
firewall-cmd --zone=external --list-forward-ports
# 4. Enable IP forwarding in kernel
sudo sysctl -w net.ipv4.ip_forward=1
# Make permanent
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# 5. Verify target machine is reachable
ping target_ip
Alto Uso de CPU
Problema: Firewalld consumiendo CPU excesiva.
Solución:
# Check for excessive rules
firewall-cmd --list-all-zones | wc -l
# Review rich rules (can be CPU intensive)
firewall-cmd --list-rich-rules
# Consider using IP sets for large IP lists
# Consolidate similar rules
# Check for rule loops or conflicts
sudo firewall-cmd --check-config
# Monitor firewalld process
top -p $(pgrep firewalld)
Mejores Prácticas
Mejores Prácticas de Seguridad
- Principio de denegación predeterminada: Empezar con reglas restrictivas, abrir solo lo necesario
# Set default zone to drop
sudo firewall-cmd --set-default-zone=drop
# Or use public zone with minimal services
sudo firewall-cmd --set-default-zone=public
- Limitar acceso SSH:
# Allow SSH only from specific IPs
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" service name="ssh" accept'
- Limitación de tasa:
# Limit connection attempts
sudo firewall-cmd --permanent --add-rich-rule='rule service name="ssh" limit value="3/m" accept'
- Registrar actividad sospechosa:
# Log dropped packets
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" log prefix="FIREWALL-DROP: " level="warning" drop'
- Auditorías regulares:
# Create audit script
cat << 'EOF' | sudo tee /usr/local/bin/firewall-audit.sh
#!/bin/bash
echo "Firewall Audit - $(date)"
echo "===================="
firewall-cmd --list-all-zones
firewall-cmd --list-rich-rules
firewall-cmd --get-active-zones
EOF
sudo chmod +x /usr/local/bin/firewall-audit.sh
Mejores Prácticas Operacionales
- Probar antes de hacer permanente:
# Add rule to runtime first
sudo firewall-cmd --add-service=http
# Test thoroughly
# Then make permanent
sudo firewall-cmd --runtime-to-permanent
- Documentar cambios:
# Add comments to rules (via rich rules or external docs)
# Maintain change log
cat >> /root/firewall-changes.log << EOF
$(date): Added HTTP service to public zone - Ticket #12345
EOF
- Respaldar configuración:
# Backup firewall config
sudo tar -czf /root/firewall-backup-$(date +%Y%m%d).tar.gz /etc/firewalld/
# Automate backups
echo "0 0 * * 0 tar -czf /root/firewall-backup-\$(date +\%Y\%m\%d).tar.gz /etc/firewalld/" | sudo crontab -
- Usar zonas apropiadamente:
# Internal network
sudo firewall-cmd --zone=internal --add-interface=eth1
# Public network
sudo firewall-cmd --zone=public --add-interface=eth0
# DMZ for web servers
sudo firewall-cmd --zone=dmz --add-interface=eth2
- Monitorear logs:
# Set up log monitoring
sudo journalctl -u firewalld -f
# Create alert script
cat << 'EOF' | sudo tee /usr/local/bin/firewall-monitor.sh
#!/bin/bash
DROPS=$(journalctl -u firewalld -S today | grep -c DROP)
if [ $DROPS -gt 1000 ]; then
echo "High number of firewall drops: $DROPS" | mail -s "Firewall Alert" [email protected]
fi
EOF
sudo chmod +x /usr/local/bin/firewall-monitor.sh
# Add to cron
Optimización de Rendimiento
- Usar conjuntos de IP para listas grandes
- Consolidar reglas similares
- Ordenar reglas por frecuencia (más usadas primero)
- Evitar logging excesivo
- Usar servicios en lugar de puertos individuales
Gestión de Configuración
# Export configuration
sudo firewall-cmd --runtime-to-permanent
sudo tar -czf firewall-config.tar.gz /etc/firewalld/
# Import on new server
sudo tar -xzf firewall-config.tar.gz -C /
sudo firewall-cmd --reload
Conclusión
Firewalld proporciona una interfaz potente, flexible y fácil de usar para gestionar reglas de firewall en distribuciones basadas en RHEL. A través de configuración basada en zonas, definiciones de servicios y sintaxis de reglas enriquecidas, puedes implementar políticas exhaustivas de seguridad de red.
Logros clave:
- Firewalld instalado y configurado
- Entendimiento del modelo de seguridad basado en zonas
- Gestión de servicios y puertos configurada
- Reglas enriquecidas avanzadas implementadas
- Reenvío de puertos y NAT configurado
- Conjuntos de IP para gestión eficiente de IPs
- Procedimientos de monitoreo y resolución de problemas establecidos
Aspectos destacados de seguridad:
- Denegación predeterminada con reglas de permiso explícitas
- Niveles de confianza basados en zonas
- Limitación de tasa para protección contra fuerza bruta
- Logging para monitoreo de seguridad
- Restricciones de acceso basadas en origen
Siguientes pasos:
- Integrar con fail2ban para protección mejorada
- Configurar logging centralizado
- Implementar procedimientos de respaldo automatizados
- Auditorías de seguridad regulares
- Documentación y entrenamiento del equipo
La naturaleza dinámica de Firewalld, combinada con configuración y monitoreo apropiados, proporciona seguridad de red robusta para tu infraestructura basada en RHEL.
Recursos Adicionales
- Documentación Oficial de Firewalld
- Guía de Firewalld RHEL 9
- Lenguaje Enriquecido de Firewalld
- Configuración de Servicios de Firewalld
- Documentación de Backend Nftables
Guías Relacionadas
- Configuración Inicial de Seguridad en CentOS/Rocky Linux
- Cómo Cambiar el Puerto SSH Predeterminado
- Configuración de iptables: Guía Completa
- Resolución de Problemas de Red con Comandos
- Fortalecimiento de Servidor Linux: Guía Completa
- SELinux: Configuración Básica y Modos


