El firewall es la primera línea de defensa de cualquier infraestructura de red. En sistemas Linux, el filtrado de paquetes a nivel del kernel se realiza mediante Netfilter. Para interactuar con Netfilter, históricamente hemos utilizado iptables, y en distribuciones modernas (como RHEL/CentOS/Fedora) se utiliza firewalld como un frontend dinámico.
iptables funciona evaluando el tráfico de red contra un conjunto de reglas matemáticas. Si un paquete coincide con una regla, se aplica una acción (Target) como ACEPTAR (ACCEPT) o DESCARTAR (DROP).
La regla de oro en ciberseguridad es el "Default Deny": bloquear todo por defecto y permitir solo lo estrictamente necesario.
# Ver reglas actuales:
iptables -L -n -v
# 1. PERMITIR tráfico en la interfaz loopback (localhost)
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# 2. PERMITIR conexiones ya establecidas (Stateful inspection)
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# 3. CAMBIAR LA POLÍTICA POR DEFECTO A DROP (¡Cuidado, no te quedes fuera por SSH!)
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT # Normalmente se permite salir, aunque en alta seguridad también se restringe.
La anatomía de un comando iptables es: iptables -[Acción] [Cadena] -p [Protocolo] -s [IP Origen] --dport [Puerto Destino] -j [Target]
# Permitir tráfico HTTP (puerto 80) y HTTPS (puerto 443) desde cualquier lugar:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Permitir SSH (puerto 22) SOLO desde una IP específica (ej. la IP de la VPN corporativa):
iptables -A INPUT -p tcp -s 203.0.113.50 --dport 22 -j ACCEPT
# Bloquear (DROP) una IP maliciosa específica:
iptables -A INPUT -s 198.51.100.22 -j DROP
# Bloquear un rango de IPs completo (Subred):
iptables -A INPUT -s 10.0.0.0/8 -j DROP
# Insertar una regla al principio (-I) en lugar de al final (-A):
# Las reglas se leen de arriba a abajo. La primera que coincida, se aplica.
iptables -I INPUT 1 -s 185.12.99.0/24 -j DROP
Estás bajo ataque. Un botnet está intentando reventar tu puerto SSH por fuerza bruta. Como administrador de sistemas, debes escribir el comando exacto de iptables para bloquear silenciosamente la IP atacante.
Podemos usar módulos extendidos (-m) para mitigar ataques comunes, como el escaneo de puertos o inundaciones SYN.
# Mitigar SYN Floods (Limitando las conexiones a 20/segundo):
iptables -A INPUT -p tcp --syn -m limit --limit 20/s --limit-burst 50 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP
# Bloquear ping (ICMP) para no ser descubiertos por escaneos básicos:
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
# Registro (Logging) de paquetes denegados antes de descartarlos:
iptables -A INPUT -j LOG --log-prefix "Paquete_Bloqueado: " --log-level 4
La tabla NAT (Network Address Translation) permite redirigir tráfico de un puerto a otro, o de una IP a otra. Es fundamental en contenedores Docker y Routers Linux.
# Habilitar el reenvío IP en el kernel:
echo 1 > /proc/sys/net/ipv4/ip_forward
# Redirigir el tráfico que llega al puerto 80 hacia el puerto 8080 interno:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
# Enmascarar tráfico saliente (SNAT/Masquerade) para dar internet a una subred:
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
firewalld es el gestor moderno de firewalls en Red Hat/CentOS/Fedora. A diferencia de iptables, utiliza el concepto de Zonas (ej. public, internal, trusted) y permite aplicar cambios en caliente sin reiniciar el servicio ni cortar conexiones activas.
# Ver el estado y la zona activa:
firewall-cmd --state
firewall-cmd --get-active-zones
# Ver qué está permitido en la zona pública:
firewall-cmd --zone=public --list-all
# Añadir el servicio HTTP (puerto 80) de forma permanente:
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --reload # ¡Obligatorio para aplicar cambios permanentes!
# Añadir un puerto no estándar (ej. 8443 TCP):
firewall-cmd --zone=public --add-port=8443/tcp --permanent
Cuando necesitas reglas complejas (como permitir un puerto solo desde una IP específica), usas Rich Rules.
# Permitir SSH (puerto 22) solo desde la IP 192.168.1.100:
firewall-cmd --permanent --zone=public \
--add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept'
# Bloquear (Reject) una subred entera maliciosa:
firewall-cmd --permanent --zone=public \
--add-rich-rule='rule family="ipv4" source address="10.50.0.0/16" reject'
firewall-cmd --reload
Las reglas de iptables se borran al reiniciar el servidor. Para hacerlas permanentes, necesitamos guardarlas.
# En Debian/Ubuntu (Instalar iptables-persistent primero):
sudo netfilter-persistent save
# o
sudo iptables-save > /etc/iptables/rules.v4
# En CentOS/RHEL con firewalld, añadir el flag "--permanent" guarda el estado automáticamente tras hacer reload.