Lab: Solución de problemas VPC
Objetivo del Lab
Este laboratorio le pone en la piel de un administrador cloud que debe diagnosticar y resolver problemas de conectividad de red. Analizará escenarios reales y propondrá soluciones.
Este laboratorio se basa en el análisis de escenarios. Debe identificar el problema y proponer la solución antes de ver la respuesta.
Parte 1: Caso de Estudio
Arquitectura de Referencia
Todas las preguntas se basan en esta arquitectura:
┌─────────────────────────────────────────────────────────────────────────┐
│ ARCHITECTURE E-COMMERCE │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ INTERNET │
│ │ │
│ ┌──────▼──────┐ │
│ │ IGW │ │
│ │ igw-abc123 │ │
│ └──────┬──────┘ │
│ │ │
│ ┌──────────────────────────────┼──────────────────────────────┐ │
│ │ VPC │ (10.0.0.0/16) │ │
│ │ │ │ │
│ │ ┌──────────────────────────┴────────────────────────────┐ │ │
│ │ │ SUBNET PUBLIC │ │ │
│ │ │ 10.0.1.0/24 │ │ │
│ │ │ rtb-public │ │ │
│ │ │ │ │ │
│ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │
│ │ │ │ BASTION │ │ NAT Gateway │ │ │ │
│ │ │ │ 10.0.1.10 │ │ 10.0.1.50 │ │ │ │
│ │ │ │ sg-bastion │ │ nat-xyz789 │ │ │ │
│ │ │ │ IP: 52.1.2.3 │ │ EIP: 52.4.5.6 │ │ │ │
│ │ │ └─────────────────┘ └─────────────────┘ │ │ │
│ │ │ │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ SUBNET PRIVÉ APP │ │ │
│ │ │ 10.0.11.0/24 │ │ │
│ │ │ rtb-private │ │ │
│ │ │ │ │ │
│ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │
│ │ │ │ WEB SERVER │ │ API SERVER │ │ │ │
│ │ │ │ 10.0.11.20 │ │ 10.0.11.30 │ │ │ │
│ │ │ │ sg-web │ │ sg-api │ │ │ │
│ │ │ └─────────────────┘ └─────────────────┘ │ │ │
│ │ │ │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ SUBNET PRIVÉ DB │ │ │
│ │ │ 10.0.21.0/24 │ │ │
│ │ │ rtb-database │ │ │
│ │ │ │ │ │
│ │ │ ┌─────────────────┐ │ │ │
│ │ │ │ DATABASE │ │ │ │
│ │ │ │ 10.0.21.10 │ │ │ │
│ │ │ │ sg-database │ │ │ │
│ │ │ │ MySQL:3306 │ │ │ │
│ │ │ └─────────────────┘ │ │ │
│ │ │ │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────┘
Configuración Actual
Route Tables:
rtb-public:
┌─────────────────────┬───────────────┐
│ Destination │ Target │
├─────────────────────┼───────────────┤
│ 10.0.0.0/16 │ local │
│ 0.0.0.0/0 │ igw-abc123 │
└─────────────────────┴───────────────┘
rtb-private:
┌─────────────────────┬───────────────┐
│ Destination │ Target │
├─────────────────────┼───────────────┤
│ 10.0.0.0/16 │ local │
│ 0.0.0.0/0 │ nat-xyz789 │
└─────────────────────┴───────────────┘
rtb-database:
┌─────────────────────┬───────────────┐
│ Destination │ Target │
├─────────────────────┼───────────────┤
│ 10.0.0.0/16 │ local │
└─────────────────────┴───────────────┘
Security Groups:
sg-bastion:
┌────────────────────────────────────────────────────┐
│ Inbound: SSH (22) from 0.0.0.0/0 │
│ Outbound: All traffic to 0.0.0.0/0 │
└────────────────────────────────────────────────────┘
sg-web:
┌────────────────────────────────────────────────────┐
│ Inbound: HTTP (80) from 0.0.0.0/0 │
│ Inbound: SSH (22) from sg-bastion │
│ Outbound: All traffic to 0.0.0.0/0 │
└────────────────────────────────────────────────────┘
sg-api:
┌────────────────────────────────────────────────────┐
│ Inbound: TCP (8080) from sg-web │
│ Inbound: SSH (22) from sg-bastion │
│ Outbound: All traffic to 0.0.0.0/0 │
└────────────────────────────────────────────────────┘
sg-database:
┌────────────────────────────────────────────────────┐
│ Inbound: MySQL (3306) from sg-api │
│ Outbound: All traffic to 0.0.0.0/0 │
└────────────────────────────────────────────────────┘
Parte 2: Ejercicios de Solución de Problemas
Ejercicio 1: SSH al Bastion
Síntoma: Un administrador no puede conectarse por SSH al bastion desde su oficina (IP: 203.0.113.50).
$ ssh -i key.pem ec2-user@52.1.2.3
Connection timed out
Preguntas:
- ¿Cuál es el problema más probable?
- ¿Qué comando usaría para verificar?
- ¿Cuál es la solución?
💡 Solución Ejercicio 1
Análisis:
El Security Group sg-bastion permite SSH desde 0.0.0.0/0, así que no es eso.
Verifiquemos:
- ✅ Route Table rtb-public tiene una ruta hacia IGW
- ✅ IGW está adjuntado
- ❓ ¿El bastion tiene una IP pública?
Verificación:
aws ec2 describe-instances --instance-id i-bastion \
--query 'Reservations[].Instances[].PublicIpAddress'
Problema probable: El bastion no tiene una IP pública o la IP cambió después de un reinicio.
Solución:
# Opción 1: Asociar una Elastic IP
aws ec2 allocate-address --domain vpc
aws ec2 associate-address --instance-id i-bastion --allocation-id eipalloc-xxx
# Opción 2: Activar auto-assign public IP en el subnet
Ejercicio 2: Web Server Inaccesible
Síntoma: El sitio web no es accesible desde Internet.
$ curl http://10.0.11.20
curl: (7) Failed to connect to 10.0.11.20 port 80: No route to host
Preguntas:
- ¿Por qué el administrador usa la IP privada desde Internet?
- ¿Cuál es el verdadero problema de arquitectura aquí?
- ¿Cómo debería estar configurada la arquitectura?
💡 Solución Ejercicio 2
Análisis:
El Web Server está en un subnet privado (10.0.11.0/24)!
Problemas identificados:
- El administrador intenta acceder a una IP privada desde Internet (imposible)
- El web server no tiene IP pública
- Incluso con IP pública, no hay ruta IGW en este subnet
Arquitectura incorrecta: Un servidor web destinado al público no debe estar en un subnet privado.
Soluciones posibles:
Opción A (Recomendada): Agregar un Load Balancer
Internet → ALB (subnet público) → Web Server (subnet privado)
Opción B: Mover el Web Server al subnet público
Internet → IGW → Web Server (subnet público con IP pública)
Para la Opción A:
- Crear un Application Load Balancer en el subnet público
- Configurar un Target Group con el web server
- Actualizar sg-web para aceptar tráfico desde sg-alb
Ejercicio 3: API no puede acceder a la Database
Síntoma: El servidor API no puede conectarse a MySQL.
$ mysql -h 10.0.21.10 -u app -p
ERROR 2003 (HY000): Can't connect to MySQL server on '10.0.21.10' (110)
Preguntas:
- Enumere todas las causas posibles.
- ¿Cómo verificaría cada hipótesis?
- ¿Cuál es la causa más probable según la configuración?
💡 Solución Ejercicio 3
Hipótesis y verificaciones:
| Hipótesis | Verificación | Resultado |
|---|---|---|
| SG API → DB | ¿sg-database permite sg-api? | ❌ Permite sg-api |
| Ruta | ¿Existe ruta local? | ✅ Sí (10.0.0.0/16 → local) |
| MySQL running | ¿Servicio MySQL iniciado? | A verificar |
| Puerto escuchando | ¿MySQL escucha en 0.0.0.0:3306? | A verificar |
Problema identificado:
Mirando sg-database:
Inbound: MySQL (3306) from sg-api
Está correcto. Pero veamos sg-api:
Inbound: TCP (8080) from sg-web
¿El sg-api no tiene acceso saliente explícito hacia MySQL? No, tiene Outbound: All traffic así que está OK.
Verificación más profunda: ¿El API server está realmente en sg-api?
aws ec2 describe-instances --filters "Name=private-ip-address,Values=10.0.11.30" \
--query 'Reservations[].Instances[].SecurityGroups'
Causa probable: ¡El API server puede que no esté adjuntado al Security Group correcto!
Ejercicio 4: Web Server no puede instalar paquetes
Síntoma: El web server no puede ejecutar yum update.
$ sudo yum update
Loaded plugins: priorities, update-motd, upgrade-helper
Could not retrieve mirrorlist https://... error was
12: Timeout on ...
Preguntas:
- ¿Por qué el servidor no puede acceder a Internet?
- Verifique la configuración de red.
- Proponga la solución.
💡 Solución Ejercicio 4
Análisis:
El Web Server está en el subnet privado (10.0.11.0/24) que usa rtb-private.
rtb-private:
10.0.0.0/16 → local
0.0.0.0/0 → nat-xyz789
¡La ruta hacia NAT Gateway existe! Verifiquemos:
Checklist NAT Gateway:
- ¿NAT Gateway en estado "available"?
aws ec2 describe-nat-gateways --nat-gateway-ids nat-xyz789
-
¿NAT Gateway en un subnet con IGW?
- NAT está en 10.0.1.0/24 (público) ✅
-
¿NAT Gateway tiene una Elastic IP?
- EIP: 52.4.5.6 ✅
-
¿El subnet público tiene la ruta hacia IGW?
- 0.0.0.0/0 → igw-abc123 ✅
Si todo está OK del lado NAT, verificar:
-
¿Security Group del NAT Gateway?
- NAT Gateway no tiene SG (es un servicio gestionado)
-
¿NACL del subnet privado permite salida?
Causa probable: NACL restrictivo en el subnet privado que bloquea el tráfico saliente o los puertos efímeros entrantes.
Solución:
# Verificar la NACL
aws ec2 describe-network-acls \
--filters "Name=association.subnet-id,Values=subnet-private"
# Asegurarse de que las reglas permitan:
# Outbound: 0.0.0.0/0 (todo el tráfico)
# Inbound: puertos efímeros 1024-65535 (para las respuestas)
Ejercicio 5: Database no recibe conexiones
Síntoma: Después de corregir el ejercicio 3, el log de la DB muestra 0 conexiones.
Configuración adicional revelada:
NACL del subnet database (acl-db):
┌────────┬──────────┬───────────┬─────────────┬────────┐
│ Rule # │ Type │ Port │ Source/Dest │ Action │
├────────┼──────────┼───────────┼─────────────┼────────┤
│ 100 │ Inbound │ 3306 │ 10.0.1.0/24 │ ALLOW │
│ * │ Inbound │ All │ 0.0.0.0/0 │ DENY │
├────────┼──────────┼───────────┼─────────────┼────────┤
│ 100 │ Outbound │ 1024-65535│ 10.0.1.0/24 │ ALLOW │
│ * │ Outbound │ All │ 0.0.0.0/0 │ DENY │
└────────┴──────────┴───────────┴─────────────┴────────┘
Preguntas:
- ¿Cuál es el problema con esta NACL?
- ¿Por qué las conexiones desde el API están bloqueadas?
- Corrija la NACL.
💡 Solución Ejercicio 5
Problema:
La NACL permite el tráfico MySQL (3306) solo desde 10.0.1.0/24 (subnet público).
Pero el API server está en 10.0.11.0/24 (subnet privado app)!
Rule 100 Inbound: 3306 from 10.0.1.0/24 → No incluye 10.0.11.0/24
Solución:
# Agregar una regla para el subnet app
aws ec2 create-network-acl-entry \
--network-acl-id acl-db \
--rule-number 110 \
--protocol tcp \
--port-range From=3306,To=3306 \
--cidr-block 10.0.11.0/24 \
--rule-action allow \
--ingress
# Agregar la regla outbound correspondiente
aws ec2 create-network-acl-entry \
--network-acl-id acl-db \
--rule-number 110 \
--protocol tcp \
--port-range From=1024,To=65535 \
--cidr-block 10.0.11.0/24 \
--rule-action allow \
--egress
Lección: Las NACL son stateless y muy precisas respecto a orígenes/destinos.
Parte 3: Ejercicio de Síntesis
Su Misión
Documente un procedimiento de solución de problemas completo para su equipo.
Cree un documento con:
-
Flowchart de diagnóstico: Árbol de decisión para problemas comunes
-
Comandos de verificación: Lista de comandos esenciales de AWS CLI
-
Checklist rápida: Lista de verificación para cada tipo de problema
-
Lecciones aprendidas: Errores comunes y cómo evitarlos
Plantilla de Entregable
# Procedimiento de Solución de Problemas de Red VPC
## 1. Flowchart de Diagnóstico
[Insertar su diagrama]
## 2. Comandos de Verificación
### Estado de las instancias
```bash
[Sus comandos]
Security Groups
[Sus comandos]
Rutas
[Sus comandos]
3. Checklist por Síntoma
Timeout desde Internet
- ...
- ...
Timeout hacia Internet
- ...
- ...
4. Lecciones Aprendidas
| Error Común | Cómo Evitarlo |
|---|---|
| ... | ... |
## Criterios de Evaluación
| Criterio | Puntos |
|----------|--------|
| Ejercicios 1-5 correctamente analizados | /50 |
| Flowchart claro y completo | /15 |
| Comandos pertinentes | /15 |
| Checklist utilizable | /10 |
| Lecciones aprendidas pertinentes | /10 |
| **Total** | **/100** |
---
*Próxima semana: [Publicación Web](../module_07/index.mdx)*