Cómo Encontrar Quién Eliminó un Recurso en AWS con CloudTrail
Una instancia EC2 desaparece en producción y nadie admite haberla terminado. Antes de escalar el incidente o revisar manualmente cada cuenta IAM, CloudTrail ya registró exactamente quién ejecutó TerminateInstances, desde qué IP y con qué credenciales. El problema no es que la información no exista — es saber dónde buscarla y cómo interpretarla correctamente.
TL;DR — Resumen Rápido
| Paso | Acción | Resultado esperado |
|---|---|---|
| 1 | Abrir CloudTrail Event History en la consola | Vista de eventos de los últimos 90 días |
| 2 | Filtrar por nombre de evento: TerminateInstances | Lista de eventos de terminación |
| 3 | Filtrar por ID de recurso o rango de tiempo | Evento específico de la instancia eliminada |
| 4 | Inspeccionar el campo userIdentity del evento | Usuario IAM, rol asumido, o cuenta raíz responsable |
| 5 | Verificar sourceIPAddress y userAgent | Contexto adicional del origen de la acción |
Cómo Funciona CloudTrail Event History
CloudTrail registra automáticamente las llamadas a la API de AWS realizadas en tu cuenta, incluyendo acciones desde la consola, el CLI, SDKs y servicios de AWS. El Event History es una vista integrada en la consola que muestra los últimos 90 días de eventos de gestión (management events) sin necesidad de configurar un trail adicional. No cubre eventos de datos (como operaciones S3 a nivel de objeto) a menos que tengas un trail configurado explícitamente para eso.
Cada evento registrado incluye un documento JSON estructurado con campos clave: quién realizó la acción (userIdentity), qué acción fue (eventName), sobre qué recurso (requestParameters), cuándo (eventTime), y desde dónde (sourceIPAddress). Para el caso de TerminateInstances, el campo requestParameters contendrá el o los IDs de instancia afectados.
- Actor: puede ser un usuario IAM, un rol asumido (via STS), la cuenta raíz, o un servicio AWS actuando en tu nombre.
- API Call: la acción
TerminateInstancesllega al endpoint de EC2 y es interceptada por CloudTrail antes de ejecutarse. - CloudTrail: registra el evento con todos sus metadatos y lo hace disponible en Event History dentro de aproximadamente 15 minutos.
- Event History: interfaz de consulta en la consola con retención de 90 días, sin costo adicional para management events.
- S3 / CloudWatch Logs: si tienes un trail configurado, los eventos también se envían aquí para retención extendida y análisis con Athena.
Paso 1 — Buscar el Evento TerminateInstances en CloudTrail
Navega a la consola de CloudTrail en la región donde existía la instancia EC2. CloudTrail es regional para los eventos de gestión estándar, así que si buscas en us-east-1 y la instancia estaba en eu-west-1, no encontrarás nada. Este error de región es el primer punto donde los ingenieros pierden tiempo innecesariamente.
En el panel izquierdo selecciona Event history. Verás un filtro desplegable que por defecto muestra 'Event name'. Cambia el valor del filtro a TerminateInstances y presiona Enter. Si conoces el rango de tiempo aproximado, ajusta el filtro de fecha para reducir el ruido.
Para hacer la misma búsqueda desde el CLI, lo cual es más reproducible y auditable:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=TerminateInstances \
--start-time 2024-01-15T00:00:00Z \
--end-time 2024-01-16T23:59:59Z \
--region us-east-1
El parámetro --region es obligatorio si tu configuración de CLI no apunta a la región correcta. El comando devuelve una lista paginada de eventos. Si hay muchos resultados, agrega --max-results para controlar el volumen inicial.
Paso 2 — Identificar la Instancia Específica con TerminateInstances
Si hubo múltiples terminaciones en ese período, necesitas filtrar por el ID de instancia específico. CloudTrail permite buscar por ResourceName usando el ID de instancia:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=ResourceName,AttributeValue=i-0abc123def456789 \
--region us-east-1
Esto devuelve todos los eventos asociados a esa instancia, no solo la terminación. Busca en la respuesta el evento con eventName igual a TerminateInstances. El campo CloudTrailEvent en la respuesta del CLI contiene el JSON completo del evento como string escapado — necesitarás parsearlo para leer los detalles.
Para extraer y formatear el evento directamente:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=ResourceName,AttributeValue=i-0abc123def456789 \
--region us-east-1 \
--query 'Events[?EventName==`TerminateInstances`].CloudTrailEvent' \
--output text | python3 -m json.tool
Esto imprime el JSON del evento de forma legible, lo que facilita identificar los campos clave sin tener que navegar por la consola.
Paso 3 — Interpretar el Campo userIdentity para Encontrar al Responsable
Aquí está el núcleo del análisis forense. El campo userIdentity tiene diferentes estructuras según el tipo de entidad que realizó la acción. Entender estas diferencias evita llegar a conclusiones incorrectas.
- IAMUser: un usuario IAM con credenciales de largo plazo. El campo
userNameidentifica directamente al responsable. - AssumedRole: una sesión de rol asumido via STS. El campo
sessionContext.sessionIssuermuestra el rol base, yarnincluye el nombre de sesión que puede revelar quién asumió el rol. - Root: la cuenta raíz de AWS. Si ves este tipo, es una señal de alerta operacional seria independientemente del contexto.
- AWSService: un servicio de AWS actuando en tu nombre, por ejemplo Auto Scaling terminando instancias por una política de escalado.
- FederatedUser: un usuario federado via SAML o OIDC. El ARN del proveedor de identidad estará presente.
Un ejemplo real de lo que verás para un rol asumido:
🔽 Ejemplo de userIdentity para AssumedRole (click para expandir)
{
'userIdentity': {
'type': 'AssumedRole',
'principalId': 'AROAEXAMPLEID:session-name',
'arn': 'arn:aws:sts::123456789012:assumed-role/DevOpsRole/maria.garcia',
'accountId': '123456789012',
'sessionContext': {
'sessionIssuer': {
'type': 'Role',
'principalId': 'AROAEXAMPLEID',
'arn': 'arn:aws:iam::123456789012:role/DevOpsRole',
'accountId': '123456789012',
'userName': 'DevOpsRole'
},
'attributes': {
'creationDate': '2024-01-15T14:23:00Z',
'mfaAuthenticated': 'false'
}
}
}
}
En este ejemplo, el nombre de sesión maria.garcia en el ARN de STS revela quién asumió el rol DevOpsRole. Este nombre de sesión es configurado por quien llama a sts:AssumeRole — si tu organización usa SSO o scripts de automatización, el nombre de sesión puede ser un email corporativo, un ID de pipeline de CI/CD, o cualquier string que el sistema de federación configure. No es un campo que AWS imponga — depende de cómo esté configurada la federación en tu organización.
Pensar en userIdentity como el equivalente al campo 'De:' en un correo electrónico: te dice quién envió el mensaje, pero si usaron un alias o un sistema de reenvío, necesitas seguir la cadena hasta el origen real.
Paso 4 — Verificar Contexto Adicional del Evento
Una vez identificado el actor, los campos sourceIPAddress y userAgent dan contexto sobre el origen de la acción. Si sourceIPAddress muestra una IP de AWS como elasticmapreduce.amazonaws.com o similar, significa que un servicio de AWS realizó la acción internamente. Si muestra una IP pública, puedes correlacionarla con VPN corporativas, oficinas, o rangos de IPs conocidos.
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=ResourceName,AttributeValue=i-0abc123def456789 \
--region us-east-1 \
--query 'Events[?EventName==`TerminateInstances`].{Time:EventTime,User:Username,Event:CloudTrailEvent}' \
--output json
El campo userAgent también puede revelar si la acción vino de la consola web (signin.amazonaws.com), del CLI (aws-cli/...), de Terraform, o de un SDK específico. Esta información no identifica al responsable de forma definitiva, pero ayuda a correlacionar con logs de acceso de otras herramientas.
El Error Clásico: Buscar en la Región Equivocada
El escenario más frustrante que se repite: el equipo pasa 30 minutos buscando en CloudTrail Event History sin encontrar nada, escalando el incidente, revisando permisos IAM — y el evento estaba en otra región todo el tiempo. CloudTrail Event History muestra eventos de la región donde estás consultando. Si la instancia EC2 estaba en ap-southeast-1 y buscas en us-east-1, el evento TerminateInstances simplemente no aparecerá.
La solución operacional correcta es tener un trail multi-región configurado que envíe todos los eventos a un bucket S3 centralizado. Con eso, puedes usar Athena para consultar eventos de cualquier región desde un único punto, sin depender de la región activa en la consola.
Si sospechas que la instancia podría haber sido terminada desde otra región o si simplemente no sabes la región exacta, verifica primero en qué región existía la instancia usando el historial de EC2 o etiquetas de recursos antes de buscar en CloudTrail.
IAM Necesario para Consultar CloudTrail
Para ejecutar los comandos anteriores, el usuario o rol que realiza la investigación necesita permisos sobre CloudTrail. Un ejemplo de política mínima para consultar Event History:
{
'Version': '2012-10-17',
'Statement': [
{
'Effect': 'Allow',
'Action': [
'cloudtrail:LookupEvents'
],
'Resource': '*'
}
]
}
La acción cloudtrail:LookupEvents no soporta restricción a nivel de recurso específico — requiere 'Resource': '*' según la documentación de autorización de servicios de AWS. Si también necesitas acceder a los archivos de log en S3 para análisis extendido, necesitarás permisos adicionales de s3:GetObject sobre el bucket donde el trail almacena los logs.
Cuándo Event History No Es Suficiente
Event History cubre 90 días y solo management events. Si el incidente ocurrió hace más de 90 días, o si necesitas buscar patrones a través de múltiples regiones y cuentas simultáneamente, necesitas un trail configurado con logs en S3 y opcionalmente CloudWatch Logs Insights o Athena para consultas estructuradas.
Para organizaciones con múltiples cuentas, AWS Organizations permite configurar un trail de organización desde la cuenta de gestión que captura eventos de todas las cuentas miembro en un bucket S3 centralizado. Esto elimina la necesidad de investigar cuenta por cuenta durante un incidente.
Próximos Pasos y Recursos
Una vez identificado el responsable, el siguiente paso operacional es revisar si la acción fue intencional, accidental, o resultado de credenciales comprometidas. Si hay indicios de compromiso, rota las credenciales inmediatamente y revisa otros eventos del mismo userIdentity en el mismo período de tiempo para identificar el alcance completo de las acciones realizadas.
Para fortalecer la postura de seguridad y evitar eliminaciones accidentales en el futuro, considera implementar EC2 Instance Termination Protection en instancias críticas y AWS Config Rules para detectar cambios de configuración no autorizados en tiempo real.
- Documentación oficial: CloudTrail Event History
- Ejemplos de archivos de log de CloudTrail
- Referencia del campo userIdentity en CloudTrail
Glosario de Términos Clave
| Término | Definición |
|---|---|
| CloudTrail Event History | Vista en consola de los últimos 90 días de management events de AWS, disponible sin configuración adicional. |
| userIdentity | Campo JSON en cada evento de CloudTrail que identifica la entidad (usuario IAM, rol, servicio) que realizó la acción. |
| AssumedRole | Tipo de identidad en CloudTrail que indica que la acción fue realizada por una sesión temporal de rol STS. |
| Management Events | Operaciones de control sobre recursos AWS (crear, modificar, eliminar). Distintos de los Data Events que cubren operaciones sobre datos. |
| Trail multi-región | Configuración de CloudTrail que captura eventos de todas las regiones AWS en un único destino, útil para auditoría centralizada. |
Comentarios
Publicar un comentario