Saltar al contenido principal

Security Groups vs NACL

Introducción​

AWS ofrece dos niveles de firewall para proteger sus recursos:

  • Security Groups: a nivel de instancia
  • NACL (Network ACL): a nivel de subnet
┌─────────────────────────────────────────────────────────────┐
│ DOS NIVELES DE SEGURIDAD │
├─────────────────────────────────────────────────────────────┤
│ │
│ INTERNET │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ SUBNET │ │
│ │ ┌────────────────────────────────────────────────┐ │ │
│ │ │ NACL (1er nivel) │ │ │
│ │ │ Filtra TODO el tráfico entrante/saliente │ │ │
│ │ │ del subnet │ │ │
│ │ └───────────────────┬────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌────────────────────────────────────────────────┐ │ │
│ │ │ INSTANCIA EC2 │ │ │
│ │ │ ┌──────────────────────────────────────────┐ │ │ │
│ │ │ │ SECURITY GROUP (2º nivel) │ │ │ │
│ │ │ │ Filtra el tráfico hacia/desde instancia│ │ │ │
│ │ │ └──────────────────────────────────────────┘ │ │ │
│ │ │ │ │ │ │
│ │ │ ┌─────▼─────┐ │ │ │
│ │ │ │ Aplicación │ │ │ │
│ │ │ └───────────┘ │ │ │
│ │ └────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

Security Groups​

Características​

┌─────────────────────────────────────────────────────────────┐
│ SECURITY GROUPS │
├─────────────────────────────────────────────────────────────┤
│ │
│ TIPO: Firewall STATEFUL (con estado) │
│ │
│ Stateful significa: │
│ • Si el tráfico entrante está permitido │
│ • Entonces la respuesta saliente está permitida automáticamente │
│ • No se necesita una regla explícita para la respuesta │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Cliente ──── Solicitud ────► Instancia │ │
│ │ (permitido por regla inbound) │ │
│ │ │ │
│ │ Cliente ◄─── Respuesta ──── Instancia │ │
│ │ (permitido automáticamente - stateful) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ FUNCIONAMIENTO │
│ • Por defecto: TODO bloqueado en entrada │
│ • Por defecto: TODO permitido en salida │
│ • Solo reglas ALLOW (no DENY) │
│ • Todas las reglas evaluadas en conjunto (sin orden) │
│ │
└─────────────────────────────────────────────────────────────┘

Anatomía de una Regla SG​

┌─────────────────────────────────────────────────────────────┐
│ REGLA SECURITY GROUP │
├─────────────────────────────────────────────────────────────┤
│ │
│ Tipo : SSH │
│ Protocolo : TCP │
│ Rango de puertos : 22 │
│ Origen : 203.0.113.0/24 │
│ Descripción: Acceso admin desde oficina │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ SIGNIFICADO: │ │
│ │ │ │
│ │ "Permitir el tráfico TCP en el puerto 22 (SSH) │ │
│ │ desde las IPs 203.0.113.0 a 203.0.113.255" │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ POSIBLES ORÍGENES: │
│ • IP única : 203.0.113.45/32 │
│ • Rango CIDR : 203.0.113.0/24 │
│ • Otro SG : sg-0123456789 │
│ • Prefix List : pl-xxx │
│ • En todas partes: 0.0.0.0/0 (⚠️ ¡cuidado!) │
│ │
└─────────────────────────────────────────────────────────────┘

Ejemplos de Security Groups​

┌─────────────────────────────────────────────────────────────┐
│ SECURITY GROUP - SERVIDOR WEB │
├─────────────────────────────────────────────────────────────┤
│ │
│ Nombre: sg-web-server │
│ │
│ REGLAS ENTRANTES (Inbound) │
│ ┌───────┬──────────┬───────┬─────────────────────────┐ │
│ │ Tipo │ Protocolo│ Puerto│ Origen │ │
│ ├───────┼──────────┼───────┼─────────────────────────┤ │
│ │ HTTP │ TCP │ 80 │ 0.0.0.0/0 │ │
│ │ HTTPS │ TCP │ 443 │ 0.0.0.0/0 │ │
│ │ SSH │ TCP │ 22 │ 10.0.0.0/16 (solo VPC) │ │
│ └───────┴──────────┴───────┴─────────────────────────┘ │
│ │
│ REGLAS SALIENTES (Outbound) │
│ ┌───────┬──────────┬───────┬─────────────────────────┐ │
│ │ Tipo │ Protocolo│ Puerto│ Destino │ │
│ ├───────┼──────────┼───────┼─────────────────────────┤ │
│ │ All │ All │ All │ 0.0.0.0/0 │ │
│ └───────┴──────────┴───────┴─────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ SECURITY GROUP - BASE DE DATOS │
├─────────────────────────────────────────────────────────────┤
│ │
│ Nombre: sg-database │
│ │
│ REGLAS ENTRANTES (Inbound) │
│ ┌────────┬──────────┬───────┬────────────────────────┐ │
│ │ Tipo │ Protocolo│ Puerto│ Origen │ │
│ ├────────┼──────────┼───────┼────────────────────────┤ │
│ │ MySQL │ TCP │ 3306 │ sg-web-server ✓ │ │
│ │ MySQL │ TCP │ 3306 │ sg-app-server ✓ │ │
│ └────────┴──────────┴───────┴────────────────────────┘ │
│ │
│ ✓ Referenciar otro SG = buena práctica │
│ Solo las instancias en este SG pueden acceder │
│ │
│ REGLAS SALIENTES (Outbound) │
│ ┌───────┬──────────┬───────┬─────────────────────────┐ │
│ │ Tipo │ Protocolo│ Puerto│ Destino │ │
│ ├───────┼──────────┼───────┼─────────────────────────┤ │
│ │ All │ All │ All │ 0.0.0.0/0 │ │
│ └───────┴──────────┴───────┴─────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

Network ACL (NACL)​

Características​

┌─────────────────────────────────────────────────────────────┐
│ NETWORK ACL (NACL) │
├─────────────────────────────────────────────────────────────┤
│ │
│ TIPO: Firewall STATELESS (sin estado) │
│ │
│ Stateless significa: │
│ • Cada dirección debe ser permitida explícitamente │
│ • Si entrada permitida, salida también debe configurarse │
│ • Reglas separadas para inbound Y outbound │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Cliente ──── Solicitud ────► Subnet │ │
│ │ (necesita regla inbound) │ │
│ │ │ │
│ │ Cliente ◄─── Respuesta ──── Subnet │ │
│ │ (¡necesita regla outbound separada!) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ FUNCIONAMIENTO │
│ • Por defecto: TODO permitido (NACL por defecto) │
│ • Reglas ALLOW y DENY │
│ • Evaluadas en el ORDEN de los números (prioridad) │
│ • La primera regla que coincide = decisión final │
│ • Se aplica a TODO el subnet │
│ │
└─────────────────────────────────────────────────────────────┘

Anatomía de una Regla NACL​

┌─────────────────────────────────────────────────────────────┐
│ REGLA NACL │
├─────────────────────────────────────────────────────────────┤
│ │
│ Número de regla : 100 │
│ Tipo : HTTP (80) │
│ Protocolo : TCP (6) │
│ Rango de puertos : 80 │
│ Origen : 0.0.0.0/0 │
│ Allow/Deny : ALLOW │
│ │
│ ORDEN DE EVALUACIÓN: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Rule 100: ALLOW HTTP from 0.0.0.0/0 │ │
│ │ Rule 200: DENY HTTP from 192.168.1.0/24 │ │
│ │ Rule * : DENY ALL │ │
│ │ │ │
│ │ ¿Paquete HTTP de 192.168.1.50? │ │
│ │ → Evaluado por Rule 100 primero │ │
│ │ → 192.168.1.50 coincide con 0.0.0.0/0 │ │
│ │ → ¡ALLOW! (Rule 200 nunca se evalúa) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ⚠️ El orden de las reglas es CRÍTICO en NACL │
│ │
└─────────────────────────────────────────────────────────────┘

Puertos Efímeros​

┌─────────────────────────────────────────────────────────────┐
│ PUERTOS EFÍMEROS (Importante para NACL) │
├─────────────────────────────────────────────────────────────┤
│ │
│ Problema NACL: ¿Cómo permitir las respuestas? │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Cliente (puerto 54321) ──HTTP:80──► Servidor │ │
│ │ Cliente (puerto 54321) ◄──TCP:54321── Servidor │ │
│ │ │ │
│ │ El servidor responde en el PUERTO ORIGEN del cliente │ │
│ │ Este puerto es "efímero" (aleatorio, temporal) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ RANGOS DE PUERTOS EFÍMEROS: │
│ • Linux : 32768 - 60999 │
│ • Windows : 49152 - 65535 │
│ • NAT Gateway : 1024 - 65535 │
│ │
│ SOLUCIÓN: Permitir los puertos efímeros en outbound │
│ │
│ NACL Outbound Rule: │
│ Rule 100: ALLOW TCP 1024-65535 to 0.0.0.0/0 │
│ │
└─────────────────────────────────────────────────────────────┘

Comparación SG vs NACL​

┌─────────────────────────────────────────────────────────────┐
│ SECURITY GROUP vs NACL │
├─────────────────────────────────────────────────────────────┤
│ │
│ Característica │ Security Group │ NACL │
│ ─────────────────────┼─────────────────┼─────────────────│
│ Nivel │ Instancia │ Subnet │
│ Tipo │ Stateful │ Stateless │
│ Reglas │ Solo ALLOW │ ALLOW & DENY │
│ Evaluación │ Todas en conjunto│ Por orden │
│ Puertos efímeros │ Automático │ Manual │
│ Por defecto │ Deny in/Allow out│ Allow all │
│ Modificable en caliente│ Sí │ Sí │
│ │
│ ¿CUÁNDO USAR CADA UNO? │
│ ───────────────────── │
│ │
│ Security Group: │
│ ✅ Caso de uso principal │
│ ✅ Control por aplicación/rol │
│ ✅ Más fácil de gestionar │
│ │
│ NACL: │
│ ✅ Bloquear IPs maliciosas (regla DENY) │
│ ✅ Línea de defensa adicional │
│ ✅ Cumplimiento (defense in depth) │
│ │
└─────────────────────────────────────────────────────────────┘

Ejemplos Prácticos​

Crear un Security Group (CLI)​

# Crear el Security Group
aws ec2 create-security-group \
--group-name sg-web-server \
--description "Security group for web servers" \
--vpc-id vpc-xxx

# Añadir regla HTTP
aws ec2 authorize-security-group-ingress \
--group-id sg-xxx \
--protocol tcp \
--port 80 \
--cidr 0.0.0.0/0

# Añadir regla SSH (restrictiva)
aws ec2 authorize-security-group-ingress \
--group-id sg-xxx \
--protocol tcp \
--port 22 \
--cidr 10.0.0.0/16

# Permitir desde otro SG
aws ec2 authorize-security-group-ingress \
--group-id sg-database \
--protocol tcp \
--port 3306 \
--source-group sg-web-server

Crear una NACL (CLI)​

# Crear la NACL
aws ec2 create-network-acl \
--vpc-id vpc-xxx \
--tag-specifications 'ResourceType=network-acl,Tags=[{Key=Name,Value=nacl-public}]'

# Añadir regla inbound HTTP
aws ec2 create-network-acl-entry \
--network-acl-id acl-xxx \
--rule-number 100 \
--protocol tcp \
--port-range From=80,To=80 \
--cidr-block 0.0.0.0/0 \
--rule-action allow \
--ingress

# Añadir regla outbound para respuestas (puertos efímeros)
aws ec2 create-network-acl-entry \
--network-acl-id acl-xxx \
--rule-number 100 \
--protocol tcp \
--port-range From=1024,To=65535 \
--cidr-block 0.0.0.0/0 \
--rule-action allow \
--egress

Buenas Prácticas​

┌─────────────────────────────────────────────────────────────┐
│ BUENAS PRÁCTICAS DE SEGURIDAD │
├─────────────────────────────────────────────────────────────┤
│ │
│ SECURITY GROUPS │
│ ✅ Principio de menor privilegio │
│ ✅ Un SG por rol/función │
│ ✅ Referenciar los SG entre sí (no IPs) │
│ ✅ Evitar 0.0.0.0/0 para SSH/RDP │
│ ✅ Documentar cada regla (Descripción) │
│ │
│ NACL │
│ ✅ Mantener la NACL por defecto (Allow all) │
│ ✅ Usar NACL para bloquear IPs maliciosas │
│ ✅ Espaciar los números de reglas (100, 200, 300...) │
│ ✅ No olvidar los puertos efímeros │
│ │
│ ⚠️ ERRORES COMUNES │
│ ❌ SSH abierto a 0.0.0.0/0 │
│ ❌ Todos los puertos abiertos "para probar" │
│ ❌ Olvidar las reglas outbound de NACL │
│ ❌ Reglas demasiado permisivas en producción │
│ │
└─────────────────────────────────────────────────────────────┘

Quiz de Validación​

  1. ¿Cuál es la diferencia entre stateful y stateless?
  2. ¿Por qué se deben configurar los puertos efímeros en NACL?
  3. ¿Cómo permitir que un servidor app acceda a una DB vía SG?
  4. ¿En qué orden se evalúan las reglas NACL?
  5. ¿Qué firewall usar para bloquear una IP maliciosa?

Próxima sección: Solución de Problemas de Red