SIEM · 보안관제 › A. SIEM 구조와 로그 수집 · 35/50편
학습 단계: 저장·파이프라인
실습 표기: 이 글의 명령어·출력·로그는 로컬 VMware 테스트 VM(Wazuh 4.x 올인원 / Rocky Linux 9 / Ubuntu 22.04) 기준의 「실습 예시」이며, IP·계정·호스트명은 가상의 값입니다.
Wazuh 매니저가 만든 Alert는 Filebeat가 읽어 인덱서로 보냅니다. 조직에 이미 ELK가 있거나 별도 가공이 필요하면, Filebeat와 저장소 사이에 Logstash를 두어 필터링·보강 후 Elasticsearch로 보내는 구성도 씁니다.
구성 비교
① 기본(Wazuh)
alerts.json → Filebeat(wazuh 모듈) → Wazuh indexer → Wazuh dashboard
② ELK 연계
alerts.json → Filebeat → Logstash(filter) → Elasticsearch → Kibana
③ 혼합
Wazuh indexer(관제) + Logstash 분기 → 다른 저장소(장기 보관·타 팀)
Logstash 기본 구조
input { beats { port => 5044 } }
filter { mutate / date / translate / geoip ... }
output { elasticsearch { hosts => ["https://es01:9200"] index => "wazuh-alerts-%{+YYYY.MM.dd}" } }
핵심: 경로가 길어질수록 장애 지점도 늘어난다 — 필요할 때만 Logstash
Logstash는 강력하지만 별도 운영 대상(메모리·큐·버전)이 하나 늘어납니다. 보강·분기가 꼭 필요한 경우에 도입하는 것이 현실적입니다.
| 구성요소 | 역할 | 점검 |
|---|---|---|
| Filebeat | alerts.json 읽기·전송 | filebeat test output |
| Logstash | 필터·보강·분기 | /_node/stats/pipelines |
| Elasticsearch | 저장·검색 | _cluster/health |
| Kibana | 시각화 | 인덱스 패턴 |
# 파이프라인 단계별 점검 (실습 예시)
sudo filebeat test config && sudo filebeat test output
# Logstash 파이프라인 처리량(입력·출력 이벤트 수)
curl -s localhost:9600/_node/stats/pipelines?pretty | grep -E '"in"|"out"|"filtered"' | head -6
# Elasticsearch 최신 문서 시각
curl -sk -u 'elastic:<비밀번호>' "https://es01:9200/wazuh-alerts-*/_search?size=1&sort=timestamp:desc&_source=timestamp" | grep -o '"timestamp":"[^"]*"'
filebeat output: talk to server... OK
logstash events in: 182,340 out: 182,340
ES 최신 문서: 수 초 전
각 단계의 입력·출력 수가 일치하고 최종 저장소의 최신 문서가 실시간에 가까우면 파이프라인이 정상입니다.
logstash events in: 182,340 out: 150,112 (filtered 단계 지연)
logstash log: [WARN] ... grok parse failure / pipeline worker blocked
ES 최신 문서: 40분 전
파이프라인 장애 위치 확인 흐름입니다(가상의 예시).
[alerts.json 증가] 매니저 정상?
↓
[Filebeat] test output · 레지스트리 오프셋 진행
↓
[Logstash] in/out/filtered 수 · 워커 경고
↓
[ES] 최신 문서 시각 · 쓰기 거부(bulk rejection)
↓
[Kibana] 인덱스 패턴·시간 범위
| 지점 | 증상 |
|---|---|
| Filebeat | 오프셋 정지 |
| Logstash | in ≠ out |
| ES | 쓰기 거부·red |
grok 실패 시 Logstash는 기본적으로 _grokparsefailure 태그를 붙이고 이벤트를 계속 보냅니다. 이 태그 건수를 집계하면 파싱 품질을 볼 수 있습니다(036편).
<!-- 실습 예시 룰: 적용 전 wazuh-logtest 및 테스트 환경 검증 필요 -->
<group name="local,siem_a,">
<rule id="110340" level="9">
<decoded_as>json</decoded_as>
<field name="check">^pipeline_lag$</field>
<field name="lag_minutes" type="pcre2">^([1-9][0-9]+)$</field>
<description>최종 저장소 반영 지연 10분 이상(파이프라인 병목)</description>
</rule>
</group>
최종 저장소의 최신 문서 시각과 현재 시각의 차이를 주기적으로 측정해 남긴다고 가정한 예시입니다. 지연은 단계별 처리량과 함께 보면 원인 지점을 빠르게 찾을 수 있습니다.
| 구성 | 용도 |
|---|---|
| Filebeat 직송 | 기본·단순 |
| Logstash 경유 | 보강·분기 |
| 점검 | 단계별 in/out |
| 원칙 | 필요할 때만 확장 |
| 면접 포인트 | "파이프라인이 길수록 장애 지점도 늘어난다 — 단계별 입력과 출력 수를 맞춰 본다" |
다음 편 036. SIEM·로그 수집 — Logstash 필터 — grok·mutate·date 에서는 Logstash에서 비정형 로그를 grok으로 분해하고 mutate로 필드명을 정규화하며 date로 원본 시각을 @timestamp에 맞추는 방법과 실패 처리 방법을 다룹니다.
이전 편: 034. SIEM·로그 수집 — 스토리지 용량 산정 — EPS와 일일 용량
📚 시리즈 전체 보기: SIEM · 보안관제