EC2 SSH Connection Timeout: Qué revisar en Security Groups para resolver el error
Lanzaste una instancia EC2, intentas conectarte por SSH y recibes un Connection timed out que no da ninguna pista sobre dónde está el problema. Este error de timeout en SSH es uno de los más frecuentes al trabajar con EC2, y casi siempre apunta a una capa de red bloqueando el tráfico antes de que llegue al sistema operativo — no a un problema con el servidor en sí.
TL;DR: Resumen rápido del diagnóstico
| Capa | Qué verificar | Herramienta |
|---|---|---|
| Security Group | Regla inbound TCP/22 desde tu IP | Consola AWS / CLI |
| Network ACL | Reglas inbound y outbound para TCP/22 | Consola VPC / CLI |
| Tabla de rutas | Ruta hacia Internet Gateway (0.0.0.0/0) | Consola VPC / CLI |
| IP pública | La instancia tiene Elastic IP o IP pública asignada | Consola EC2 |
| Subnet | La subnet es pública (auto-assign public IP activo) | Consola VPC |
Cómo funciona el flujo de red en EC2 antes de que llegue SSH
Antes de diagnosticar, hay que entender qué capas atraviesa un paquete TCP entrante hacia tu instancia. El error Connection timed out significa que el cliente TCP nunca recibió respuesta al SYN inicial — el paquete fue descartado silenciosamente en algún punto del camino. No es un rechazo explícito (que daría Connection refused), es una ausencia total de respuesta.
0.0.0.0/0 → igw"] NACL["Network ACL
(stateless)"] SG["Security Group
(stateful)"] EC2["EC2 Instance
puerto 22"] Internet -->|"SYN TCP/22"| IGW IGW --> RT RT -->|"subnet pública"| NACL NACL -->|"regla inbound ALLOW"| SG SG -->|"regla TCP/22 ALLOW"| EC2 style IGW fill:#FF9900,color:#000 style NACL fill:#1A73E8,color:#fff style SG fill:#E53935,color:#fff style EC2 fill:#2E7D32,color:#fff
- Internet Gateway: Punto de entrada a la VPC desde Internet. Sin él, ningún tráfico externo puede entrar.
- Route Table: La subnet donde vive la instancia debe tener una ruta
0.0.0.0/0 → igw-xxxxxxxx. Sin esta ruta, los paquetes no saben hacia dónde ir. - Network ACL: Filtro stateless a nivel de subnet. Evalúa inbound Y outbound por separado. Un ACL mal configurado puede bloquear el tráfico de retorno aunque el inbound esté permitido.
- Security Group: Filtro stateful a nivel de instancia. Si el inbound está permitido, el tráfico de retorno se permite automáticamente. Es la capa más frecuentemente mal configurada.
- IP pública: Si la instancia no tiene IP pública ni Elastic IP, simplemente no es alcanzable desde Internet.
Diagnóstico paso a paso del SSH Connection Timeout en EC2
Paso 1: Confirma que la instancia tiene IP pública asignada
Parece obvio, pero es el primer punto de falla silenciosa. Si lanzaste la instancia en una subnet donde 'Auto-assign public IPv4 address' estaba desactivado, la instancia existe pero es inalcanzable desde Internet sin una Elastic IP. Verifica el estado con CLI antes de seguir con las capas de red.
aws ec2 describe-instances \
--instance-ids i-0abcdef1234567890 \
--query 'Reservations[0].Instances[0].{PublicIP:PublicIpAddress,State:State.Name,SubnetId:SubnetId}' \
--output table \
--region us-east-1
Si PublicIP aparece como None, asigna una Elastic IP o relanza la instancia en una subnet con auto-assign activado. Sin IP pública, los pasos siguientes no tienen sentido.
Paso 2: Verifica las reglas inbound del Security Group
El Security Group es la causa más común del timeout. Necesitas una regla inbound que permita TCP en el puerto 22 desde tu dirección IP de origen. Muchos ingenieros crean la regla con el CIDR incorrecto — especialmente cuando su IP cambió desde la última vez que configuraron el SG, o cuando están detrás de un NAT corporativo.
aws ec2 describe-security-groups \
--group-ids sg-0123456789abcdef0 \
--query 'SecurityGroups[0].IpPermissions' \
--output json \
--region us-east-1
Busca en la salida una entrada con "FromPort": 22, "ToPort": 22, "IpProtocol": "tcp" y un rango CIDR que incluya tu IP actual. Para obtener tu IP pública actual:
curl -s https://checkip.amazonaws.com
Si la regla no existe o el CIDR no cubre tu IP, agrégala:
aws ec2 authorize-security-group-ingress \
--group-id sg-0123456789abcdef0 \
--protocol tcp \
--port 22 \
--cidr 203.0.113.25/32 \
--region us-east-1
Usar/32en lugar de0.0.0.0/0es la diferencia entre abrir una puerta para ti y dejar la puerta principal sin cerrojo. En producción, siempre restringe SSH a IPs conocidas o usa AWS Systems Manager Session Manager para eliminar la exposición del puerto 22 completamente.
Paso 3: Revisa el Network ACL de la subnet
Aquí está la trampa que atrapa a ingenieros con experiencia en Security Groups pero poca en ACLs. Los Network ACLs son stateless — evalúan inbound y outbound de forma independiente. Aunque el Security Group permita TCP/22 inbound (y el retorno es automático por ser stateful), el ACL de la subnet puede estar bloqueando el tráfico de respuesta en outbound si no tiene una regla explícita para puertos efímeros.
aws ec2 describe-network-acls \
--filters Name=association.subnet-id,Values=subnet-0abc123456789def0 \
--query 'NetworkAcls[0].{Inbound:Entries[?Egress==`false`],Outbound:Entries[?Egress==`true`]}' \
--output json \
--region us-east-1
Para inbound, necesitas una regla ALLOW para TCP/22 desde tu IP (o 0.0.0.0/0 si es un entorno de prueba). Para outbound, necesitas una regla ALLOW para el rango de puertos efímeros — en Linux el rango típico es 1024-65535 — hacia tu IP de origen. Si el ACL predeterminado de la VPC no fue modificado, tiene una regla ALLOW * que permite todo y no debería ser el problema. El problema aparece cuando alguien endureció el ACL sin considerar el tráfico de retorno.
Paso 4: Verifica la tabla de rutas de la subnet
Si los pasos anteriores están correctos y el timeout persiste, la subnet podría no tener ruta hacia Internet. Una subnet 'pública' en AWS no lo es por su nombre — lo es porque su tabla de rutas tiene una entrada que apunta al Internet Gateway de la VPC.
aws ec2 describe-route-tables \
--filters Name=association.subnet-id,Values=subnet-0abc123456789def0 \
--query 'RouteTables[0].Routes' \
--output table \
--region us-east-1
Busca una ruta con DestinationCidrBlock: 0.0.0.0/0 y GatewayId que empiece con igw-. Si no existe, la subnet es efectivamente privada y el tráfico SSH nunca llega a la instancia.
Paso 5: Confirma que el Internet Gateway está adjunto a la VPC
Menos frecuente, pero ocurre en entornos donde alguien desconectó el IGW o la instancia fue lanzada en una VPC sin IGW. Un IGW desconectado hace que la ruta 0.0.0.0/0 → igw-xxx quede en estado blackhole.
aws ec2 describe-internet-gateways \
--filters Name=attachment.vpc-id,Values=vpc-0abc123456789def0 \
--query 'InternetGateways[0].{IGW_ID:InternetGatewayId,State:Attachments[0].State}' \
--output table \
--region us-east-1
El campo State debe mostrar available. Si no hay resultados, la VPC no tiene Internet Gateway adjunto.
relanzar en subnet pública"] B -->|"Sí"| D{"¿SG tiene regla
inbound TCP/22?"} D -->|"No"| E["Agregar regla inbound
TCP/22 desde tu IP"] D -->|"Sí"| F{"¿Network ACL permite
inbound TCP/22 y
outbound efímeros?"} F -->|"No"| G["Agregar reglas ACL
inbound 22 + outbound 1024-65535"] F -->|"Sí"| H{"¿Route Table tiene
0.0.0.0/0 → IGW?"} H -->|"No"| I["Agregar ruta hacia
Internet Gateway"] H -->|"Sí"| J{"¿IGW adjunto
a la VPC?"} J -->|"No"| K["Adjuntar IGW a la VPC"] J -->|"Sí"| L["Revisar firewall local
o usar Session Manager"] style A fill:#E53935,color:#fff style C fill:#FF9900,color:#000 style E fill:#FF9900,color:#000 style G fill:#FF9900,color:#000 style I fill:#FF9900,color:#000 style K fill:#FF9900,color:#000 style L fill:#1A73E8,color:#fff
El caso que confunde: Security Group correcto, timeout igual
Síntoma: regla TCP/22 en el SG apunta a tu IP exacta, pero el timeout persiste. Diagnóstico inicial: 'el SG debe estar mal aplicado a la instancia'. Causa real: la instancia estaba en una subnet privada con una NAT Gateway — no un Internet Gateway — como ruta de salida. El tráfico de entrada nunca puede llegar a través de una NAT Gateway; esa ruta solo sirve para tráfico de salida iniciado desde la instancia.
La confusión viene de que la consola muestra la instancia con una IP privada y el SG correcto, pero nadie revisó si la subnet tenía ruta hacia un IGW o hacia un NGW. Son dos rutas visualmente similares en la consola pero con comportamientos opuestos para tráfico entrante.
La solución en ese caso no era modificar el SG — era mover la instancia a una subnet pública o usar AWS Systems Manager Session Manager para acceso sin exponer el puerto 22.
Alternativa recomendada: AWS Systems Manager Session Manager
Si tu caso de uso lo permite, Session Manager elimina la necesidad de abrir el puerto 22 en el Security Group. El acceso se realiza a través del plano de control de AWS, sin IP pública requerida y con registro de sesiones integrado en CloudWatch Logs o S3.
aws ssm start-session \
--target i-0abcdef1234567890 \
--region us-east-1
Requiere que el SSM Agent esté corriendo en la instancia (incluido por defecto en AMIs de Amazon Linux 2 y Amazon Linux 2023) y que el instance profile tenga adjunta la política AmazonSSMManagedInstanceCore.
IAM mínimo para ejecutar el diagnóstico por CLI
Si estás ejecutando estos comandos con un rol o usuario IAM con permisos restringidos, necesitas al menos los siguientes permisos de lectura:
🔽 Ver política IAM mínima para diagnóstico
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeSecurityGroups",
"ec2:DescribeNetworkAcls",
"ec2:DescribeRouteTables",
"ec2:DescribeInternetGateways"
],
"Resource": "*"
}
]
}
Las acciones Describe* de EC2 requieren "Resource": "*" — no admiten restricción por ARN de recurso específico según la Service Authorization Reference de AWS.
Wrap-up: Resolver SSH Connection Timeout en EC2 de forma sistemática
El error Connection timed out en SSH hacia EC2 casi siempre es una capa de red descartando el paquete silenciosamente. El orden de diagnóstico importa: primero confirma que la instancia es alcanzable (IP pública + ruta IGW), luego verifica el Security Group, luego el Network ACL. Saltarse capas lleva a modificar el SG correcto mientras el problema real está en la tabla de rutas.
Para entornos de producción, considera eliminar el puerto 22 del Security Group completamente y usar Session Manager — reduces la superficie de ataque y obtienes auditoría de sesiones sin costo adicional de infraestructura.
Documentación oficial de referencia: Autorizar acceso a instancias EC2 y AWS Systems Manager Session Manager.
Glosario de términos clave
| Término | Definición operacional |
|---|---|
| Security Group | Firewall stateful a nivel de instancia EC2. El tráfico de retorno se permite automáticamente si el inbound está autorizado. |
| Network ACL | Filtro stateless a nivel de subnet. Requiere reglas explícitas tanto para inbound como outbound, incluyendo puertos efímeros de retorno. |
| Internet Gateway (IGW) | Componente de VPC que permite comunicación bidireccional entre instancias con IP pública e Internet. |
| Puertos efímeros | Rango de puertos temporales (típicamente 1024-65535 en Linux) usados por el sistema operativo para el tráfico de retorno de conexiones TCP iniciadas desde el cliente. |
| Session Manager | Funcionalidad de AWS Systems Manager que permite acceso interactivo a instancias EC2 sin necesidad de abrir el puerto 22 ni gestionar claves SSH. |
Comentarios
Publicar un comentario