99 lines
4.3 KiB
Markdown
99 lines
4.3 KiB
Markdown
---
|
|
title: Netbis Sigmatch — VL 기반 자동 시그니처 생성 + CF 차단
|
|
updated: 2026-04-24
|
|
tags: [netbis, security, ai-defense, wip]
|
|
---
|
|
|
|
## 개요
|
|
|
|
Netbis NPM 로그(VictoriaLogs)를 실시간 분석해 **사람 개입 없이 자동으로 공격 시그니처를 생성**하고 CF IP Access Rules에 차단 반영. LAPI·CrowdSec·LLM 모두 사용 안 함 — 통계/ML 기반.
|
|
|
|
- **저장소**: https://gitea.inouter.com/kaffa/netbis-sigmatch
|
|
- **로컬 개발**: `~/netbis-sigmatch/` (Mac)
|
|
- **배포 예정**: jp1 Incus `ai-sigmatch` 컨테이너 (systemd timer 1분)
|
|
- **책임자**: kappa 직접 개발 (Heimdall 위임 X, 개발 단계)
|
|
|
|
## 설계 결정
|
|
|
|
| 결정 | 값 | 근거 |
|
|
|------|-----|------|
|
|
| 탐지 주기 | 1분 (슬라이딩 윈도우 5분) | 5분 내 방어 개시 목표 |
|
|
| 분석 대상 | 5분 요청 100+ IP만 | 통계적 유의성 확보, 노이즈 제거 |
|
|
| LLM 사용 | **없음** | 이전 `ddos-detect` 실패 원인(매 요청 LLM 동기 호출) 교훈 |
|
|
| LAPI 경유 | **없음** | Netbis는 로그 파이프라인이 독립, LAPI 중간 레이어 불필요 |
|
|
| 차단 저장소 | CF IP Access Rules 직접 | 한도 50k (vs Custom List 10k) |
|
|
| Feature | 13종 + 메타 (경로 문자열·UA 문자열 비의존) | 공격 path·UA가 매번 바뀌어도 시그니처 재사용 가능 |
|
|
|
|
## Feature 확정
|
|
|
|
5분 윈도우, 요청 100+ IP.
|
|
|
|
| 카테고리 | Feature |
|
|
|---------|---------|
|
|
| 볼륨 | reqs, rate_per_min |
|
|
| 경로 shape | path_entropy, top_path_ratio, uniq_paths |
|
|
| UA | ua_count |
|
|
| 응답 | status_2xx_ratio, status_4xx_ratio |
|
|
| 간격 | iri_mean, iri_p50, iri_p90, iri_cv |
|
|
| 행동 | static_ratio, ref_count, ref_top_ratio, active_sec, has_post |
|
|
| 메타 | is_reserved (240/4 플래그) |
|
|
|
|
### 제거된 후보
|
|
|
|
- `top_path`·`top_ua` 문자열 — 공격자가 매번 바꿈. 시그니처가 종속되면 재생성 부담
|
|
- `ref_none_ratio`, `ref_external_ratio` — 봇도 referer 세팅, 실측 전부 0
|
|
- UA 문자열 기반 봇 분류 — 정교한 봇은 정상 Chrome/Safari UA 사용
|
|
|
|
## 개발 단계
|
|
|
|
- [x] Phase 1: feature 추출 파이프라인 (`fetch_features.py`)
|
|
- [x] Phase 2: 24h baseline 수집기 (retrospective, `collect_baseline.py`)
|
|
- [x] Phase 3: IsolationForest 기반 anomaly detection (loop.py 내)
|
|
- [x] Phase 4: DBSCAN 클러스터링 + 단발 봇 persistence 탐지 (loop.py 내)
|
|
- [x] Phase 5: state DB (IP별 persistence/action 이력, `state.py`)
|
|
- [ ] **Phase 5b: 장시간 관찰 (현재 진행)** — 수 시간~1일 dry-run, 실제 공격 도달 시 거동 확인
|
|
- [ ] Phase 6: CF IP Access Rules 호출 (managed_challenge → block 승급)
|
|
- [ ] Phase 7: jp1 Incus 배포 (systemd timer)
|
|
|
|
## 오탐 방지 설계 (핵심)
|
|
|
|
사람이 작성한 공격 패턴 룰 **없음**. 매 사이클 자동 재합성.
|
|
|
|
**2트랙 탐지**:
|
|
|
|
1. **클러스터 기반 (캠페인 공격)**
|
|
- IsolationForest로 outlier 추출
|
|
- DBSCAN으로 outlier 간 유사 패턴 클러스터
|
|
- 클러스터 강도(크기·rate·성공률) 평가 → challenge
|
|
- 연속 5+ 사이클 지속 시 block 승급
|
|
|
|
2. **단발 지속 (개별 봇)**
|
|
- 클러스터 미형성 noise outlier 중
|
|
- 3+ 사이클 연속 + anomaly_score 하위 50% 이내
|
|
- → challenge, 5+ 사이클 지속 → block
|
|
|
|
**조치 레벨**:
|
|
- challenge: Cloudflare managed_challenge (CAPTCHA), TTL 30분 — 정상 유저는 한 번 풀고 통과
|
|
- block: TTL 24시간 — challenge 통과 후에도 공격 지속 시만
|
|
|
|
**사람이 조정하는 건 파라미터만** (코드에 공격 지식 없음):
|
|
- `min_cluster_ips` (클러스터 최소 IP 수)
|
|
- `min_avg_rate`, `min_success` (강도 임계)
|
|
- `persistence_for_challenge`, `persistence_for_block` (승급 기준)
|
|
- DBSCAN eps, min_samples
|
|
- TTL
|
|
|
|
## 관찰된 공격 유형 (2026-04-24 실측)
|
|
|
|
**유형 A — 리소스 크롤러**: static_ratio > 0.5, iri_p90 < 0.1, uniq_paths > 50, 짧은 active
|
|
|
|
**유형 B — API/HTML 봇**: static_ratio < 0.05, iri_p90 5~8s, path_entropy < 5, top_path_ratio 0.2~0.3, active 200s+
|
|
|
|
**루프 봇**: ref_top_ratio >= 0.9 + reqs >= 100 (단독 ban 기준 후보)
|
|
|
|
## 연관 정본
|
|
|
|
- [[../services/netbis]] — NPM → VL 파이프라인
|
|
- [[../infra/security/cloudflare#Pseudo IPv4 (Class E 240/4)]] — 240/4 대역 해석
|
|
- [[../history/2026-04-24-cf-pseudo-ipv4-discovery]] — CF Pseudo IPv4 규명
|