Saltar al contenido principal

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.

Enfoque pedagógico

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:

  1. ¿Cuál es el problema más probable?
  2. ¿Qué comando usaría para verificar?
  3. ¿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:

  1. ¿Por qué el administrador usa la IP privada desde Internet?
  2. ¿Cuál es el verdadero problema de arquitectura aquí?
  3. ¿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:

  1. El administrador intenta acceder a una IP privada desde Internet (imposible)
  2. El web server no tiene IP pública
  3. 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:

  1. Crear un Application Load Balancer en el subnet público
  2. Configurar un Target Group con el web server
  3. 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:

  1. Enumere todas las causas posibles.
  2. ¿Cómo verificaría cada hipótesis?
  3. ¿Cuál es la causa más probable según la configuración?
💡 Solución Ejercicio 3

Hipótesis y verificaciones:

HipótesisVerificaciónResultado
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:

  1. ¿Por qué el servidor no puede acceder a Internet?
  2. Verifique la configuración de red.
  3. 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:

  1. ¿NAT Gateway en estado "available"?
aws ec2 describe-nat-gateways --nat-gateway-ids nat-xyz789
  1. ¿NAT Gateway en un subnet con IGW?

    • NAT está en 10.0.1.0/24 (público) ✅
  2. ¿NAT Gateway tiene una Elastic IP?

    • EIP: 52.4.5.6 ✅
  3. ¿El subnet público tiene la ruta hacia IGW?

    • 0.0.0.0/0 → igw-abc123 ✅

Si todo está OK del lado NAT, verificar:

  1. ¿Security Group del NAT Gateway?

    • NAT Gateway no tiene SG (es un servicio gestionado)
  2. ¿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:

  1. ¿Cuál es el problema con esta NACL?
  2. ¿Por qué las conexiones desde el API están bloqueadas?
  3. 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:

  1. Flowchart de diagnóstico: Árbol de decisión para problemas comunes

  2. Comandos de verificación: Lista de comandos esenciales de AWS CLI

  3. Checklist rápida: Lista de verificación para cada tipo de problema

  4. 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únCó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)*