title, updated
| title |
updated |
| CrowdSec 및 SafeLine WAF |
2026-03-28 |
CrowdSec LAPI
| 항목 |
값 |
| 위치 |
jp1 Incus crowdsec 컨테이너 |
| LAPI |
http://10.253.100.240:8080 |
| 관리 |
ssh incus-jp1 "incus exec crowdsec -- cscli ..." |
로그 수집 (Acquisition)
Traefik → CrowdSec (Vector)
| 항목 |
값 |
| Vector |
Helm vector/vector 0.51.0, Agent DaemonSet (3노드) |
| Values |
~/k8s/vector/values.yaml |
| CrowdSec 포트 |
8086 |
| 인증 |
Authorization: traefik-crowdsec-log-2024 |
| 파서 |
crowdsecurity/traefik-logs (Hub, JSON 모드) |
APISIX → CrowdSec (http-logger)
| 항목 |
값 |
| 설정 |
APISIX Admin API global_rules/1 |
| CrowdSec 포트 |
8085 |
| 인증 |
Authorization: apisix-crowdsec-log-2024 |
| 파서 |
custom/apisix-json-logs (로컬) |
리얼 IP 처리
| 경로 |
설정 |
source IP 추출 |
| BunnyCDN → HAProxy → Traefik |
forwardedHeaders.trustedIPs: 127/8, 10/8, 172.16/12, 192.168/16 + externalTrafficPolicy: Local |
ClientHost (X-Forwarded-For에서 추출) |
| BunnyCDN → HAProxy → APISIX |
real_ip_header: X-Forwarded-For + real_ip_from: 127/8, 10.42/16, 10.43/16, 192.168.9/24, 100.64/10 |
client_ip (nginx real_ip 모듈) |
Traefik values: ~/k8s/traefik/values.yaml
시나리오
| 유형 |
시나리오 |
출처 |
| HTTP |
http-probing, http-crawl-non_statics, http-sensitive-files, http-backdoors-attempts, http-sqli-probing, http-xss-probing 등 |
Hub |
| SafeLine |
custom/safeline-waf-blocked (trigger), custom/safeline-waf-repeated (3+/5min) |
로컬 |
| CAPI |
http:dos, http:scan, ssh:bruteforce (커뮤니티) |
자동 |
Bouncer
cs-cf-worker-bouncer (Cloudflare Worker)
| 항목 |
값 |
| 위치 |
jp1 Incus cs-cf-worker-bouncer 컨테이너 |
| 설정 |
/etc/crowdsec/bouncers/crowdsec-cloudflare-worker-bouncer.yaml |
| 정본 |
gitea.inouter.com/kaffa/k8s → configs/crowdsec/crowdsec-cloudflare-worker-bouncer.yaml |
| 동기화 |
10초 (decision stream polling) |
| 방식 |
LAPI → bouncer → Cloudflare Worker KV (bloom filter) → Worker에서 차단/captcha |
| 보호 zone |
keepanker.cv, actions.it.com, ironclad.it.com, inouter.com, servidor.it.com |
| Turnstile |
5개 zone managed 모드, 168시간 secret key 로테이션 |
Decision 수동 관리
bouncer의 lapi_key는 읽기 전용. decision 추가/삭제는 crowdsec 컨테이너에서 cscli로:
bouncer 컨테이너에서 curl POST /v1/decisions로 직접 넣으면 등록 안 됨 — API 키 권한 제한.
설정 변경 시 주의
sed -i 사용 금지 — Incus 컨테이너 내에서 sed -i로 수정 시 이전 내용이 파일 끝에 남아 YAML 깨짐. 반드시 전체 파일 덮어쓰기:
bunny-cdn-bouncer (BunnyCDN Edge Script)
| 항목 |
값 |
| 동기화 |
jp1 infra-tool 컨테이너, /opt/crowdsec-bouncer/bouncer.py |
| 크론 |
3분 delta sync, 매시 full sync |
| 방식 |
LAPI → Bloom filter → BunnyCDN Edge Script 임베딩 → 퍼블리시 |
| Edge Script |
ID 64811 (crowdsec-bouncer-middleware), FNV-1a bloom filter |
| 차단 시 |
Cloudflare Turnstile CAPTCHA + LibSQL verified IP 캐싱(4h) |
| 적용 풀존 |
iron-jp (5555247) |
| API 키 |
Vault secret/infra/crowdsec-bunny-bouncer |
| 소스 |
~/crowdsec-bunny-bouncer/ |
보안 구조
0차: BunnyCDN Edge Script (CrowdSec bouncer)
- Bloom filter로 악성 IP 즉시 차단
- false positive 시 Turnstile CAPTCHA로 구제
1차: BunnyCDN WAF (OWASP CRS)
- CDN 에지에서 오리진 도달 전 차단
- 차단: SQLi, XSS, CMDi, SSRF, Shellshock, Log4j
- 비활성화: DATA LEAKAGES SQL (id=911) — NocoDB 오탐 방지
- 통과: Request Smuggling, NoSQLi, 경로 스캔
2차: SafeLine WAF (chaitin-waf)
- APISIX plugin_metadata → detector
10.43.253.244:8000
- SafeLine v9.3.2, K3s safeline ns
- 관리: safeline.inouter.com, API 헤더
X-SLCE-API-TOKEN
- 토큰: Vault
secret/infra/safeline
- tengine 미사용, APISIX 직접 연동
3차: CrowdSec 로그 분석
- Traefik 로그: Vector DaemonSet →
:8086 → crowdsecurity/traefik-logs
- APISIX 로그: http-logger →
:8085 → custom/apisix-json-logs
- HTTP 시나리오 매칭 → decision → bouncer 피드백
waf-kr BunnyCDN Pull Zone
APISIX SafeLine WAF 전용.
| 항목 |
값 |
| Zone ID |
5554681 |
| Name |
waf-kr |
| Origin |
https://220.120.65.245:9443 |
| 경로 |
인터넷 → BunnyCDN(waf-kr) → HAProxy(:9443) → APISIX(31137) → SafeLine → K3s |
등록 호스트: juiceshop.keepanker.cv (WAF 테스트용)
참고
- BunnyCDN WAF 차단 시 오리진에 로그 안 옴 → CrowdSec에 미수신
- OpenWrt CrowdSec firewall bouncer는 DNAT 구조라 리얼 IP 매칭 불가
- chaitin-waf 플러그인은
plugin_attr이 아닌 **plugin_metadata(etcd)**에서 detector 노드를 읽음
- Incus 컨테이너에서
sed -i로 설정 수정 시 파일 손상 주의 (전체 파일 push 사용)