CloudTrail 감사 로깅
"누가, 언제, 무엇을 했는지 모든 기록을 남기자"
이 문서는 강사용 답안입니다. 학생에게 공유하지 마세요. 각 단계의 정확한 답과 해설, 트러블슈팅 가이드가 포함되어 있습니다.
Step 1: CloudTrail 이벤트 기록 확인
답안
웹 콘솔 방법
- AWS 콘솔에서 CloudTrail 서비스로 이동
- 좌측 메뉴에서 이벤트 기록(Event history) 클릭
- 기본적으로 최근 이벤트가 시간 역순으로 표시됨
- 필터 드롭다운을 "이벤트 이름"으로 변경
RunInstances입력 후 Enter - EC2 인스턴스 생성 기록 확인- 검색된 이벤트 행을 클릭하면 상세 JSON 이벤트 레코드를 확인 가능
- JSON에서 다음 항목을 확인:
userIdentity.userName- 작업을 수행한 IAM 사용자eventTime- 작업 수행 시간 (UTC)sourceIPAddress- 요청을 보낸 IP 주소requestParameters- 요청에 사용된 파라미터
같은 방법으로 다른 이벤트도 검색해 봅니다:
CreateBucket- S3 버킷 생성 이벤트CreateRole- IAM 역할 생성 이벤트CreateDBInstance- RDS 인스턴스 생성 이벤트
AWS CLI 방법
# EC2 인스턴스 생성(RunInstances) 이벤트 조회
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=RunInstances \
--max-results 5 \
--region ap-northeast-2
# S3 버킷 생성(CreateBucket) 이벤트 조회
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=CreateBucket \
--max-results 5 \
--region ap-northeast-2
# IAM 역할 생성(CreateRole) 이벤트 조회
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=CreateRole \
--max-results 5 \
--region ap-northeast-2
# 결과를 보기 좋게 포맷팅
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=RunInstances \
--max-results 3 \
--region ap-northeast-2 \
--query "Events[].{Time:EventTime, Name:EventName, User:Username, Source:EventSource}" \
--output table
- 무료: 추가 비용 없이 최근 90일간의 관리 이벤트를 조회할 수 있습니다
- 자동 활성화: AWS 계정을 만들면 이벤트 기록이 자동으로 활성화됩니다. Trail을 생성하지 않아도 사용 가능합니다
- 관리 이벤트만: 리소스 생성/변경/삭제 등 관리 작업만 기록됩니다. 데이터 이벤트(S3 GetObject 등)는 포함되지 않습니다
- 90일 제한: 90일이 지난 이벤트는 자동 삭제됩니다. 장기 보관이 필요하면 Trail을 생성해야 합니다
Step 2: CloudTrail 추적(Trail) 생성
답안
웹 콘솔 방법
- AWS 콘솔에서 CloudTrail 서비스로 이동
- 좌측 메뉴에서 추적(Trails) 클릭
- 추적 생성(Create trail) 클릭
- 일반 세부 정보:
- 추적 이름:
ShopEasy-Trail - 스토리지 위치: 새 S3 버킷 생성 선택
- 추적 로그 버킷 이름:
shopeasy-cloudtrail-{ACCOUNT_ID} - 로그 파일 SSE-KMS 암호화: 활성화됨 (체크)
- AWS KMS 고객 관리형 키: 새로 만들기 또는 기존 (기본 aws/s3 키 사용)
- 로그 파일 검증: 활성화됨 (기본값 유지)
- 추적 이름:
- 다음 클릭
- 이벤트 선택:
- 이벤트 유형: 관리 이벤트 체크 (기본값)
- 관리 이벤트 → API 활동: 읽기와 쓰기 모두 체크
- 다음 클릭
- 검토 화면에서 설정 확인 후 추적 생성 클릭
- 추적 상태가 로깅 중(Logging)인지 확인
AWS CLI 방법
# 계정 ID 확인
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
echo "Account ID: $ACCOUNT_ID"
# 1. CloudTrail 로그용 S3 버킷 생성
aws s3api create-bucket \
--bucket shopeasy-cloudtrail-${ACCOUNT_ID} \
--region ap-northeast-2 \
--create-bucket-configuration LocationConstraint=ap-northeast-2
# 2. S3 버킷 정책 설정 (CloudTrail이 버킷에 로그를 쓸 수 있도록 허용)
cat > /tmp/cloudtrail-bucket-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSCloudTrailAclCheck",
"Effect": "Allow",
"Principal": {
"Service": "cloudtrail.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::shopeasy-cloudtrail-${ACCOUNT_ID}"
},
{
"Sid": "AWSCloudTrailWrite",
"Effect": "Allow",
"Principal": {
"Service": "cloudtrail.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::shopeasy-cloudtrail-${ACCOUNT_ID}/AWSLogs/${ACCOUNT_ID}/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
EOF
aws s3api put-bucket-policy \
--bucket shopeasy-cloudtrail-${ACCOUNT_ID} \
--policy file:///tmp/cloudtrail-bucket-policy.json
# 3. CloudTrail 추적 생성
aws cloudtrail create-trail \
--name ShopEasy-Trail \
--s3-bucket-name shopeasy-cloudtrail-${ACCOUNT_ID} \
--is-multi-region-trail \
--region ap-northeast-2
# 4. 로깅 시작
aws cloudtrail start-logging \
--name ShopEasy-Trail \
--region ap-northeast-2
# 5. 추적 상태 확인
aws cloudtrail get-trail-status \
--name ShopEasy-Trail \
--region ap-northeast-2
# 6. 추적 설정 확인
aws cloudtrail describe-trails \
--trail-name-list ShopEasy-Trail \
--region ap-northeast-2
웹 콘솔에서 Trail을 생성하면 S3 버킷과 버킷 정책이 자동으로 설정됩니다. 하지만 CLI로 생성할 때는 다음 작업을 수동으로 해야 합니다:
- S3 버킷 생성: CloudTrail 로그를 저장할 버킷을 먼저 만들어야 합니다
- 버킷 정책 설정: CloudTrail 서비스가 버킷에 로그를 쓸 수 있도록 권한을 부여해야 합니다
- Trail 생성: 버킷 준비가 완료된 후에야 Trail을 생성할 수 있습니다
- 로깅 시작: Trail을 생성한 후
start-logging을 호출해야 실제로 로깅이 시작됩니다
| Statement | Action | 설명 |
|---|---|---|
AWSCloudTrailAclCheck |
s3:GetBucketAcl |
CloudTrail이 버킷의 ACL을 확인하여 쓰기 권한이 있는지 검증 |
AWSCloudTrailWrite |
s3:PutObject |
CloudTrail이 로그 파일을 버킷에 저장. AWSLogs/{ACCOUNT_ID}/* 경로만 허용 |
보안 포인트: Condition의 s3:x-amz-acl: bucket-owner-full-control은
CloudTrail이 저장하는 로그 파일의 소유권이 버킷 소유자에게 있음을 보장합니다.
| 옵션 | 설명 | 권장 설정 |
|---|---|---|
--is-multi-region-trail |
모든 리전의 이벤트를 기록 | 활성화 (단일 리전만 사용해도 권장) |
| SSE-KMS 암호화 | S3에 저장되는 로그를 암호화 | 활성화 (보안 Best Practice) |
| 로그 파일 검증 | 로그가 변조되지 않았음을 확인하는 무결성 검증 | 활성화 (컴플라이언스 필수) |
| 관리 이벤트 읽기/쓰기 | 읽기(Describe, List 등)와 쓰기(Create, Delete 등) 이벤트 | 모두 활성화 |
Step 3: 추적 로그 S3 버킷 확인
답안
웹 콘솔 방법
- AWS 콘솔 → S3 서비스로 이동
shopeasy-cloudtrail-{ACCOUNT_ID}버킷 클릭- 폴더 구조를 순서대로 탐색:
AWSLogs/클릭{ACCOUNT_ID}/클릭CloudTrail/클릭ap-northeast-2/클릭- 오늘 날짜 폴더 (
YYYY/MM/DD/) 클릭
.json.gz확장자의 로그 파일이 있으면 성공- 로그 파일을 다운로드하여 압축을 풀면 JSON 형태의 이벤트 기록을 확인할 수 있음
Trail 생성 후 첫 번째 로그 파일이 S3에 도착하기까지 5~15분 소요됩니다. 파일이 보이지 않으면 잠시 기다린 후 새로고침하세요.
AWS CLI 방법
# 계정 ID 확인
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
# S3 버킷 내용 확인 (재귀적으로 첫 10개 파일)
aws s3 ls s3://shopeasy-cloudtrail-${ACCOUNT_ID}/ --recursive | head -10
# 특정 날짜의 로그 파일 확인 (오늘 날짜로 변경)
TODAY=$(date +%Y/%m/%d)
aws s3 ls s3://shopeasy-cloudtrail-${ACCOUNT_ID}/AWSLogs/${ACCOUNT_ID}/CloudTrail/ap-northeast-2/${TODAY}/
# 로그 파일 다운로드 및 내용 확인 (첫 번째 파일)
FIRST_LOG=$(aws s3 ls s3://shopeasy-cloudtrail-${ACCOUNT_ID}/ --recursive | head -1 | awk '{print $4}')
if [ -n "$FIRST_LOG" ]; then
aws s3 cp s3://shopeasy-cloudtrail-${ACCOUNT_ID}/${FIRST_LOG} /tmp/cloudtrail-log.json.gz
gunzip -f /tmp/cloudtrail-log.json.gz
python3 -m json.tool /tmp/cloudtrail-log.json | head -50
fi
shopeasy-cloudtrail-{ACCOUNT_ID}/
AWSLogs/
{ACCOUNT_ID}/
CloudTrail/
ap-northeast-2/ <-- 리전별 폴더
2024/
12/
15/ <-- 날짜별 폴더
{ACCOUNT_ID}_CloudTrail_ap-northeast-2_20241215T0930Z_xxxxx.json.gz
{ACCOUNT_ID}_CloudTrail_ap-northeast-2_20241215T0935Z_xxxxx.json.gz
...
- 로그 파일은 리전별 → 연도별 → 월별 → 일별로 정리됩니다
- 각 파일은 약 5분 단위로 생성되며,
.json.gz(gzip 압축 JSON) 형식입니다 - 파일 이름에 타임스탬프가 포함되어 있어 시간대별로 식별이 가능합니다
- Multi-region Trail을 활성화하면 다른 리전의 로그도 함께 저장됩니다
Step 4: 특정 이벤트 검색
답안
웹 콘솔 방법
- AWS 콘솔 → CloudTrail → 이벤트 기록
- 필터 드롭다운에서 검색 기준 선택:
- 이벤트 이름으로 검색:
CreateBucket입력 - S3 버킷 생성 이벤트 확인 - 이벤트 이름으로 검색:
CreateTrail입력 - 방금 만든 Trail 생성 이벤트 확인
- 이벤트 이름으로 검색:
- 검색된 이벤트를 클릭하여 상세 JSON 확인
- JSON에서 다음 핵심 필드를 확인:
userIdentity→ 누가 이 작업을 수행했는지eventTime→ 언제 수행했는지sourceIPAddress→ 어디서(어떤 IP에서) 수행했는지eventName→ 어떤 API를 호출했는지requestParameters→ 어떤 파라미터를 사용했는지responseElements→ 결과는 무엇인지
다른 필터도 시도해 봅니다:
- 사용자 이름으로 검색: 본인의 IAM 사용자 이름 입력 → 해당 사용자의 모든 활동 조회
- 리소스 유형으로 검색:
AWS::S3::Bucket입력 → S3 관련 모든 이벤트 조회
AWS CLI 방법
# CreateBucket 이벤트 검색
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=CreateBucket \
--region ap-northeast-2
# CreateTrail 이벤트 검색 (방금 만든 Trail 생성 기록)
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=CreateTrail \
--region ap-northeast-2
# 특정 사용자의 활동 검색
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=Username,AttributeValue=admin \
--max-results 10 \
--region ap-northeast-2
# 결과를 보기 좋게 요약
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=Username,AttributeValue=admin \
--max-results 10 \
--region ap-northeast-2 \
--query "Events[].{Time:EventTime, Event:EventName, Source:EventSource}" \
--output table
# 시간 범위 지정 검색 (예: 오늘 하루)
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=CreateTrail \
--start-time $(date -u -d "today 00:00:00" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v0H -v0M -v0S +%Y-%m-%dT%H:%M:%SZ) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
--region ap-northeast-2
| AttributeKey | 설명 | 예시 값 |
|---|---|---|
EventName |
API 호출 이름으로 검색 | RunInstances, CreateBucket |
Username |
IAM 사용자 이름으로 검색 | admin, developer |
ResourceType |
리소스 유형으로 검색 | AWS::S3::Bucket, AWS::EC2::Instance |
ResourceName |
리소스 이름/ID로 검색 | i-0abcdef1234567890 |
EventSource |
AWS 서비스로 검색 | s3.amazonaws.com, ec2.amazonaws.com |
ReadOnly |
읽기 전용 여부로 검색 | true (읽기), false (쓰기) |
{
"eventVersion": "1.08",
"userIdentity": {
"type": "IAMUser",
"principalId": "AIDAEXAMPLE",
"arn": "arn:aws:iam::123456789012:user/admin",
"accountId": "123456789012",
"userName": "admin"
},
"eventTime": "2024-12-15T09:30:00Z",
"eventSource": "cloudtrail.amazonaws.com",
"eventName": "CreateTrail",
"awsRegion": "ap-northeast-2",
"sourceIPAddress": "203.0.113.50",
"userAgent": "aws-cli/2.x Python/3.x",
"requestParameters": {
"name": "ShopEasy-Trail",
"s3BucketName": "shopeasy-cloudtrail-123456789012",
"isMultiRegionTrail": true
},
"responseElements": {
"name": "ShopEasy-Trail",
"s3BucketName": "shopeasy-cloudtrail-123456789012",
"trailARN": "arn:aws:cloudtrail:ap-northeast-2:123456789012:trail/ShopEasy-Trail"
}
}
읽는 법: IAM 사용자 admin이 2024-12-15 09:30(UTC)에 IP 주소 203.0.113.50에서 AWS CLI를 사용하여 ShopEasy-Trail이라는 CloudTrail 추적을 생성했다.
트러블슈팅 가이드
자주 발생하는 문제와 해결 방법
원인: CLI로 Trail을 생성할 때 S3 버킷이 없거나 버킷 정책이 설정되지 않음
해결 방법:
- S3 버킷이 존재하는지 확인
- 버킷 정책에 CloudTrail 서비스의
s3:GetBucketAcl과s3:PutObject권한이 있는지 확인 - 웹 콘솔에서 Trail을 생성하면 S3 버킷과 정책이 자동으로 설정되므로, CLI로 어려우면 콘솔 사용을 권장
# 버킷 존재 확인
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
aws s3api head-bucket --bucket shopeasy-cloudtrail-${ACCOUNT_ID}
# 버킷 정책 확인
aws s3api get-bucket-policy \
--bucket shopeasy-cloudtrail-${ACCOUNT_ID} \
--output text | python3 -m json.tool
# 버킷이 없으면 생성
aws s3api create-bucket \
--bucket shopeasy-cloudtrail-${ACCOUNT_ID} \
--region ap-northeast-2 \
--create-bucket-configuration LocationConstraint=ap-northeast-2
원인: CLI로 Trail을 생성한 후 start-logging을 실행하지 않음
해결 방법:
# 로깅 상태 확인
aws cloudtrail get-trail-status \
--name ShopEasy-Trail \
--region ap-northeast-2
# IsLogging이 false이면 로깅 시작
aws cloudtrail start-logging \
--name ShopEasy-Trail \
--region ap-northeast-2
# 다시 상태 확인
aws cloudtrail get-trail-status \
--name ShopEasy-Trail \
--region ap-northeast-2 \
--query "{IsLogging:IsLogging, LatestDeliveryTime:LatestDeliveryTime}"
웹 콘솔에서 Trail을 생성하면 로깅이 자동으로 시작됩니다. CLI에서는 create-trail 후 반드시 start-logging을 실행해야 합니다.
원인: Trail 생성 직후이거나, 로깅이 시작되지 않았음
해결 방법:
- Trail 생성 후 첫 번째 로그 파일이 S3에 도착하기까지 5~15분 소요됩니다. 잠시 기다린 후 확인하세요
- Trail의 로깅 상태가 활성(Logging: true)인지 확인
- S3 버킷 이름이 Trail 설정과 일치하는지 확인
- 어떤 API 호출이라도 발생해야 로그가 생성됩니다 (콘솔에서 아무 서비스를 조회하면 이벤트가 발생합니다)
# Trail 로깅 상태 확인
aws cloudtrail get-trail-status \
--name ShopEasy-Trail \
--region ap-northeast-2
# 마지막 로그 전달 시간 확인 (LatestDeliveryTime이 있으면 정상)
aws cloudtrail get-trail-status \
--name ShopEasy-Trail \
--region ap-northeast-2 \
--query "{IsLogging:IsLogging, LatestDeliveryTime:LatestDeliveryTime, LatestDeliveryError:LatestDeliveryError}"
# API 호출을 발생시켜 로그 생성 유도
aws sts get-caller-identity
aws s3 ls
# 5분 후 S3 버킷 다시 확인
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
aws s3 ls s3://shopeasy-cloudtrail-${ACCOUNT_ID}/ --recursive | head -5
원인: 이벤트가 아직 반영되지 않았거나, 데이터 이벤트를 검색하고 있음
해결 방법:
- 이벤트가 이벤트 기록에 반영되기까지 최대 15분 소요될 수 있습니다
- 이벤트 기록은 관리 이벤트만 표시합니다. S3 GetObject(파일 다운로드), PutObject(파일 업로드) 같은 데이터 이벤트는 표시되지 않습니다
- 필터 값의 대소문자가 정확한지 확인하세요 (예:
RunInstances(O),runinstances(X)) - 이벤트 이름이 정확한지 확인하세요 (예: EC2 생성은
RunInstances이지,CreateInstance가 아닙니다)
# 최근 이벤트 목록 확인 (최근 10개)
aws cloudtrail lookup-events \
--max-results 10 \
--region ap-northeast-2 \
--query "Events[].{Time:EventTime, Event:EventName, User:Username}" \
--output table
# 주요 관리 이벤트 이름 참고:
# EC2 인스턴스 생성: RunInstances
# EC2 인스턴스 종료: TerminateInstances
# S3 버킷 생성: CreateBucket
# S3 버킷 삭제: DeleteBucket
# IAM 역할 생성: CreateRole
# IAM 정책 연결: AttachRolePolicy
# RDS 인스턴스 생성: CreateDBInstance
# CloudTrail 추적 생성: CreateTrail
원인: 설정이 잘못되었거나, 다시 처음부터 하고 싶음
해결 방법:
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
# 1. 로깅 중지
aws cloudtrail stop-logging \
--name ShopEasy-Trail \
--region ap-northeast-2
# 2. Trail 삭제
aws cloudtrail delete-trail \
--name ShopEasy-Trail \
--region ap-northeast-2
# 3. (선택) S3 버킷의 기존 로그 삭제 후 버킷 삭제
aws s3 rm s3://shopeasy-cloudtrail-${ACCOUNT_ID} --recursive
aws s3api delete-bucket \
--bucket shopeasy-cloudtrail-${ACCOUNT_ID} \
--region ap-northeast-2
# 4. 다시 처음부터 Step 2를 수행
원인: S3 버킷 이름은 전 세계에서 유일해야 하는데, 이미 같은 이름이 존재
해결 방법:
- 버킷 이름에 계정 ID를 포함했는지 확인 (
shopeasy-cloudtrail-{ACCOUNT_ID}) - 이미 본인이 만든 버킷이 있을 수 있으므로
aws s3 ls | grep cloudtrail로 확인 - 필요시 다른 이름을 사용 (예:
shopeasy-trail-logs-{ACCOUNT_ID})
# 기존 버킷 확인
aws s3 ls | grep cloudtrail
# 이미 있으면 해당 버킷을 사용하여 Trail 생성
# 또는 다른 이름으로 버킷 생성
- CLI에서 start-logging을 빼먹음 -
create-trail만으로는 로깅이 시작되지 않습니다. 반드시start-logging을 실행해야 합니다 - 로그가 바로 안 보인다고 당황 - CloudTrail은 약 5분 간격으로 로그를 배치 전달합니다. Trail 생성 직후에는 5~15분 기다려야 합니다
- 데이터 이벤트와 관리 이벤트를 혼동 - 이벤트 기록에서 S3 PutObject(파일 업로드)를 찾으려 하는 경우가 있습니다. 이벤트 기록은 관리 이벤트만 표시합니다
- 이벤트 이름의 대소문자 오류 - API 이름은 대소문자를 구분합니다.
RunInstances가 맞고runinstances는 검색되지 않습니다 - CLI에서 버킷 정책 설정을 건너뜀 - 콘솔에서는 자동이지만, CLI에서는 버킷 정책을 직접 설정해야 Trail이 로그를 쓸 수 있습니다
- 리전 설정 누락 - CLI 명령에
--region ap-northeast-2를 빼먹으면 기본 리전에서 실행됩니다