728x90
Wazuh Manager의 “queue full” 문제를 해소하고, NGINX stream 로드밸런서로 라운드로빈 분산을 적용하는 과정을 점검→완화→근본개선→모니터링 순서로 정리한 가이드입니다. 근거·배경, 보안 관점 점검포인트, 구체 예시(명령/설정)까지 담았습니다.
목표
analysisd
,remoted
등 내부 큐 포화(Queue full) 원인 파악·완화- 이벤트 유입량(throughput) ≤ 처리량(processing) 상태로 복원
- NGINX stream 라운드로빈을 통한 수평 분산으로 구조적 대응
- 변경 후 드롭/지연 없는 안정 운영 + 모니터링/알림 체계 수립
빠른 진단 체크리스트 (10분 점검)
- 증상 확인
- 대표 징후:
queue is full
,messages dropped
,analysisd: … decode queue full
,remoted: queue size exceeded
등# 경고/오류 및 큐 포화 로그 확인 sudo tail -n 2000 -f /var/ossec/logs/ossec.log | egrep -i "queue|full|drop|overrun|delay|backpressure|WARNING|ERROR"
- 대표 징후:
- CPU/메모리/IO 병목 확인
vmstat 1 5 iostat -xz 1 5 top -H -p $(pgrep -d',' -f wazuh-manager)
- 유입량 vs 처리량 대략 추정
- “최근 5~10분 간 초당 이벤트 수(EPS) > Manager 처리 가능 EPS?”
- 급증 원인: 신규 에이전트 대거 등록, noisy 로그(디버그/트레이스), 실시간 FIM 폭증, 스캐너/크롤러 등
즉시 완화 (팀 간 조정 없이 적용 가능한 변경)
1. 내부 큐 및 스레드 튜닝 (Manager)
파일: /var/ossec/etc/internal_options.conf
⚠️ Wazuh 버전에 따라 세부 키가 다를 수 있습니다. 제공한 항목이 유효한지 ossec.log 경고 여부로 검증하세요.
원복 대비를 위해 사전 백업 필수.
# 분석 파이프라인 병렬 처리도 늘림
analysisd.event_threads = 4
analysisd.syscheck_threads = 2
analysisd.syscollector_threads = 2
analysisd.rootcheck_threads = 2
analysisd.hostinfo_threads = 2
# 디코더 큐(입력 큐) 확대
analysisd.decode_queue_size = 16384
# 원격 수신 큐 확대 (기본 131072 → 524288)
remoted.queue_size = 524288
스레드는 CPU 코어 수 내에서 점진 증가(2→4→8…). 과도 증가는 컨텍스트 스위칭 비용↑
- 큐는 메모리 여유를 보며 2배씩 상향·재시작·관찰(“증분 적용” 권장)
2. ossec.conf 전역 메모리·출력 제한 상향
파일: /var/ossec/etc/ossec.conf
<ossec_config>
<global>
<memory_size>8192</memory_size> <!-- MB 단위가 아닌 Wazuh 내부 단위. 버전별 해석 주의 -->
<max_output_size>65536</max_output_size> <!-- 과도히 크면 OOM 위험. 점진 상향 -->
</global>
<analysisd>
<stats_maxdiff>999000</stats_maxdiff>
<stats_mindiff>1</stats_mindiff>
<stats_level>8</stats_level> <!-- 통계 상세도↑ (문제 시 롤백) -->
</analysisd>
</ossec_config>
3. 시스템 커널 파라미터 (옵션)
Wazuh는 주로 유저 공간 큐/소켓을 사용합니다. 다만 시스템 전반의 IPC/SHM 제한이 타 서비스와 경합 시 병목이 될 수 있습니다. 아래 값은 여유치 확대 목적이며, 적용 전/후 모니터링 필수.
파일: /etc/sysctl.conf
# (옵션) 메시지 큐 상한
kernel.msgmnb = 1048576
kernel.msgmax = 1048576
kernel.msgmni = 2048
# (옵션) 공유 메모리 상한
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
적용
sudo sysctl -p
4. 재시작
sudo systemctl restart wazuh-manager
근본 개선: 유입 자체를 줄이고, 구조적으로 분산
1. 노이즈 컷 (수집 소스 다이어트)
- 불필요 로그 제외: 애플리케이션/시스템 로그 중 보안 의미 낮은 패턴 필터링
<ossec_config> <localfile> <log_format>syslog</log_format> <location>/var/log/syslog</location> <!-- 특정 이벤트/패턴 제외 --> <ignore binop="match">noise_pattern</ignore> </localfile> </ossec_config>
- FIM(파일 무결성) 빈도·범위 최적화
<syscheck> <frequency>86400</frequency> <!-- 1일 주기 --> <realtime>no</realtime> <!-- 실시간 OFF (필요 경로에만 ON) --> <!-- 대용량/변화 잦은 디렉터리는 제외 --> <!-- <ignore>/var/tmp</ignore> 등 전략적 제외 --> </syscheck>
- 에이전트 측면 감량: 디버그 레벨↓, 대용량 앱 로그 롤테이션/샘플링 적용
🔐 보안 관점 Tip
- “제외(ignorance)”는 보안 블라인드가 될 수 있음. 위험지표 기반으로 필터링(예: DEBUG 잡음 제거, ERROR/SECURITY 키워드 유지).
- 변경 전/후 탐지율·오탐율을 수치로 기록하여 정책 심의 기록 보관.
2. NGINX stream 로드밸런싱으로 수평 확장
현재 설정에 hash $remote_addr consistent;가 있다면 동일 클라이언트 IP → 동일 서버로 가는 세션 지속성 구조입니다. 균등 분산이 필요하면 해시 제거로 라운드 로빈이 기본 동작이 됩니다.
300x250
(A) TCP(기본) – 라운드로빈
stream {
upstream wazuh_cluster_tcp {
# hash 제거 → 기본 라운드 로빈
server wazuh.worker:1514; # Manager/Worker 1 (TCP 1514)
server wazuh2.worker:1514; # Manager/Worker 2
# 필요 시 가중치/헬스체크 추가
# server wazuh.worker:1514 weight=3;
}
server {
listen 1514; # TCP
proxy_connect_timeout 3s;
proxy_timeout 60s;
proxy_next_upstream on; # 장애 시 다음 서버로
proxy_pass wazuh_cluster_tcp;
}
}
(B) UDP(사용 중이라면) – 라운드로빈
stream {
upstream wazuh_cluster_udp {
server wazuh.worker:1514;
server wazuh2.worker:1514;
}
server {
listen 1514 udp; # UDP
proxy_timeout 30s;
proxy_pass wazuh_cluster_udp;
}
}
(C) 다른 방식
upstream mycluster {
# 최소 연결 우선
# least_conn;
# server wazuh.worker:1514;
# server wazuh2.worker:1514;
# IP 해시(세션 지속성)
# hash $remote_addr consistent;
}
🔐 보안 관점 Tip
- TLS/Mutual-Auth: 에이전트↔Manager TLS 권장. NGINX stream TCP 프록시 시 종단간 암호화 유지 구조(프록시 단 단순 패스스루) 검토.
- 접근제어:
allow/deny
(stream은 직접 미지원 → 소스 IP 기반 방화벽/보안그룹으로 통제).- 가용성: NGINX 앞단에 VIP/Anycast/Keepalived로 LB HA, LB 뒤쪽 여러 Manager/Worker 구성.
3. Wazuh Cluster 측 최적화(운영 포인트)
- Worker 수 확대: 유입 EPS 대비 여유 있게.
- Ruleset 업데이트/디코더 최적화: 과도 매칭 비용 유발하는 커스텀 룰 정리.
- 출력 파이프라인(SIEM/ES) 병목 해소: ES bulk thread, queue, JVM heap 등 동행 튜닝.
운영 안전장치: 모니터링·알림·용량계획
1. 큐/드롭 실시간 관측
# 매니저 상태 개요
sudo /var/ossec/bin/wazuh-control info
# 핵심 로그 팔로우
tail -f /var/ossec/logs/ossec.log | grep -Ei "queue|drop|full|over|delay|WARN|ERROR"
- 지표 예: “분당 드롭 수”, “decode queue 사용률”, “remoted backlog”, “event latency p95”
- 알림:
queue full
/dropped
문자열 탐지 시 Slack/Webhook 경보(ElastAlert, Wazuh 규칙, n8n 등 활용)
2. 과부하 자동 완화(Safeguard)
- 에이전트 측 샘플링/레이트리밋 정책 문서화
- FIM real-time 자동 OFF(특정부하 조건) 같은 운영 런북 수립
3. 용량 계획(간단 모델)
- 처리량(Events/sec) ≈
코어수 × (스레드 효율) × (평균 룰/디코더 비용 역수)
- EPS 피크 × 1.5~2.0 배수로 버퍼 잡고, 스케일아웃(Worker 증설) 기본전략으로
변경 적용 순서
- 증상 캡처: 드롭률/경고로그/CPU·메모리 지표 스냅샷
- 내부 큐·스레드 소폭 상향 → 재시작 → 10~30분 관찰
- 노이즈 컷/수집 다이어트(FIM/로그 제외) → 관찰
- NGINX 라운드로빈 분산 투입(한 번에 전환 X, Traffic 일부부터 단계적)
- 지표·알림 체계화(드롭=0, 레이턴시 안정)
- 치환 전/후 성능비교 리포트(정책심의/감사 대응용 산출물)
검증 체크(적용 후 바로 확인)
# 드롭/큐 포화 재발 여부
grep -E "queue|drop|full" /var/ossec/logs/ossec.log
# NGINX 동작 확인 (라운드로빈 분산 여부)
nginx -t
sudo systemctl reload nginx
# 매니저 양측 연결/세션 수 증감 확인(netstat/ss)
ss -antp | grep 1514
문제 지속 시 추가 옵션
- 하드웨어 증설: CPU/메모리/디스크 IO 보강(특히 ES 클러스터 포함 End-to-end)
- 룰셋 프로파일링: 가장 무거운 규칙/디코더 식별 후 최적화
- 아키텍처 분리: 고잡음 소스(예: 앱 디버그) 전용 파이프라인 분리 → 별도 Manager/ES로 흡수
- UDP→TCP 전환: 신뢰성 요구 시 TCP 권장(단, 네트워크 품질 고려)
보안 점검 가이드
- 데이터 유실(드롭) 금지: 큐 포화 경보 발생 시 즉시 알림 → 런북 실행
- 제외 규칙 변경 = 탐지저하 리스크: 모든 제외 항목은 변경 사유/근거 기록 및 승인절차
- 암호화/인증: 에이전트↔Manager TLS 유지, LB 통과 시 종단간 보장 설계
- 권한/접근통제: LB/Manager 노드 접근을 출발지·포트 기준 최소화
- 가용성: LB 및 Manager 이중화(헬스체크/페일오버) 정기 테스트
- 감사 추적: 성능변경·필터링 변경 Change Log 관리, 주기적 효과성 리뷰(탐지율)
설정 예시 모음
(1) internal_options.conf 스니펫
analysisd.event_threads = 4
analysisd.decode_queue_size = 16384
remoted.queue_size = 524288
(2) ossec.conf 스니펫
<ossec_config>
<global>
<memory_size>8192</memory_size>
<max_output_size>65536</max_output_size>
</global>
<analysisd>
<stats_maxdiff>999000</stats_maxdiff>
<stats_mindiff>1</stats_mindiff>
<stats_level>8</stats_level>
</analysisd>
<syscheck>
<frequency>86400</frequency>
<realtime>no</realtime>
</syscheck>
<localfile>
<log_format>syslog</log_format>
<location>/var/log/syslog</location>
<ignore binop="match">noise_pattern</ignore>
</localfile>
</ossec_config>
(3) NGINX stream (라운드로빈)
stream {
upstream wazuh_cluster_tcp {
server wazuh.worker:1514;
server wazuh2.worker:1514;
}
server {
listen 1514;
proxy_connect_timeout 3s;
proxy_timeout 60s;
proxy_next_upstream on;
proxy_pass wazuh_cluster_tcp;
}
}
728x90
그리드형(광고전용)
댓글