728x90

- 파일 I/O 중심 Syslog 구조를 벗어나기: Kafka 스트리밍 기반 Dedup 설계
- 보안 로그 대량 유입 대응을 위한 스트리밍 Dedup 파이프라인
- Raw 로그 보존과 운영 효율을 동시에 만족하는 보안 로그 Dedup 구조
- 대량 방화벽 트래픽 로그를 위한 실전 Kafka Dedup 아키텍처
- 보안 로그는 지우지 않고 요약한다: Raw 보존 기반 Dedup 전략
배경과 상황 정리
현재 운영 방식(문제의 출발점)
- 여러 개의 rsyslog 서비스를 각각 띄워서,
- 특정 송신지(IP) 또는 장비별로
- 서로 다른 디렉터리에 파일을 저장하는 구조로 운영 중이었습니다.
- 보안 솔루션(방화벽/EDR/DLP/AV 등)별로 로그가 분산 저장되어 관리가 복잡해지고,
- 특히 방화벽(FortiGate류)의 트래픽 로그처럼 대량 로그(EPS가 큰)가 들어오면서,
- 파일 쓰기 I/O가 커지고
- 저장비/분석비/탐지부하도 커지는 문제가 커졌습니다.
추가 요구(대량 로그 효율화)
- “동일 시간대(예: 1분)에는 동일한 흐름(src ip, dst ip, dst port)은 1건만 남기고 싶다”
- 즉,
- 단순히 “문자열이 완전히 같은 로그”를 줄이는 게 아니라,
- 필드 기반(키 기반) + 시간 윈도우 기반 중복제거(dedup)가 필요합니다.
- 파일로 기록 → 다시 읽어서 정제하면,
- 디스크 I/O + 시간 지연이 커져 실전 운영에서 부담이 됩니다.
목표 정의
최종 목표
- rsyslog를 단일 서비스(collector)로 통합
- 수신 로그를 Kafka로 Raw(원본) 저장
- 스트리밍 처리로 키/시간 윈도우 기반 Dedup 수행
- Dedup 결과를 별도 Kafka 토픽으로 분리(= 후단 저장/분석의 입력)
- Dedup 과정에서 “버려진 중복의 수(빈도)”를 통계로 별도 보존
기대 효과
- 파일 I/O 중심 구조에서 벗어나 파이프라인 기반 처리
- 대량 로그에서도
- Raw는 증적/재처리용으로 보관
- Dedup 로그만 SIEM/ES/저장소로 흘려 비용과 부하 대폭 절감
- “Dedup로 인해 정보가 사라지는 문제”는
- stats 토픽으로 “중복 횟수”를 보전해 운영 가시성 확보
설계 원칙(운영/보안 관점)
원본(Raw)과 정제(Dedup)를 분리
- Raw: 사고 대응/감사/재처리(룰 개선 후 과거 재분석)용 “증적”
- Dedup: 실시간 탐지/대시보드/분석/장기 저장의 “운영 효율”
Dedup은 “삭제”가 아니라 “요약”이어야 함
- 윈도우 내 최초 1건만 남기더라도,
- 같은 키로 몇 건이 중복되었는지(count)는 반드시 남겨야 합니다.
- 이렇게 해야 탐지/용량 최적화와 운영 신뢰성을 동시에 만족합니다.
확장성과 장애 내성을 기본값으로
- Kafka는 유입이 커져도 consumer/processor를 확장할 수 있고,
- raw 토픽에 쌓아두면 processor가 잠시 멈춰도 복구 후 따라잡기(catch-up)가 가능합니다.
“정석/확장형” 완전 구성안(End-to-End)
아래가 목표 아키텍처입니다.
300x250
- Syslog Collector (rsyslog 단일 서비스)
- TCP/UDP로 원격 syslog 수신(예: 2514/tcp)
- 라우팅 정책
- 1차: 송신지(IP) 기반
- 2차: 메시지 패턴 기반(백업)
- Forti 트래픽류 “대량” 로그는 파일로 쓰지 않고 Kafka로 바로 전송
- Kafka (Raw 토픽)
- 예:
logs.firewall.raw - syslog 원문 라인을 그대로 저장(또는 JSON으로 최소 변환)
- Stream Dedup Processor (Kafka Streams / Flink 중 택1)
- Raw를 소비(consuming)
- 파싱하여
src_ip,dst_ip,dst_port,event_time추출 - dedup key 생성
src_ip|dst_ip|dst_port|time_bucket
- 윈도우 내 최초 1건만 통과시켜
logs.firewall.dedup으로 전송 - 중복된 건수는
logs.firewall.dedup.stats로 별도 전송
- Kafka (Dedup 토픽)
logs.firewall.dedup: 운영용 이벤트logs.firewall.dedup.stats: 중복 제거 통계(운영 대시보드/튜닝 근거)
- 저장/분석
- SIEM / Elasticsearch / ClickHouse / Data Lake 등으로 적재
- 일반적으로는 Dedup만 적재하고, Raw는 필요 시 리플레이
rsyslog: 수신 + Forti 대량 로그는 Kafka로 전송
rsyslog 수신부 예시
- 포트:
2514/tcp - 작업 디렉터리:
/var/lib/syslog-collector
# /etc/rsyslog.conf (예시)
module(load="imtcp")
input(type="imtcp" port="2514")
global(workDirectory="/var/lib/syslog-collector")
$FileOwner syslog
$FileGroup syslog
$FileCreateMode 0640
$DirCreateMode 0750
$IncludeConfig /etc/rsyslog.d/*.conf
Forti 대량 로그를 Kafka Raw 토픽으로 보내기(예시)
- Kafka 브로커:
kafka-a.internal:9092,kafka-b.internal:9092,kafka-c.internal:9092 - Raw 토픽:
logs.firewall.raw
# /etc/rsyslog.d/20-firewall-to-kafka.conf (예시)
module(load="omkafka")
template(name="T_SYSLOG_RAWLINE" type="string"
string="%timereported:::date-rfc3339% %fromhost-ip% %hostname% %syslogtag%%msg%\n"
)
ruleset(name="rs_firewall_raw_to_kafka") {
action(
type="omkafka"
broker=["kafka-a.internal:9092","kafka-b.internal:9092","kafka-c.internal:9092"]
topic="logs.firewall.raw"
template="T_SYSLOG_RAWLINE"
# 성능/안정성(예시)
confParam=[
"compression.type=snappy",
"linger.ms=20",
"batch.num.messages=5000"
]
# 폭주 대비 큐(예시)
queue.type="LinkedList"
queue.size="200000"
queue.filename="q_firewall_kafka"
queue.saveOnShutdown="on"
action.resumeRetryCount="-1"
)
}
# 1차: 송신지 IP 기반 (예: 방화벽 syslog 송신 IP)
if ($fromhost-ip == "10.10.10.10") then {
call rs_firewall_raw_to_kafka
stop
}
# 2차: 패턴 기반 (IP 변경/NAT 대비)
if ($msg contains "type=traffic" and $msg contains "srcip=" and $msg contains "dstip=" and $msg contains "dstport=") then {
call rs_firewall_raw_to_kafka
stop
}
요점: “대량 로그는 파일로 쓰지 않고 Kafka로 직행”
(필요하면 소량 로그는 기존처럼 파일 저장도 병행 가능)
Kafka 토픽 설계 예시
- Raw:
logs.firewall.raw - Dedup:
logs.firewall.dedup - Dedup 통계:
logs.firewall.dedup.stats
권장 방향(예시)
- Raw는 짧은 보존(예: 7일) + 압축
- Dedup는 긴 보존(예: 30~90일) 또는 최종 저장소가 장기 보존
Stream Dedup 로직(핵심 개념 + 예시)
Dedup 정책 예시
- 윈도우: 60초(1분)
- dedup key
src_ip|dst_ip|dst_port|bucket_start_epoch
- 출력
- 최초 1건:
logs.firewall.dedup - 중복 카운트:
logs.firewall.dedup.stats
- 최초 1건:
입력 로그(예시) → 파싱 필드
예: raw 메시지(키=값 형태)
... type=traffic srcip=192.0.2.10 dstip=198.51.100.7 dstport=443 ...
추출
- src_ip =
192.0.2.10 - dst_ip =
198.51.100.7 - dst_port =
443 - event_time = (eventtime= 가 있으면 그 값, 없으면 수신시간/로그시간 사용)
Dedup 결과 예시(JSON)
logs.firewall.dedup로 내보내는 이벤트(예시)
{
"vendor": "firewall",
"src_ip": "192.0.2.10",
"dst_ip": "198.51.100.7",
"dst_port": 443,
"time_bucket_start": 1760000000,
"first_seen_time": "2026-01-15T12:34:05+09:00",
"sample_raw": "type=traffic srcip=192.0.2.10 dstip=198.51.100.7 dstport=443 ..."
}
logs.firewall.dedup.stats로 내보내는 통계(예시)
{
"dedup_key": "192.0.2.10|198.51.100.7|443|1760000000",
"time_bucket_start": 1760000000,
"suppressed_count": 1542
}
이렇게 하면 “중복은 줄였지만 빈도는 보존”되어
탐지/운영 리포트에서 “원래 얼마나 발생했는지”를 잃지 않습니다.
운영 계획(단계별 실행 시나리오)
1단계: rsyslog 단일화 + Kafka Raw 적재
- 기존 여러 rsyslog 인스턴스 → 단일 collector로 통합
- Forti 트래픽 로그만이라도 먼저 Kafka raw로 전환
- Raw 토픽에 정상 적재/유실 없는지 검증
- Kafka produce rate / rsyslog queue 적체 / 디스크 사용량 모니터링
2단계: Dedup Processor 도입
- Streams/Flink 중 선택(조직 역량/운영 도구에 맞춤)
- 윈도우 값 기본(예: 60초)으로 시작
- dedup + stats 토픽 동시 생성
- dedup 토픽을 SIEM/ES로 연결
3단계: 튜닝(효율 극대화)
- 윈도우 조정(60초 → 10초 등)
- dedup key 확장(필요 시)
- 예:
proto,action,policyid등 추가 (다만 key가 커질수록 dedup 효과 감소 가능)
- 예:
- “중요 이벤트는 dedup 제외” 규칙 추가
- 예:
action=deny또는 특정 threat/event는 dedup 없이 모두 남기기
- 예:
보안/점검 포인트
접근통제
- syslog 수신 포트(예: 2514)는 장비 allowlist 기반으로 제한
- Kafka는
- rsyslog collector는 produce 권한만
- dedup processor는 raw consume + dedup produce 권한만
- 최소권한(least privilege)으로 토픽 ACL 분리
무결성과 증적
- Raw 토픽은 “최소 기간”이라도 유지해서 사고 시 재처리 가능하게
- Dedup로 손실되는 “빈도”는 stats로 반드시 보전
장애/폭주 대비
- Kafka 장애 시 rsyslog 큐가 얼마나 버틸지(디스크/용량) 계산
- Processor 장애 시 raw가 쌓이고, 복구 후 따라잡을 수 있도록 consumer lag 모니터링
- 저장소(ES/SIEM) 장애와 분리: dedup 토픽이 “완충 역할”
어떤 형태로 “완성”으로 볼 것인가(성공 기준)
- Forti 트래픽 기준
- Raw EPS 대비 Dedup EPS가 의미 있게 감소(예: 10배~100배까지도 가능)
- stats 토픽을 통해
- “줄인 양”을 수치로 증명 가능(운영 리포트/비용절감 근거)
- 사고 대응 시
- Raw 리플레이로 정책 변경 후 재분석 가능
추가로 바로 적용 가능한 “현실적인 예외 규칙” 예시
Dedup을 무조건 적용하면 위험한 케이스가 있습니다. 예를 들어,
action=deny/threat/ips이벤트는 dedup 제외
- 공격은 “반복”이 의미이므로 오히려 반복 수가 중요할 수 있음
- 특정 VIP 시스템 대상으로 가는 트래픽은 dedup 축소(더 많이 남김)
- 특정 시간대(장애/사고 대응 중)는 dedup 완화/해제
이런 규칙을 Streams에서 분기하면 운영 안정성이 크게 올라갑니다.
728x90
그리드형(광고전용)
댓글