Configurar Reglas de Firewall iptables con Bash
Configura reglas básicas de firewall con iptables y scripts bash.
Visión General
iptables es el framework de firewall por defecto en Linux. Filtra tráfico de red a nivel kernel usando cadenas de reglas. Esta recipe cubre configurar un firewall básico: permitir SSH y HTTP, bloquear todo lo demás, configurar NAT y persistir reglas tras reinicios.
Cuándo Usar
- Estás configurando un servidor Linux nuevo y necesitas protección básica de firewall
- Quieres restringir tráfico entrante a puertos específicos
- Necesitas configurar NAT o port forwarding
- Estás endureciendo un servidor antes de deployar a producción
Solución
Configuración básica de firewall
#!/bin/bash
# Flush existing rules
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
# Set default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Allow loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow SSH (port 22)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow HTTP and HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow DNS queries
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
# Log dropped packets (optional, rate-limited)
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables-dropped: " --log-level 4
echo "Firewall configured. SSH, HTTP, HTTPS, DNS allowed."
Rate limiting de conexiones SSH
#!/bin/bash
# Allow only 3 SSH connections per minute, drop the rest
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
# Allow established SSH
iptables -A INPUT -p tcp --dport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT
echo "SSH rate limiting configured: max 3 new connections per minute"
Port forwarding con NAT
#!/bin/bash
# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# Forward port 8080 to port 80 on 192.168.1.100
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80
iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.100 --dport 80 -j MASQUERADE
# Allow forwarding
iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 80 -j ACCEPT
echo "Port forwarding: 8080 -> 192.168.1.100:80"
Bloquear IPs específicas
#!/bin/bash
BLOCKED_IPS=(
"203.0.113.50"
"198.51.100.23"
"192.0.2.100"
)
for ip in "${BLOCKED_IPS[@]}"; do
iptables -A INPUT -s "$ip" -j DROP
echo "Blocked: $ip"
done
Permitir tráfico solo de un subnet específico
#!/bin/bash
# Only allow SSH from 10.0.0.0/24
iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
echo "SSH restricted to 10.0.0.0/24"
Persistir reglas tras reinicios
#!/bin/bash
# Save rules
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
# Install persistence package (Debian/Ubuntu)
apt-get install -y iptables-persistent
# Or restore manually on boot via systemd
cat > /etc/systemd/system/iptables-restore.service << 'EOF'
[Unit]
Description=Restore iptables rules
Before=network-pre.target
[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore /etc/iptables/rules.v4
[Install]
WantedBy=multi-user.target
EOF
systemctl enable iptables-restore.service
echo "Rules persisted to /etc/iptables/rules.v4"
Script de reset de firewall
#!/bin/bash
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
echo "All iptables rules cleared. Default: ACCEPT all."
Listar y verificar reglas
#!/bin/bash
echo "=== Filter table ==="
iptables -L -n -v --line-numbers
echo ""
echo "=== NAT table ==="
iptables -t nat -L -n -v --line-numbers
echo ""
echo "=== Mangle table ==="
iptables -t mangle -L -n -v --line-numbers
Explicación
iptables procesa reglas en orden, de arriba hacia abajo. La primera regla que coincide gana. Las políticas por defecto (-P) aplican cuando ninguna regla coincide.
Conceptos clave:
- Chains:
INPUT(entrante),OUTPUT(saliente),FORWARD(ruteado). - Tables:
filter(por defecto),nat(traducción de direcciones),mangle(modificación de paquetes). - Targets:
ACCEPT,DROP,REJECT,LOG,MASQUERADE. - State matching:
ESTABLISHED,RELATEDpermite tráfico de retorno para conexiones iniciadas desde el servidor.
El módulo -m recent trackea IPs de origen y habilita rate limiting. Guarda intentos de conexión en /proc/net/xt_recent/.
Variantes
| Enfoque | Herramienta | Complejidad | Usar Cuando |
|---|---|---|---|
| iptables | iptables | Media | Servidores Linux estándar |
| nftables | nft | Media | Linux moderno (reemplaza iptables) |
| UFW | ufw | Baja | Setup rápido Ubuntu/Debian |
| firewalld | firewall-cmd | Baja | RHEL/CentOS/Fedora |
Pautas
- Siempre permite SSH antes de setear
DROPcomo política por defecto. Puedes bloquearte fuera. - Testea reglas en una sesión SSH separada antes de cerrar la actual.
- Usa
iptables -L -n -vpara verificar que las reglas se aplicaron correctamente. - Persiste reglas con
iptables-persistento un servicio systemd. Las reglas se pierden al reiniciar. - Loguea paquetes dropeados con rate limiting para evitar llenar el log.
- Usa
REJECTen vez deDROPpara redes internas.REJECTenvía respuesta;DROPdescarta silenciosamente.
Errores Comunes
- Setear política
DROPantes de permitir SSH. Pierdes acceso inmediatamente. - No persistir reglas. Desaparecen al reiniciar y el servidor queda desprotegido o inalcanzable.
- Permitir todas las conexiones establecidas antes de verificar el origen. Un paquete spoofed puede bypassar reglas.
- Olvidar IPv6.
ip6tableses separado. Un puerto IPv6 abierto bypassa las reglas IPv4 de iptables. - Usar
DROPen todos lados.DROPhace el troubleshooting más difícil. UsaREJECTpara tráfico interno.
Mejores Prácticas Adicionales
- For a deeper guide, see Docker Network Isolation and Inter-Container Security.
- Usa
conntracken vez destatepara setups nuevos. El módulostateestá deprecado en favor deconntrackque provee la misma funcionalidad con mejor performance:
# Viejo (deprecado)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Nuevo (recomendado)
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
- Setea parámetros del kernel para hardening. Combina iptables con settings de sysctl para defensa en profundidad:
# Habilitar SYN cookies
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
# Deshabilitar IP forwarding (a menos que sea un router)
echo 0 > /proc/sys/net/ipv4/ip_forward
# Ignorar broadcasts ICMP (ataques smurf)
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# Reverse path filtering
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter Preguntas frecuentes
¿Cuál es la diferencia entre iptables y nftables?
nftables es el sucesor de iptables, introducido en Linux kernel 3.13. Usa una sintaxis unificada, soporta IPv4 e IPv6 en una sola tabla y tiene mejor performance. Las reglas de iptables se pueden traducir a nftables con iptables-translate.
¿Cómo permito un rango de puertos?
iptables -A INPUT -p tcp --dport 8000:8100 -j ACCEPT
Esto permite tráfico TCP en los puertos 8000 a 8100.
¿Cómo bloqueo todo el tráfico de un país?
Usa ipset con una lista de rangos IP del país:
ipset create blocklist hash:net
# Add IP ranges (from a geoip database)
ipset add blocklist 203.0.113.0/24
iptables -A INPUT -m set --match-set blocklist src -j DROP
¿Cómo depuro por qué un paquete está siendo dropeado?
Agrega una regla LOG antes de la regla DROP:
iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH-DROP: "
iptables -A INPUT -p tcp --dport 22 -j DROP
Revisa /var/log/syslog o /var/log/messages para las entradas de log. Remueve la regla LOG después de debuggear.
Recursos Relacionados
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.
RecipeGestión de Llaves SSH en Bash
Genera, rota y distribuye llaves SSH con scripts bash.
DocPlantilla de Politica de Segmentacion de Red
Una plantilla para documentar zonas de seguridad de red, reglas de segmentacion y controles de trafico entre ambientes e inquilinos.
DocPlantilla de Gestion de Certificados SSL
Una plantilla para rastrear el inventario, renovaciones, despliegues y riesgos de vencimiento de certificados TLS/SSL en dominios y servicios.
DocPlantilla de Evaluacion de Proveedores Terceros
Una plantilla estructurada para evaluar la seguridad, cumplimiento y postura operativa de proveedores terceros antes de la incorporacion o renovacion.
RecipeAislamiento de Red Docker y Seguridad Entre Contenedores
Asegura la comunicación entre contenedores con redes Docker personalizadas, segmentación de red y políticas de control de acceso.