수집은 끝났습니다. 남은 과제는 "무엇을, 어떤 형태로 집계하여 시각화할 것인가"입니다.
WAF 로그의 수집·저장은 이미 완료되어 있습니다. 다음 과제는 이 데이터를 어떻게 시각화·분석할 것인가입니다.
QuickSight SPICE는 빠르지만 데이터셋당 용량 한도가 있습니다. raw를 그대로 넣으면 며칠치밖에 담지 못합니다.
| SPICE에 넣는 형태 | 일일 크기(추정) | 2TB(Enterprise) 기준 보관 |
|---|---|---|
| raw 상세 전체 | ~200 GB | 약 10일 |
| 축소 상세 · 차단중심 · 컬럼 프루닝 | 10–30 GB | 70–200일 |
| 집계 · 시간 × 저카디널리티 | 수십 MB | 수년 (실질 무제한) |
| 테이블 | 집계 단위 |
|---|---|
hourly_overview | hour×action×source×country×rule |
hourly_attack_type | hour×attack_category×action |
top_client_ip_daily | day×clientIp(Top-N)×action |
| WAF 로그 필드 | 집계 역할 |
|---|---|
timestamp | 시간 차원 (hour) |
action | 차원 · ALLOW/BLOCK/COUNT |
labels | 공격 유형 차원 · SQLi/XSS/Bot |
terminatingRuleId | 차원 · Rule별 |
httpRequest.country | 차원 · 국가 |
httpSourceName | 차원 · CF/ALB |
(행 수) | 측정값 · request/blocked_count |
clientIp | 측정(distinct) · Top-N |
uri · User-Agent | Top-N · 고카디널리티 |
INSERT INTO curated.waf_hourly_overview SELECT date_trunc('hour', ts) AS hour, action, country, terminatingRuleId, httpSourceName, count(*) AS request_count, count_if(action='BLOCK') AS blocked_count, approx_distinct(clientIp) AS distinct_ip FROM cleaned.waf WHERE month=? AND day=? AND hour=? -- 증분 GROUP BY 1,2,3,4,5;
| 결정 항목 | 선택지 | 비고 |
|---|---|---|
| 집계 엔진 | 안 A · Athena 권장 / 안 B · Glue | 다음 장에서 안별 비교 |
| curated 저장 포맷 | S3 Parquet · 집계 결과, 소량 | 단순 · 저렴 |
| 데이터 신선도 | SPICE(시간) / Direct Query(분) / CloudWatch(초·알림) | 실시간 수집 ≠ 실시간 시각화 |
| 보관 기간 | 상세 vs 집계 각각 · 롤링 윈도우 | SPICE 누적 한계 대응 |
SQL만으로 집계·서빙. EventBridge로 무인 배치.
인프라 없음 → 저성숙 고객에 가장 적합.
단순 GROUP BY엔 충분 — WAF에 적합.
Spark — 대규모 조인·다단계·커스텀 로직.
단순 집계엔 기동 오버헤드로 Athena보다 비쌈.
Job 스크립트·스케줄·DPU 튜닝 관리.
시작은 안 A(Athena) + SPICE로 단순하게. 옵션(미래)으로 Amazon Quick agentic·Bedrock 연계로 확장합니다.
직전 시간 파티션 · 필요 컬럼만 raw에서 읽음.
hour GROUP BY로 request/blocked/distinct_ip 계산.
clientIp·uri·UA는 일 Top-N으로 분리(폭증 방지).
curated에 CTAS/INSERT, EventBridge로 매시간.
curated만 읽어 위젯 렌더 → raw 직접조회 없이 빠르게.
위 대시보드 위젯을 채우는 컬럼·타입·설명입니다. WAF 원천 로그 컬럼과 집계 시 생성되는 파생 컬럼으로 나뉩니다.
| 컬럼 | 타입 | 설명 | 출처 |
|---|---|---|---|
timestamp | bigint | 요청 시각(epoch ms) | WAF |
action | string | ALLOW/BLOCK/COUNT | WAF |
terminatingRuleId | string | 매칭 Rule ID | WAF |
httpSourceName | string | CLOUDFRONT/ALB | WAF |
clientIp | string | 클라이언트 IP | WAF |
country | string | ISO 국가코드 | WAF |
uri | string | 요청 경로 | WAF |
httpMethod | string | GET/POST/… | WAF |
| 컬럼 | 타입 | 설명 | 출처 |
|---|---|---|---|
headers[UA] | string | User-Agent | WAF |
labels | array | 공격유형 라벨 | WAF |
hour | timestamp | 시간 버킷 | 파생 |
attack_category | string | SQLi/XSS/Bot | 파생 |
request_count | bigint | 요청 수 | 파생 |
blocked_count | bigint | 차단 수 | 파생 |
distinct_ip | bigint | 고유 IP 수 | 파생 |
hour·attack_category·request_count 같은 파생 컬럼만 집계 시 생성해 curated 테이블에 저장합니다.| 질의 예시 | 사용 컬럼 | 출처 |
|---|---|---|
| 급증 공격 유형 | labels,action | WAF파생 |
| 출처 국가 Top | country,action | WAF |
| SQLi 일별 추이 | labels,hour | 파생 |
| 차단율 높은 URI | uri,action | WAF |
| Top 차단 IP | clientIp,action | WAF |
| 봇 트래픽 변화 | labels(Bot),hour | 파생 |
| 단계 | 내용 | 산출물 |
|---|---|---|
| P0 · 현황 측정 | 카디널리티 측정, Managed Rule·라벨 확인, SPICE 한도·에디션 확인, 컬럼 프루닝 진단 | 측정 결과 + 임시 대시보드 |
| P1 · MVP 집계 | 안 A(Athena)로 표준 집계 3종 증분 ETL · EventBridge 스케줄 | curated 테이블 |
| P2 · 대시보드 | SPICE 대시보드 · 개요·위협·출처 | 운영 대시보드 |
| P3 · 보안·거버넌스 | RLS, KMS, 접근 거버넌스 · 사용자별 권한 | 정책 |
| P4 · 확장 | URI/UA Top-N, Rate-based, 경영진 리포트, 롤링·롤업 | 확장 뷰 |
| P5 · 궁극 (옵션) | Amazon Quick agentic · 자연어 질의 + Bedrock 에이전트 연계 | agentic 워크스페이스 |
카디널리티 · Rule · SPICE 한도 확인.
표준 집계 3종 + SPICE 대시보드.
SPICE / Direct Query 신선도 결정.
감사합니다 · 김도형, Solutions Architect, AWS