Configurar Reglas de Firewall con iptables
Configura reglas de firewall básicas usando iptables en Bash para filtrar tráfico, bloquear puertos y proteger servidores Linux.
Visión General
iptables es el framework clásico de firewall de Linux. Te permite definir reglas que filtran paquetes entrantes, salientes y reenviados basándose en direcciones IP, puertos, protocolos y estado de conexión. Un script de Bash bien estructurado hace las reglas de iptables legibles, repetibles y fáciles de restablecer, lo cual es esencial cuando endureces un servidor o resuelves problemas de conectividad.
Cuándo Usar
Usa este recurso cuando:
- Necesites filtrar tráfico en un servidor Linux sin un security group cloud.
- Quieras permitir solo puertos específicos (SSH, HTTP, HTTPS) y descartar el resto.
- Estés construyendo un bastion host o una imagen mínima de servidor.
- Necesites bloquear una dirección IP o rango temporalmente.
Solución
Script básico de firewall con iptables
#!/usr/bin/env bash
set -euo pipefail
# Restablecer reglas
iptables -F
iptables -X
iptables -Z
# Políticas por defecto
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Permitir loopback
iptables -A INPUT -i lo -j ACCEPT
# Permitir conexiones establecidas y relacionadas
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Permitir SSH (rate-limited)
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Permitir HTTP y HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Guardar reglas
iptables-save > /etc/iptables/rules.v4
echo "Reglas de firewall aplicadas"
Explicación
El script comienza eliminando reglas existentes y reiniciando contadores. Establece una política de denegación por defecto para tráfico entrante y reenviado, permitiendo el tráfico saliente. El tráfico de loopback siempre se acepta porque los servicios locales dependen de él. El módulo de connection tracking permite respuestas a solicitudes salientes. SSH se acepta con rate limiting para ralentizar intentos de fuerza bruta. HTTP y HTTPS están abiertos para servicios web. Finalmente, las reglas se guardan para que persistan tras el reinicio.
Variantes
| Tipo de regla | Ejemplo | Propósito |
|---|---|---|
| Permitir puerto | --dport 443 | Abrir HTTPS |
| Bloquear IP | -s 10.0.0.0/8 -j DROP | Denegar una subnet |
| Rate limit | -m recent | Ralentizar fuerza bruta |
| Log y drop | -j LOG --log-prefix | Auditar tráfico bloqueado |
Lo que funciona
- Denegación por defecto, permitir explícitamente. Una política de drop por defecto es más segura que una de allow.
- Guarda reglas antes del reinicio. Usa
iptables-savey un servicio systemd o el paquete netfilter-persistent. - Usa connection tracking. Permitir conexiones establecidas y relacionadas evita romper conexiones salientes.
- Limita SSH. La fuerza bruta es común; limita nuevas conexiones por minuto.
- Prueba antes de guardar. Aplica reglas, verifica conectividad, luego guarda. Una mala regla puede dejarte fuera del servidor.
Errores Comunes
- Olvidar permitir conexiones establecidas. Sin conntrack, las respuestas a solicitudes salientes se bloquean.
- Dejarte fuera de SSH. Siempre permite tu puerto de gestión antes de cambiar la política por defecto.
- Eliminar reglas sin un plan de recuperación. Si pierdes acceso, puedes necesitar acceso a consola para recuperarte.
- Ignorar IPv6.
ip6tablesnecesita su propio conjunto de reglas; muchos servidores son dual-stack. - Depender solo de iptables. Usa security groups cloud y network ACLs como capas adicionales.
Preguntas frecuentes
Reglas de firewall IPv6 con ip6tables
#!/usr/bin/env bash
set -euo pipefail
# Restablecer reglas IPv6
ip6tables -F
ip6tables -X
ip6tables -Z
# Políticas por defecto
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT ACCEPT
# Permitir loopback
ip6tables -A INPUT -i lo -j ACCEPT
# Permitir conexiones establecidas y relacionadas
ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Permitir ICMPv6 (requerido para que IPv6 funcione — neighbor discovery, MLD, etc.)
ip6tables -A INPUT -p icmpv6 -j ACCEPT
# Permitir SSH (rate-limited)
ip6tables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set
ip6tables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
# Permitir HTTP y HTTPS
ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT
ip6tables -A INPUT -p tcp --dport 443 -j ACCEPT
# Guardar reglas IPv6
ip6tables-save > /etc/iptables/rules.v6
echo "Reglas de firewall IPv6 aplicadas"
Mitigación de DDoS con límites de conexión
#!/usr/bin/env bash
set -euo pipefail
# Limitar conexiones por IP origen para prevenir SYN floods
iptables -A INPUT -p tcp -m connlimit --connlimit-above 50 --connlimit-mask 32 -j DROP
# Limitar nuevas conexiones por segundo (protección contra port scans y floods)
iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m limit --limit 20/s --limit-burst 40 -j ACCEPT
iptables -A INPUT -p tcp -m conntrack --ctstate NEW -j DROP
# Descartar paquetes inválidos (spoofed, malformados)
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
# Protección SYN flood con SYNPROXY (kernel 3.12+)
iptables -t raw -A PREROUTING -p tcp -m tcp --syn -j CT --notrack
iptables -A INPUT -p tcp -m tcp --syn -m conntrack --ctstate UNTRACKED,INVALID -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
iptables -A INPUT -p tcp -m tcp --syn -m conntrack --ctstate UNTRACKED,INVALID -j DROP
# Limitar ICMP (protección contra ping flood)
iptables -A INPUT -p icmp -m limit --limit 1/s --limit-burst 3 -j ACCEPT
iptables -A INPUT -p icmp -j DROP
echo "Reglas de mitigación de DDoS aplicadas"
Logging de paquetes descartados para auditoría
#!/usr/bin/env bash
set -euo pipefail
# Log de paquetes descartados con prefijo (rate-limited para evitar flooding de logs)
iptables -A INPUT -m limit --limit 5/min --limit-burst 10 -j LOG \
--log-prefix "iptables-DROP: " \
--log-level 4 \
--log-ip-options \
--log-tcp-options \
--log-uid
# Descartar todo lo demás
iptables -A INPUT -j DROP
# Ver paquetes descartados en el log del sistema
# journalctl -k | grep "iptables-DROP"
# o: dmesg | grep "iptables-DROP"
# Log a un archivo personalizado vía rsyslog
cat > /etc/rsyslog.d/10-iptables.conf << 'EOF'
:msg, contains, "iptables-DROP" /var/log/iptables.log
& stop
EOF
systemctl restart rsyslog
Integración de fail2ban con iptables
#!/usr/bin/env bash
set -euo pipefail
# Instalar fail2ban
# apt install fail2ban O yum install fail2ban
# Crear configuración local
cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
banaction = iptables-multiport
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = systemd
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
bantime = 86400
findtime = 86400
maxretry = 5
EOF
# Iniciar y habilitar fail2ban
systemctl enable fail2ban
systemctl start fail2ban
# Verificar IPs baneadas
fail2ban-client status sshd
# Banear/desbanear una IP manualmente
fail2ban-client set sshd banip 198.51.100.1
fail2ban-client set sshd unbanip 198.51.100.1
# fail2ban crea reglas de iptables automáticamente:
# Chain f2b-sshd (referencias en la cadena INPUT)
# iptables -L f2b-sshd -n --line-numbers
Migración a nftables (reemplazo moderno)
#!/usr/bin/env bash
set -euo pipefail
# nftables es el reemplazo moderno de iptables (kernel 3.13+)
# Muchas distribuciones (Debian 10+, Ubuntu 20.04+, RHEL 8+) usan backend nftables
# Convertir reglas existentes de iptables a nftables
iptables-restore-translate -f /etc/iptables/rules.v4 > /etc/nftables.conf
# O escribir reglas nftables directamente
cat > /etc/nftables.conf << 'EOF'
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Permitir loopback
iif "lo" accept
# Permitir establecidas y relacionadas
ct state established,related accept
# Descartar inválidas
ct state invalid drop
# Permitir ICMP (rate-limited)
icmp type echo-request limit rate 1/second accept
icmpv6 type echo-request limit rate 1/second accept
# Permitir SSH con rate limiting
tcp dport 22 ct state new limit rate 4/minute accept
# Permitir HTTP y HTTPS
tcp dport { 80, 443 } accept
# Log y descartar todo lo demás
limit rate 5/minute log prefix "nft-DROP: " level warn
drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
EOF
# Aplicar reglas nftables
nft -f /etc/nftables.conf
# Habilitar nftables en el boot
systemctl enable nftables
systemctl start nftables
# Listar reglas
nft list ruleset
Port knocking para servicios ocultos
#!/usr/bin/env bash
set -euo pipefail
# Port knocking: SSH solo se abre después de una secuencia específica de "golpes" de puertos
# Requiere knockd: apt install knockd
cat > /etc/knockd.conf << 'EOF'
[openSSH]
sequence = 7000,8000,9000
seq_timeout = 15
tcpflags = syn
command = iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
stop_timeout = 30
[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 15
tcpflags = syn
command = iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
EOF
# Iniciar knockd
systemctl enable knockd
systemctl start knockd
# Cliente: golpear antes de conectar
# knock -v server-ip 7000 8000 9000
# ssh user@server-ip
# knock -v server-ip 9000 8000 7000 # Cerrar después
Recursos Relacionados
Script de Rotación de Backups
Automatiza backups con políticas de retención usando un script de Bash que rota snapshots diarios, semanales y mensuales.
RecipeMonitorear Uso de Disco
Alerta cuando el espacio en disco cruza umbrales usando un script de Bash que verifica mount points y notifica operadores.
RecipeGestión de Claves SSH
Genera, rota y distribuye claves SSH de forma segura con scripts de Bash para equipos y acceso a servidores.
RecipeScripting en Bash para Automatizacion DevOps y Tareas de
Como escribir scripts Bash robustos para automatizar despliegues, monitoreo de sistemas, rotacion de logs y tareas de mantenimiento rutinarias
RecipeRotación y Compresión de Logs
Rota y comprime logs de aplicaciones con Bash para evitar que el disco se llene y simplificar la retención.
RecipeExtraer Archivos Zip de Forma Segura con Python
Cómo extraer y validar archivos zip de forma segura usando zipfile y shutil en Python.