Python으로 나만의 SIEM 만들기 - 시작편

SIEM Dashboard

들어가며

2024년, 한국인터넷진흥원(KISA)에 따르면 국내 사이버 공격 시도는 일평균 150만 건을 넘어섰습니다.
랜섬웨어, DDoS, APT 공격 등 점점 정교해지는 위협 속에서 기업들은 24시간 보안 관제(SOC)의 필요성을 절감하고 있습니다.

하지만 현실은 녹록지 않습니다.

  • Splunk: 연간 수천만 원 ~ 수억 원
  • IBM QRadar: 라이선스만 수백만 원
  • ArcSight: 구축 비용 1억 원 이상

중소기업이나 스타트업, 개인 학습자에게는 그림의 떡이죠.

그래서 저는 직접 만들기로 했습니다.

이 글은 제가 보안 관제 및 보안 서비스 개발 직무를 준비하면서 만든 Mini-SIEM (Security Information and Event Management) 프로젝트의 여정을 공유합니다.
오픈소스 기술 스택만으로 실무 수준의 SIEM을 구축하고, 실제 위협을 탐지하는 방법을 단계별로 알아봅니다.


SIEM이란 무엇인가?

정의

SIEM (시엠)은 Security Information and Event Management의 약자로,
조직 내 모든 보안 이벤트를 수집, 저장, 분석, 대응하는 통합 보안 관제 시스템입니다.

쉽게 말해, 수백 개 시스템에서 발생하는 로그를 한 곳에 모아 분석하는 "보안 관제 센터"라고 생각하면 됩니다.

핵심 기능

┌─────────────────────────────────────────────────────────┐
│                    SIEM 핵심 기능                         │
├─────────────────────────────────────────────────────────┤
│ 1. 수집 (Collection)                                     │
│    → 방화벽, 웹서버, DB, AD 등 다양한 로그 수집          │
│                                                          │
│ 2. 정규화 (Normalization)                                │
│    → 서로 다른 로그 형식을 표준 포맷으로 변환             │
│                                                          │
│ 3. 상관 분석 (Correlation)                               │
│    → 여러 이벤트를 연결하여 공격 패턴 탐지                │
│                                                          │
│ 4. 탐지 (Detection)                                      │
│    → 미리 정의된 룰로 위협 식별                          │
│                                                          │
│ 5. 알림 (Alerting)                                       │
│    → Slack, 이메일, SMS로 즉시 통보                       │
│                                                          │
│ 6. 대응 (Response)                                       │
│    → 자동 차단, 격리, 티켓 생성                          │
└─────────────────────────────────────────────────────────┘

상용 SIEM 제품들

제품특징연간 비용 (추정)
Splunk시장 점유율 1위, 강력한 검색5천만 원 ~ 3억 원
IBM QRadar금융권 많이 사용, AI 분석3천만 원 ~ 2억 원
ArcSight (Micro Focus)레거시 강함, 복잡함1억 원 ~ 5억 원
LogRhythm중소기업 친화적2천만 원 ~ 1억 원
Elastic SIEM오픈소스 기반, 상대적 저렴무료 ~ 5천만 원

참고: 비용은 로그 처리량(GB/일), 사용자 수, 유지보수 포함 여부에 따라 천차만별입니다.


왜 직접 만들었나?

1. 학습 목적

저는 보안 관제 및 보안 서비스 개발 직무를 준비하고 있습니다.

채용 공고를 보면 항상 나오는 요구사항:

  • "Splunk, QRadar 등 SIEM 운영 경험"
  • "로그 분석 및 위협 탐지 능력"
  • "인시던트 대응 프로세스 이해"

하지만 개인이 Splunk를 써볼 방법은 거의 없습니다. (Free Trial은 60일 제한)

직접 만들면서 배운 것들:

  • SIEM의 내부 동작 원리
  • 로그 정규화 (Log Normalization)
  • 상관 분석 (Correlation Rules)
  • MITRE ATT&CK 프레임워크
  • 인시던트 라이프사이클 관리

2. 비용 절감

개인 학습이나 소규모 프로젝트에 수천만 원은 부담스럽죠.

오픈소스 대안:

Splunk (1억 원)
    ↓
FastAPI + Elasticsearch + Kibana (무료!)

물론 상용 제품의 고급 기능(머신러닝, 자동 플레이북 등)은 없지만,
핵심 기능은 충분히 구현 가능합니다.

3. 커스터마이징 자유도

상용 제품은 정해진 틀 안에서만 작동합니다.

직접 만들면:

  • 원하는 로그 소스 자유롭게 추가
  • 탐지 룰을 내 환경에 최적화
  • 알림 채널 마음대로 설정 (Slack, Discord, Telegram...)
  • 새로운 기능 실험 가능 (ML 모델, 그래프 분석 등)

프로젝트 요구사항 정의

필수 기능 (Must Have)

  1. 로그 수집

    • REST API로 외부 시스템에서 로그 수신
    • 다양한 이벤트 타입 지원
  2. 위협 탐지

    • 룰 기반 탐지 (Rule-based Detection)
    • 최소 5개 이상의 실전 공격 패턴
  3. 실시간 알림

    • 위협 발견 즉시 Slack 알림
    • 심각도별 분류 (Critical, High, Medium, Low)
  4. 인시던트 관리

    • 탐지된 위협을 인시던트로 자동 생성
    • 상태 추적 (탐지됨 → 분석 중 → 해결됨)
  5. 대시보드

    • 실시간 통계 조회
    • 일일/주간 보안 리포트

선택 기능 (Nice to Have)

  • 🔲 머신러닝 기반 이상 탐지
  • 🔲 자동 IP 차단 (방화벽 연동)
  • 🔲 웹 UI 대시보드
  • 🔲 위협 인텔리전스 연동 (AbuseIPDB, VirusTotal)

기술 스택 선정

아키텍처 개요

┌─────────────────┐
│  외부 시스템     │  (로그 소스)
│  - 웹 서버       │
│  - 방화벽        │
│  - 데이터베이스  │
└────────┬────────┘
         │ HTTP POST (JSON)
         ▼
┌─────────────────────────────────────┐
│     FastAPI Application             │
│  ┌──────────────────────────────┐   │
│  │ /log   - 로그 수신            │   │
│  │ /dashboard - 실시간 통계      │   │
│  │ /incidents - 인시던트 관리    │   │
│  └──────────────────────────────┘   │
│          │                           │
│          ▼                           │
│  ┌──────────────────────────────┐   │
│  │  위협 탐지 엔진               │   │
│  │  - Brute Force               │   │
│  │  - SQL Injection             │   │
│  │  - Privilege Escalation      │   │
│  └──┬───────────────────────────┘   │
│     │                               │
│     ├─────────────┬─────────────┐   │
│     ▼             ▼             ▼   │
│  [로그저장]   [Slack알림]   [통계]  │
└─────┬───────────────────────────────┘
      │
      ▼
┌─────────────┐      ┌──────────────┐
│  Filebeat   │─────▶│Elasticsearch │
│ (로그 수집기)│      │ (로그 저장소) │
└─────────────┘      └──────┬───────┘
                            │
                            ▼
                     ┌──────────────┐
                     │    Kibana    │
                     │  (시각화)     │
                     └──────────────┘

기술 스택 상세

1. Backend: FastAPI (Python 3.10)

선택 이유:

성능

  • ASGI 기반 비동기 I/O
  • Django 대비 3-5배 빠름
  • Uvicorn으로 고성능 달성

개발 생산성

  • 자동 API 문서 생성 (Swagger UI)
  • Pydantic으로 타입 안전성
  • 코드 양이 Flask 대비 30% 적음

보안

  • 입력 검증 자동화
  • SQL Injection, XSS 사전 차단

대안 비교:

프레임워크성능학습 곡선문서화선택
FastAPI⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Flask⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Django⭐⭐⭐⭐⭐⭐⭐⭐

2. 로그 저장: Elasticsearch 8.15

선택 이유:

대용량 처리

  • 초당 수만 건 로그 색인
  • 페타바이트급 데이터 저장

전문 검색

  • 역인덱스로 빠른 텍스트 검색
  • 정규식, 퍼지 매칭 지원

실시간 분석

  • Near Real-Time (1초 이내)
  • Aggregation으로 통계 계산

실무 사례:

  • Uber: 하루 수조 건 로그
  • Netflix: 보안 이벤트 분석
  • GitHub: 코드 검색

대안 비교:

솔루션검색 속도확장성비용
Elasticsearch⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐무료 ✅
Splunk⭐⭐⭐⭐⭐⭐⭐⭐⭐매우 비쌈
PostgreSQL⭐⭐⭐⭐⭐무료

3. 로그 수집: Filebeat 8.15

선택 이유:

경량

  • Go 언어로 작성
  • CPU 사용률 < 1%

안정성

  • At-least-once 전송 보장
  • 네트워크 장애 시 재시도

Elastic Stack 통합

  • Elasticsearch와 네이티브 호환

대안:

  • Logstash: 너무 무거움 (Java 기반, 메모리 많이 사용)
  • Fluentd: 설정 복잡

4. 시각화: Kibana 8.15

선택 이유:

강력한 시각화

  • 드래그 앤 드롭 대시보드
  • 50+ 차트 타입

무료

  • 오픈소스 (Elastic License)

대안:

  • Grafana: 좋지만 Elasticsearch 연동 복잡
  • Tableau: 비쌈

5. 알림: Slack Webhook

선택 이유:

간편함

  • Webhook URL 하나면 끝
  • 별도 인증 불필요

실시간

  • 위협 탐지 즉시 알림

30분만에 시작해보기

1. 사전 요구사항

# 필수
✅ Docker 20.10 이상
✅ Docker Compose 1.29 이상

# 선택 (로컬 개발 시)
⭕ Python 3.10 이상
⭕ Git

2. 프로젝트 클론

git clone https://github.com/YOUR_USERNAME/mini-siem-log-monitoring.git
cd mini-siem-log-monitoring

3. 환경 설정

# .env 파일 생성
cp .env.example .env

# .env 파일 편집
nano .env

.env 파일 내용:

# Elasticsearch 비밀번호
ELASTIC_PASSWORD=changeme123!

# Slack Webhook URL (https://api.slack.com/messaging/webhooks)
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/YOUR/WEBHOOK/URL

# API 키 (원하는 문자열)
API_KEY=my-secret-api-key-2024

참고: Slack Webhook URL 생성 방법은 공식 문서 참조

4. 시스템 시작

# 모든 서비스 시작 (최초 실행 시 5-10분 소요)
docker-compose up -d

# 로그 확인
docker-compose logs -f fastapi_app

성공 메시지:

fastapi_app  | INFO:     Started server process [1]
fastapi_app  | INFO:     Waiting for application startup.
fastapi_app  | 🚀 Mini-SIEM Application Started
fastapi_app  | 🔐 API authentication enabled
fastapi_app  | INFO:     Application startup complete.
fastapi_app  | INFO:     Uvicorn running on http://0.0.0.0:8000

5. 동작 확인

1) API 서버 확인

curl http://localhost:8000/

# 응답:
{
  "message": "Mini-SIEM FastAPI Server is running.",
  "version": "2.0.0",
  "status": "healthy",
  "timestamp": "2025-11-11T10:30:00.123Z"
}

2) Swagger API 문서 접속

브라우저에서 http://localhost:8000/docs 접속

3) Kibana 대시보드 접속

브라우저에서 http://localhost:5601 접속

6. 첫 로그 전송해보기

정상 로그인 이벤트:

curl -X POST http://localhost:8000/log \
  -H "Content-Type: application/json" \
  -H "X-API-Key: my-secret-api-key-2024" \
  -d '{
    "event_type": "login_success",
    "source_ip": "192.168.1.10",
    "username": "john.doe",
    "count": 1,
    "description": "Successful login from office"
  }'

응답:

{
  "status": "ok",
  "log": {
    "timestamp": "2025-11-11T10:30:00.123Z",
    "event_type": "login_success",
    "severity": "info",
    "source_ip": "192.168.1.10",
    "username": "john.doe",
    "is_threat": false
  },
  "alert_sent": false
}

Brute Force 공격 시뮬레이션:

curl -X POST http://localhost:8000/log \
  -H "Content-Type: application/json" \
  -H "X-API-Key: my-secret-api-key-2024" \
  -d '{
    "event_type": "login_failed",
    "source_ip": "192.168.1.100",
    "username": "admin",
    "count": 8,
    "description": "Multiple failed login attempts"
  }'

응답:

{
  "status": "threat_detected",
  "log": {
    "timestamp": "2025-11-11T10:31:00.456Z",
    "event_type": "login_failed",
    "severity": "medium",
    "source_ip": "192.168.1.100",
    "is_threat": true,
    "threat_details": "Brute force attack detected: 8 failed login attempts from 192.168.1.100"
  },
  "incident_id": "INC-20251111-0001",
  "alert_sent": true
}

동시에 Slack으로 알림 전송됩니다!

🚨 [MEDIUM] Security Threat Detected
• Type: login_failed
• Source IP: 192.168.1.100
• Details: Brute force attack detected: 8 failed login attempts
• Incident ID: INC-20251111-0001

7. 대시보드 확인

<curl http://localhost:8000/dashboard

응답:

{
  "total_events": 2,
  "total_threats": 1,
  "critical_incidents": 0,
  "high_incidents": 0,
  "medium_incidents": 1,
  "low_incidents": 0,
  "active_incidents": 1,
  "resolved_incidents": 0,
  "top_attack_ips": ["192.168.1.100"],
  "top_event_types": {
    "login_success": 1,
    "login_failed": 1
  },
  "timestamp": "2025-11-11T10:32:00.789Z"
}

주요 기능 미리보기

1. 위협 탐지 룰 (7가지)

탐지 룰MITRE ATT&CK심각도
Brute Force AttackT1110Medium/High
SQL InjectionT1190Critical
Privilege EscalationT1548High
Suspicious Time AccessT1078Medium
Botnet ActivityT1571Medium
Known Malicious IPT1071Critical
File Access AnomalyT1005Medium/High

2. 인시던트 관리

탐지됨 (detected)
    ↓
분석 중 (analyzing)
    ↓
처리 중 (in_progress)
    ↓
해결됨 (resolved) / 오탐 (false_positive)

3. 실시간 리포트

  • 일일 보안 리포트
  • 주간 보안 리포트
  • 위협 타임라인
  • 상위 공격 IP 목록

다음 단계

시리즈 예고

이 프로젝트는 5편의 시리즈로 연재됩니다:

  1. [현재] Python으로 나만의 SIEM 만들기 - 시작편
  2. [다음편] MITRE ATT&CK 기반 위협 탐지 룰 구현하기
    • Brute Force 탐지 알고리즘
    • SQL Injection 정규식 설계
    • 임계값 설정의 과학
  3. FastAPI로 실시간 보안 이벤트 처리하기
  4. Elasticsearch로 대용량 로그 저장하고 검색하기
  5. 보안 설계 원칙을 코드로 구현하기

추가 학습 자료


마치며

"상용 SIEM이 없어서 보안을 못 하겠다"는 더 이상 변명이 아닙니다.

오픈소스와 약간의 코딩 실력만 있으면 누구나 실무 수준의 SIEM을 구축할 수 있습니다.

이 프로젝트를 통해:

  • ✅ SIEM의 내부 동작 원리를 이해했습니다
  • ✅ 실제 공격 패턴을 탐지하는 방법을 배웠습니다
  • ✅ 보안 관제 및 보안 서비스 개발 직무 역량을 입증할 포트폴리오를 만들었습니다

다음 편에서는 MITRE ATT&CK 프레임워크 기반 위협 탐지 룰을 상세히 다룹니다.

  • Brute Force 공격을 왜 5회로 설정했는가?
  • SQL Injection 정규식은 어떻게 설계했는가?
  • 오탐(False Positive)을 줄이는 방법은?

궁금하신 점이나 피드백은 댓글로 남겨주세요!


프로젝트 정보


💡 도움이 되셨다면 GitHub Star와 좋아요 부탁드립니다!
💬 질문이나 개선 아이디어가 있다면 댓글 또는 이슈로 남겨주세요!

0개의 댓글