
AWS CloudTrail은 내 계정의 모든 활동을 기록하는 블랙박스이자 CCTV다.
누가, 언제, 어디서, 어떤 리소스에 무슨 작업을 했는지 API 호출 단위로 기록하여 완벽한 감사 추적(Audit Trail)을 제공한다.
계정의 거버넌스, 규정 준수, 운영 및 위험 감사를 위한 필수 서비스이며, 특히 침해 사고 발생 시 원인을 분석하고 대응하는 첫 단추 역할을 한다. 이 글에서는 CloudTrail의 핵심 개념과 실전 분석 쿼리, 최신 기능까지 정리한다.
AWS 계정 내에서 발생하는 API 호출과 활동을 이벤트(Event) 형태로 기록하고 모니터링하는 서비스다.
사용자가 콘솔, SDK, CLI를 통해 수행하는 모든 작업(EC2 인스턴스 생성, S3 버킷 삭제, IAM 사용자 정책 변경 등)이 로그로 남는다.
단순 기록을 넘어서 보안 분석, 리소스 변경 추적, 규정 준수 감사의 핵심 데이터가 된다.
| 유형 | 설명 | 예시 | 기본 상태 |
|---|---|---|---|
| 관리 이벤트 | 리소스 생성/삭제/수정 같은 제어 작업 | RunInstances, DeleteBucket | ✅ 활성화됨 |
| 데이터 이벤트 | 리소스 내부 데이터 접근 | GetObject, PutObject, Invoke | ❌ 비활성화 (선택적 설정) |
CloudTrail 로그로 다음과 같은 이상 징후를 탐지할 수 있다:
ConsoleLogin 이벤트에서 해외 IP 등 AccessDenied 이벤트가 급증하면서 iam:* API 호출 시도 StopLogging, UpdateDetector 이벤트 DeleteObject, RunInstances 등 CloudTrail 로그를 S3에 저장하고 Athena로 쿼리하면 실시간 분석이 가능하다.
SELECT
eventtime,
sourceipaddress,
useridentity.type AS user_type,
useridentity.arn AS user_arn,
eventsource,
eventname
FROM
"your_cloudtrail_table"
WHERE
eventname = 'ConsoleLogin'
AND errorcode IS NULL AND errormessage IS NULL
AND sourceipaddress NOT IN ('203.0.113.10', '198.51.100.20')
ORDER BY eventtime DESC
LIMIT 100;
SELECT
useridentity.arn AS user_arn,
eventname,
eventsource,
COUNT(*) AS attempt_count
FROM
"your_cloudtrail_table"
WHERE
errorcode = 'AccessDenied'
AND (
eventname LIKE 'Create%' OR
eventname LIKE 'Delete%' OR
eventname LIKE 'Attach%' OR
eventname LIKE 'Put%'
)
AND eventsource = 'iam.amazonaws.com'
GROUP BY
useridentity.arn,
eventname,
eventsource
ORDER BY attempt_count DESC
LIMIT 50;
| eventName | 설명 |
|---|---|
ConsoleLogin | AWS 콘솔 로그인 시도 (성공/실패 포함) |
AssumeRole | STS를 통한 임시 자격 증명 획득 |
CreateUser | IAM 사용자 생성 |
AttachUserPolicy | 사용자에게 정책 연결 |
PutUserPolicy | 인라인 정책 직접 추가 |
UpdateLoginProfile | IAM 사용자 비밀번호 변경 |
CreateAccessKey | 액세스 키 생성 (비밀 키 노출 위험) |
DeleteAccessKey | 액세스 키 삭제 |
StopLogging | CloudTrail 로깅 중지 시도 |
StartLogging | CloudTrail 로깅 시작 |
PutBucketPolicy | S3 버킷 정책 변경 |
GetObject | S3 객체 조회 (데이터 이벤트) |
PutObject | S3 객체 업로드 (데이터 이벤트) |
RunInstances | EC2 인스턴스 실행 |
TerminateInstances | EC2 인스턴스 종료 |
CreateSecurityGroup | 보안 그룹 생성 |
AuthorizeSecurityGroupIngress | 보안 그룹 인바운드 규칙 추가 |
UpdateDetector | GuardDuty 설정 변경 (비활성화 시도 탐지에 사용) |
| errorCode | 설명 |
|---|---|
AccessDenied | 권한 부족으로 API 호출 실패 |
UnauthorizedOperation | 루트 또는 IAM 권한 부족 |
ThrottlingException | 호출 제한(쿼터) 초과 |
EntityAlreadyExists | 이미 존재하는 엔티티 (예: 사용자, 역할 등) |
NoSuchEntity | 없는 리소스에 접근 시 발생 |
ServiceUnavailable | AWS 서비스 일시적 중단 또는 내부 오류 |
InvalidClientTokenId | 잘못된 액세스 키 ID 사용 |
ExpiredToken | 세션 토큰 또는 자격 증명 만료 |
RequestLimitExceeded | 요청 횟수 초과 |
MalformedPolicyDocument | 잘못된 정책 JSON 형식 |
-- 최근 발생한 이벤트 이름 상위 50개
SELECT eventname, COUNT(*) AS cnt
FROM your_cloudtrail_table
GROUP BY eventname
ORDER BY cnt DESC
LIMIT 50;
-- 최근 30일간 발생한 AccessDenied 이벤트
SELECT *
FROM your_cloudtrail_table
WHERE errorcode = 'AccessDenied'
AND eventtime >= current_date - interval '30' day;
year, month, day, region, account_id 등의 디렉토리 기준으로 로그 저장 MSCK REPAIR TABLE 또는 Partition Projection 기능 활용 SELECT * FROM cloudtrail_logs
WHERE year = '2025' AND month = '08'
AND eventname = 'DeleteBucket';
1. Amazon GuardDuty
2. AWS Config
3. AWS Security Hub