Saltar a contenido

🔥 Lab 10: Firewall con iptables

Hasta ahora todo el tráfico en tus labs pasaba libremente. En la realidad, los servidores y routers tienen reglas que deciden qué tráfico se permite y qué se bloquea. Eso es un firewall.

En Linux, el firewall se llama iptables. Ya lo usaste sin saberlo — en el lab de NAT vas a ver que usa la misma herramienta. Primero hay que entender cómo funciona para filtrar tráfico.


¿Cómo piensa iptables?

Todo el tráfico que pasa por un Linux atraviesa una serie de cadenas (chains). Las tres principales:

Chain ¿Qué tráfico evalúa?
INPUT Paquetes que llegan a este equipo
OUTPUT Paquetes que salen de este equipo
FORWARD Paquetes que pasan por este equipo (router)

Cada cadena tiene una lista de reglas. El kernel las evalúa en orden hasta encontrar una que coincida. Si ninguna coincide, aplica la política por defecto (normalmente ACCEPT).


🏗️ Topología del Laboratorio

name: "lab-09-firewall"
nodes:
  - name: PC-Cliente
    type: HOST
    x: 100
    y: 200
  - name: SERVIDOR
    type: HOST
    x: 500
    y: 200
  - name: SWITCH-1
    type: SWITCH
    x: 300
    y: 200
links:
  - source: PC-Cliente
    target: SWITCH-1
  - source: SERVIDOR
    target: SWITCH-1

🛠️ Paso 1: Configuración de IPs

En PC-Cliente:

ip addr add 192.168.1.10/24 dev eth1
ip link set eth1 up

En SERVIDOR:

ip addr add 192.168.1.20/24 dev eth1
ip link set eth1 up

Verificá que hay conectividad:

# Desde PC-Cliente
ping -c 3 192.168.1.20

Funciona. Por defecto, iptables acepta todo.


🔍 Paso 2: Ver las reglas actuales

Antes de tocar nada, mirá el estado del firewall en SERVIDOR:

iptables -L -n -v

Verás algo así:

Chain INPUT (policy ACCEPT)
Chain FORWARD (policy ACCEPT)
Chain OUTPUT (policy ACCEPT)

Las tres cadenas tienen política ACCEPT y ninguna regla. Todo pasa.


🚫 Paso 3: Bloquear ping (DROP)

Agregá una regla en SERVIDOR que descarte los pings:

# En SERVIDOR
iptables -A INPUT -p icmp -j DROP

-A INPUT → agregar al final de la cadena INPUT
-p icmp → solo aplica a paquetes ICMP (ping)
-j DROP → descartarlos silenciosamente

Ahora desde PC-Cliente:

ping -c 4 192.168.1.20

Los paquetes desaparecen sin respuesta. DROP no avisa — para el cliente parece que el host no existe.


⚡ Paso 4: DROP vs REJECT

Hay dos formas de bloquear. La diferencia importa:

Primero eliminá la regla anterior:

# En SERVIDOR
iptables -D INPUT -p icmp -j DROP

Ahora usá REJECT:

iptables -A INPUT -p icmp -j REJECT

Desde PC-Cliente:

ping -c 4 192.168.1.20

Esta vez el ping falla inmediatamente con Destination Port Unreachable. REJECT envía un mensaje ICMP de error de vuelta — el cliente sabe enseguida que está bloqueado.

¿Cuándo usar cada uno? - DROP en firewalls externos — no le das información al atacante - REJECT en redes internas — el administrador puede diagnosticar más rápido

Eliminá la regla antes de seguir:

iptables -D INPUT -p icmp -j REJECT


🔒 Paso 5: Bloquear un puerto específico

Los servidores reales exponen servicios en puertos. Simulá un servicio en SERVIDOR:

# En SERVIDOR — levantar un "servidor" básico en el puerto 8080
nc -lk -p 8080

Desde PC-Cliente, intentá conectarte:

nc 192.168.1.20 8080

Funciona — podés escribir texto y llega al servidor. Salí con Ctrl+C.

Ahora bloqueá ese puerto:

# En SERVIDOR (nueva terminal)
iptables -A INPUT -p tcp --dport 8080 -j DROP

Intentá conectarte de nuevo desde PC-Cliente:

nc -w 3 192.168.1.20 8080

La conexión queda colgada (timeout) — los paquetes TCP SYN llegan al servidor pero los descarta.


🔓 Paso 6: Permitir solo tráfico establecido (firewall stateful)

Un firewall bien configurado no bloquea todo — bloquea las conexiones nuevas no autorizadas pero deja pasar las respuestas de conexiones que ya iniciaste vos.

Limpiá todas las reglas:

# En SERVIDOR
iptables -F

Ahora configurá una política más real:

# Permitir conexiones ya establecidas (respuestas)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Permitir el puerto 80 (HTTP)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# Bloquear todo lo demás
iptables -A INPUT -j DROP

Verificá:

iptables -L -n -v

Con esta configuración: - ping desde PC-Cliente → bloqueado (ICMP no tiene regla ACCEPT) - nc 192.168.1.20 80 → pasa - nc 192.168.1.20 8080 → bloqueado - Las respuestas del servidor a conexiones que él inició → siempre pasan (ESTABLISHED)


🌐 Paso 7: La cadena FORWARD (para routers)

La cadena INPUT protege el equipo donde corre iptables. Cuando el equipo actúa como router — recibe paquetes que no van a él sino que debe reenviar — entra en juego FORWARD.

En el próximo lab vas a ver esto en acción cuando configures NAT: el router tiene que dejar pasar (FORWARD) los paquetes de la red interna hacia afuera. Por defecto en muchos sistemas FORWARD está bloqueado, y hay que habilitarlo explícitamente con:

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -A FORWARD -j ACCEPT

📝 Ejercicio: El orden de las reglas importa

Probá este experimento en SERVIDOR:

# Primero, aceptá HTTP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# Después, bloqueá TODO
iptables -A INPUT -j DROP

Desde PC-Cliente, intentá:

nc -w 3 192.168.1.20 80

Resultado: No funciona. Aunque hay una regla que acepta el puerto 80, nunca se evalúa porque la regla DROP está después... pero iptables evalúa en orden, y ACCEPT apareció primero. Esperá, ¿no debería funcionar?

Mirá de nuevo: ACCEPT fue primero, DROP segundo. Entonces ¿por qué falla?

Trampa: Si seguiste el Paso 6, puede que tengas reglas viejas. Hacé iptables -F primero y repetí el ejercicio.

Ahora invertí el orden:

iptables -F

# Primero, bloqueá TODO
iptables -A INPUT -j DROP

# Después, aceptá HTTP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Probá de nuevo nc 192.168.1.20 80.

Resultado: Tampoco funciona. La regla DROP apareció primero y "atrapa" todo el tráfico antes de que llegue a ACCEPT.

Lección: El orden en iptables no es "de más específico a más general" por casualidad — es una regla de supervivencia. Las reglas se evalúan secuencialmente, y la primera que coincide gana.

La forma correcta:

iptables -F
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -j DROP

Limpiá antes de seguir:

iptables -F
iptables -P INPUT ACCEPT


💡 Conceptos Clave

  • Chain INPUT: filtra tráfico destinado a este equipo
  • Chain FORWARD: filtra tráfico que pasa a través (routers)
  • DROP: descarta silenciosamente — el cliente no sabe qué pasó
  • REJECT: descarta y avisa — el cliente sabe enseguida
  • Stateful (--state ESTABLISHED): distingue conexiones nuevas de respuestas a conexiones existentes
  • Las reglas se evalúan en orden — la primera que coincide gana

En el próximo lab vas a usar iptables de una forma distinta: no para filtrar, sino para traducir IPs (NAT).