배경
AWS 콘솔의 이벤트 기록(Event History)은 90일까지만 조회 가능합니다. 보안 감사나 장애 원인 추적 시 90일 이전 이력이 필요한 경우가 있어, CloudTrail + S3 + Athena 기반의 장기 감사 로그 분석 환경을 구축했습니다.
이후 개발팀에서 S3 버킷의 파일 접근 이력(업로드/다운로드/삭제)을 추적해야 하는 요구사항이 추가되어, S3 데이터 이벤트 추적과 SES 이메일 발송 이력 추적까지 확장했습니다. IAM User(Presigned URL)뿐 아니라 ECS Task Role을 통한 접근까지 포함하여 전체 접근 경로를 커버합니다.
구성 개요
AWS API 호출 → CloudTrail (추적) → S3 (JSON 로그 저장) → Athena (SQL 쿼리 분석)
계정 전체의 모든 관리 이벤트(Management Events)를 S3에 영구 저장하고, Athena로 SQL 쿼리하여 분석하는 구조입니다. 특정 S3 버킷에 대해서는 데이터 이벤트(Data Events)도 추가로 수집합니다.
CloudTrail 설정
| 항목 | 설정값 |
|---|---|
| Trail 이름 | management-events-trail |
| 멀티 리전 | 활성화 (모든 리전의 API 호출 기록) |
| 글로벌 서비스 이벤트 | 포함 (IAM 등) |
| 이벤트 유형 | 관리 이벤트 + S3 데이터 이벤트 (선택적) |
| 데이터 이벤트 대상 | oms-cloudedi-prod, oms-cloudedi-dev S3 버킷 |
S3 로그 저장소
| 항목 | 설정값 |
|---|---|
| 암호화 | AES256 (SSE-S3) |
| 퍼블릭 접근 | 전면 차단 |
| 로그 보존 기간 | 365일 (라이프사이클 자동 삭제) |
기존 이벤트 기록과의 차이
| 이벤트 기록 (기본 제공) | Trail (추적) | |
|---|---|---|
| 보존 기간 | 90일 | 365일 (S3 저장, 변경 가능) |
| S3 저장 | X | O |
| 90일 이후 조회 | 불가 | Athena로 조회 가능 |
| 장기 감사/컴플라이언스 | 불가 | 가능 |
| S3 객체 수준 추적 | 불가 | 데이터 이벤트 활성화 시 가능 |
| 추가 비용 | 무료 | S3 저장 비용만 (미미) |
Athena 분석 환경
구성 요소
| 항목 | 설정값 |
|---|---|
| Workgroup | cloudtrail-analysis |
| Database | cloudtrail_logs |
| Table | cloudtrail_events |
| 쿼리 결과 보존 | 30일 (라이프사이클 자동 삭제) |
사용 방법
- AWS 콘솔 → Athena → 쿼리 편집기
- Workgroup을
cloudtrail-analysis로 선택 - Database를
cloudtrail_logs로 선택 - "저장된 쿼리(Saved queries)" 탭에서 원하는 쿼리 선택 후 실행
저장된 쿼리 목록
| 쿼리명 | 용도 | 조회 기간 |
|---|---|---|
console-login-history | 콘솔 로그인 이력 (성공/실패) | 최근 24시간 |
root-account-activity | 루트 계정 사용 이력 | 최근 30일 |
security-group-changes | Security Group 규칙 변경 이력 | 최근 7일 |
iam-changes | IAM 사용자/정책/역할 변경 이력 | 최근 7일 |
ec2-instance-state-changes | EC2 시작/중지/종료 이력 | 최근 7일 |
api-error-events | API 호출 에러 (AccessDenied 등) | 최근 24시간 |
user-activity-summary | 사용자별 API 호출 통계 | 최근 7일 |
s3-oms-prod-presign-activity | Presigned URL 유저의 운영 S3 접근 이력 | 최근 7일 |
s3-oms-prod-taskrole-activity | ECS Task Role의 운영 S3 접근 이력 | 최근 7일 |
s3-oms-dev-presign-activity | Presigned URL 유저의 개발 S3 접근 이력 | 최근 7일 |
ses-oms-prod-email-activity | IAM 유저의 운영 SES 이메일 발송 이력 | 최근 7일 |
ses-oms-prod-taskrole-email-activity | ECS Task Role의 운영 SES 이메일 발송 이력 | 최근 7일 |
ses-oms-dev-email-activity | IAM 유저의 개발 SES 이메일 발송 이력 | 최근 7일 |
활용 시나리오
| 상황 | 사용할 쿼리 |
|---|---|
| 누가 SG를 변경해서 장애가 발생했는지 | security-group-changes |
| 비인가 접근 시도가 있었는지 | api-error-events |
| 루트 계정이 사용된 적 있는지 | root-account-activity |
| 특정 EC2가 누구에 의해 종료됐는지 | ec2-instance-state-changes |
| IAM 권한이 언제 누구에 의해 바뀌었는지 | iam-changes |
| 의심스러운 콘솔 로그인 확인 | console-login-history |
| OMS S3 파일 접근 이력 확인 | s3-oms-prod-presign-activity / s3-oms-prod-taskrole-activity |
| OMS SES 이메일 발송 이력 확인 | ses-oms-prod-email-activity / ses-oms-prod-taskrole-email-activity |
S3 데이터 이벤트 추적 — 파일 접근 감사
도입 배경
개발팀에서 Presigned URL을 통해 S3 버킷에 파일을 업로드/다운로드하는 서비스를 운영하고 있었습니다. 특정 IAM 유저가 언제, 어떤 파일에 접근했는지 추적해야 하는 감사 요구사항이 발생했습니다.
기존 관리 이벤트 Trail에 S3 데이터 이벤트를 추가하면 전체 S3 트래픽이 기록되어 비용이 급증할 수 있으므로, 특정 버킷(oms-cloudedi-prod, oms-cloudedi-dev)만 선택적으로 데이터 이벤트를 수집하도록 구성했습니다.
구성
IAM User (Presigned URL 발급)
→ S3 PutObject / GetObject / DeleteObject
→ CloudTrail (S3 데이터 이벤트)
→ S3 로그 저장
→ Athena SQL 쿼리
| 항목 | 설정값 |
|---|---|
| 추적 대상 | oms-cloudedi-prod, oms-cloudedi-dev S3 버킷 |
| 이벤트 유형 | S3 데이터 이벤트 (읽기 + 쓰기) |
| 추적 주체 | IAM User (Presigned URL 발급) + ECS Task Role |
저장된 쿼리
| 쿼리명 | 용도 |
|---|---|
s3-oms-prod-presign-activity | 운영 — IAM User(connectoms-presign-signer-prod)의 S3 접근 이력 |
s3-oms-prod-taskrole-activity | 운영 — ECS Task Role(htc-oms-connect-oms-taskrole-prod)의 S3 접근 이력 |
s3-oms-dev-presign-activity | 개발 — IAM User(connectoms-presign-signer-dev)의 S3 접근 이력 |
결과 컬럼
| 컬럼 | 설명 |
|---|---|
eventTime | API 호출 시각 (UTC) |
user_name | IAM 유저명 |
eventName | PutObject(업로드), GetObject(다운로드), DeleteObject(삭제), HeadObject(메타데이터 조회) |
requestParameters | 버킷명, 파일 경로(key) 등 상세 정보 (JSON) |
sourceIPAddress | 호출한 IP 주소 |
userAgent | 호출에 사용된 클라이언트 (SDK, 콘솔, Presigned URL 등) |
errorCode | 에러 발생 시 코드 (비어있으면 성공) |
조회 기간 변경
기본 쿼리는 최근 7일을 조회합니다. 기간을 변경하려면 쿼리의 WHERE 절을 수정합니다.
-- 최근 1일
AND from_iso8601_timestamp(eventTime) > current_timestamp - interval '1' day
-- 최근 30일
AND from_iso8601_timestamp(eventTime) > current_timestamp - interval '30' day운영 가이드
이 환경은 개발팀이 직접 사용할 수 있도록 가이드 문서를 작성하여 전달했습니다. Athena 콘솔에서 Workgroup 선택 → 저장된 쿼리 실행만으로 파일 접근 이력을 조회할 수 있어, SQL 지식 없이도 감사 업무를 수행할 수 있습니다.
SES 이메일 발송 이력 추적
도입 배경
S3 파일 접근 감사를 구축한 뒤, 동일한 IAM 유저가 SES를 통해 이메일을 발송하는 이력도 추적해야 하는 요구사항이 추가되었습니다.
SES API 호출(SendEmail, SendRawEmail 등)은 CloudTrail 관리 이벤트로 기록되므로, S3 데이터 이벤트처럼 별도 설정 없이 기존 Trail에서 바로 조회할 수 있습니다. IAM User뿐 아니라 ECS Task Role을 통한 발송도 추적합니다.
추적 대상
| 이벤트 | 설명 |
|---|---|
SendEmail | 일반 이메일 발송 |
SendRawEmail | Raw 형식 이메일 발송 |
SendTemplatedEmail | 템플릿 기반 이메일 발송 |
SendBulkTemplatedEmail | 대량 템플릿 이메일 발송 |
requestParameters에서 발신자(Source), 수신자(Destination), 제목(Subject)을 확인할 수 있고, responseElements에서 SES MessageId를 확인할 수 있습니다.
저장된 쿼리
| 쿼리명 | 용도 |
|---|---|
ses-oms-prod-email-activity | 운영 — IAM User(connectoms-presign-signer-prod)의 SES 발송 이력 |
ses-oms-prod-taskrole-email-activity | 운영 — ECS Task Role(htc-oms-connect-oms-taskrole-prod)의 SES 발송 이력 |
ses-oms-dev-email-activity | 개발 — IAM User(connectoms-presign-signer-dev)의 SES 발송 이력 |
S3 이력은 2026-04-08(데이터 이벤트 활성화 시점), SES 이력은 2026-04-06(Trail 생성 시점) 이후부터 조회 가능합니다.
커스텀 쿼리 예시
저장된 쿼리 외에 직접 SQL을 작성할 수도 있습니다.
-- 특정 사용자의 최근 활동 조회
SELECT eventTime, eventName, eventSource, sourceIPAddress
FROM cloudtrail_events
WHERE userIdentity.userName = '사용자명'
AND from_iso8601_timestamp(eventTime) > current_timestamp - interval '7' day
ORDER BY eventTime DESC
LIMIT 50;
-- 특정 IP에서의 모든 활동 조회
SELECT eventTime, userIdentity.userName, eventName, eventSource
FROM cloudtrail_events
WHERE sourceIPAddress = 'x.x.x.x'
AND from_iso8601_timestamp(eventTime) > current_timestamp - interval '7' day
ORDER BY eventTime DESC;
-- 특정 S3 버킷의 파일 삭제 이력 조회
SELECT eventTime, userIdentity.userName, eventName,
requestParameters
FROM cloudtrail_events
WHERE eventSource = 's3.amazonaws.com'
AND eventName = 'DeleteObject'
AND requestParameters LIKE '%bucket-name%'
AND from_iso8601_timestamp(eventTime) > current_timestamp - interval '30' day
ORDER BY eventTime DESC;비용
| 항목 | 예상 비용 |
|---|---|
| CloudTrail 관리 이벤트 (1개 Trail) | 무료 |
| CloudTrail S3 데이터 이벤트 | $0.10 / 100,000 이벤트 |
| S3 로그 저장 | 월 $0.025/GB (미미) |
| Athena 쿼리 | 스캔 1TB당 $5 (소규모 쿼리는 거의 무료) |
S3 데이터 이벤트는 특정 버킷만 선택적으로 활성화하여 비용을 최소화했습니다. 전체 버킷에 활성화하면 비용이 급증할 수 있으므로 주의가 필요합니다.
Athena 환경 확장 — VPC Flow Logs 분석
CloudTrail 분석용으로 구축한 Athena 환경(cloudtrail-analysis Workgroup)을 VPC Flow Logs 분석에도 활용하고 있습니다. NLB의 TCP 리스너 환경에서 Target Group별 트래픽을 확인해야 할 때, CloudWatch 메트릭이나 NLB 액세스 로그로는 불가능하여 VPC Flow Logs를 사용했습니다.
구성
NLB ENI → VPC Flow Logs → S3 → Athena (SQL 분석)
| 항목 | 설정값 |
|---|---|
| Table | vpc_flow_logs |
| 파티션 | 날짜별 자동 (Partition Projection) |
| 저장된 쿼리 | 테이블 생성, 포트별 트래픽 요약, 전체 포트 상위 20개 |
동일한 Workgroup과 Database에 테이블만 추가하여, 별도 인프라 없이 분석 환경을 확장할 수 있었습니다. CloudTrail 감사 로그와 VPC Flow Logs를 하나의 Athena 환경에서 통합 관리합니다.
정리
- CloudTrail로 모든 리전의 관리 이벤트를 S3에 365일 보존
- Athena로 SQL 기반 감사 로그 분석 환경 구축
- 7개 저장된 쿼리로 주요 보안 감사 시나리오 즉시 대응 가능
- S3 데이터 이벤트 추적으로 특정 버킷의 파일 접근 감사까지 확장 (IAM User + ECS Task Role)
- SES 이메일 발송 이력 추적으로 이메일 감사까지 확장 (IAM User + ECS Task Role, 관리 이벤트 활용)
- VPC Flow Logs 분석 환경도 동일한 Athena Workgroup에 통합 — NLB 포트별 트래픽 분석 등에 활용
- 개발팀이 직접 사용할 수 있는 셀프서비스 감사 환경 제공
- 비용은 S3 저장 비용 수준으로 거의 무료
- Terraform으로 전체 구성 코드화