7.1 KiB
date, topic, areas, tags
| date | topic | areas | tags | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 2026-04-23 | Netbis Firewall Bouncer 도입 (Worker Bouncer 병행) |
|
|
배경
Netbis 계정 2026-04 Cloudflare Workers 요금 $100 중 82%가 KV read 비용 오버. Worker Bouncer(netbis-cf) 구조는 요청이 CF에 도달 → Worker 실행 → KV.get으로 IP 확인 → 차단/통과 순서. 즉 Worker가 실행돼야 KV read가 발생. 악성 IP라 결국 차단해도 KV read 비용은 이미 청구됨.
기존 Bouncer는 제거하지 않고 병행. Worker Bouncer는 Turnstile/captcha 등 정교한 챌린지용 유지, Firewall Rule Bouncer는 엣지 즉시 차단으로 Worker 실행 자체를 회피해 비용 방어.
최종 구조
LAPI (jp1:crowdsec, 10.253.100.240:8080)
├─ netbis-cf → CF Worker + KV (기존, Turnstile/정교)
└─ netbis-cf-firewall → CF Rule List + Firewall Rule (신규, 엣지 차단)
CF 요청 평가 순서상 Firewall Rule → Worker. Firewall Rule에서 block되면 Worker는 실행되지 않아 KV read 없음.
실행 단계
1. 사전 조사 — CF 플랜 / IP List 용량
6개 zone 플랜 (scoped API 아님, global_api_key X-Auth 조회):
| Zone | Zone ID | Plan |
|---|---|---|
| fall-vip.com | 662312b0ca619d1d5c8f4c112150d749 | Pro |
| fall-mvp.com | 6c171579912a271c0fc89c8187493b0f | Free |
| fall-vip7.com | a8832b9d3b546f96505abeadea4750d1 | Free |
| psd777.com | a14533c2937b19e5b7ed19cbecd58679 | Pro |
| rss-555.com | 6d4b084940520c1f820927e5d8ade2c6 | Pro |
| rss-7790.com | d9db9e50e202339326498baa340a9d16 | Pro |
Free/Pro/Biz 공통 IP list 상한 = 10,000. total_ip_list_capacity: 10000 설정.
2. 컨테이너 패키지 설치
jp1:netbis-cf-bouncer (기존 Worker Bouncer 컨테이너 재사용, 서비스 분리).
incus exec jp1:netbis-cf-bouncer -- apt-get update
incus exec jp1:netbis-cf-bouncer -- apt-get install -y crowdsec-cloudflare-bouncer # v0.3.0
3. LAPI 바우언서 등록
incus exec jp1:crowdsec -- cscli bouncers add netbis-cf-firewall
# API key 출력을 즉시 설정 파일에 주입
4. CF scoped API token 발급
v0.3.0 바우언서는 cloudflare.NewWithAPIToken(token) Bearer-only. Global API Key는 X-Auth 헤더 전용이라 token 필드에 그대로 못 넣음 (Bearer auth에서 Invalid request headers 거절 확인). 해결: global_api_key 경유로 scoped API token 신규 발급.
| 항목 | 값 |
|---|---|
| Token 이름 | crowdsec-cloudflare-bouncer-netbis |
| Account 스코프 | Netbis (8fcf3c7876332aba33e974cbbfdad951) 전용, All zones |
| TTL | 무기한 |
| 권한 | Account Rule Lists Write + Account Settings Read + Zone Firewall Services Write + Zone WAF Write + Zone Read |
| 저장 | Vault secret/cloud/cloudflare-netbis api_token 필드 (기존 global_api_key 보존) |
발급 시 CF API permission_group IDs:
2edbf20661fd4661b0fe10e9e12f485cAccount Rule Lists Writec1fde68c7bcc44588cbb6ddbc16d6480Account Settings Read43137f8d07884d3198dc0ee77ca6e79bFirewall Services Writefb6778dc191143babbfaa57993f1d275Zone WAF Writec8fed203ed3043cba015a93ad1616f1fZone Read
메모: Account.Account Filter Lists:Edit (user 스펙 명)은 현재 CF에서 Account Rule Lists Write로 이름 변경됨. 기능 동일. Rulesets API 경로 사용 시 403 발생하면 Account Rulesets:Edit (56907406c3d548ed902070ec4df0e328) 추가 후 재발급.
5. Config 파일 전송
/etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml — 전체 파일 push (sed -i 금지, Incus 컨테이너 내 in-place 편집 피함):
incus exec jp1:netbis-cf-bouncer --mode=non-interactive -- \
bash -c 'cat > /etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml && chmod 600 /etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml' \
< /tmp/crowdsec-cloudflare-bouncer.yaml
주요 값:
crowdsec_lapi_url: http://10.253.100.240:8080crowdsec_lapi_key: cscli bouncers add 출력cloudflare_config.accounts[0].token: 위에서 발급한 scoped tokenip_list_prefix: crowdsecdefault_action: block, 모든 zoneactions: [block]단일total_ip_list_capacity: 10000
6. 서비스 기동 + CF 리소스 자동 생성
incus exec jp1:netbis-cf-bouncer -- systemctl enable --now crowdsec-cloudflare-bouncer
바우언서 부팅 직후:
- CF IP List
crowdsec(IDb14745a3306a4f81b46d96593135f78b) 생성 — Account Rule List - 6개 zone에 firewall rule 자동 생성 (ip.src in $crowdsec → block)
- LAPI 스트림 첫 풀: 28,885건 decision 수신, 10,000건 CF로 push
7. E2E 검증
- 추가 경로:
cscli decisions add --ip 203.0.113.99 --duration 2m --type ban→ LAPI 기록 확인 → 바우언서 다음 사이클에 처리. 단 LAPI 총량 > 10k 상황에서 신규 IP는 용량 우선순위 밀려 CF 반영 보장 안 됨. 실제 테스트에서1 IPs won't be inserted/kept to avoid exceeding IP list limit경고 발생 - 삭제 경로: CF 리스트 내 IP (
1.14.7.100) LAPI decision 삭제 → 다음 사이클 제거. CF API 레이트리밋(10040) 영향으로 즉시 반영 아닌 다음 rate-limit window 이후 반영 - 실제 push 성공 증거: 바우언서 로그
added 10000 new IPs and deleted 0 IPs— 초기 sync 정상
8. Obsidian 커밋 + graphify
infra/security/crowdsec-safeline.md—### netbis-cf-firewall서브섹션 추가, 바우언서 역할 분담 도식history/2026-04-23-netbis-firewall-bouncer-migration.md— 이 문서- commit:
netbis: crowdsec-cloudflare-bouncer (firewall rule) 추가 — worker bouncer와 병행 /graphify update ~/obsidian
운영 관찰 사항
IP List 용량 제약
LAPI 전체 decision 수가 ~29k, CF Pro 제한 10k. 바우언서는 10k 초과분을 우선순위 선별해 push하지 않음. 결과:
- 오래된/높은 우선순위 decision은 CF 반영 (일관성 있는 차단)
- 신규 short-TTL decision은 CF 반영 불확실 (커뮤니티 CAPI 결정 다수 + 큰 TTL 누적 영향)
- 운영상 Worker Bouncer 경로가 여전히 필요한 이유 — Firewall Rule로 못 잡는 부분은 Worker Bouncer가 KV 조회로 커버
CF API 레이트리밋 (10040)
바우언서 update_frequency: 30s에서 매 사이클 신규 IP 1~수건 push 시도. CF Rule List items API 제한(분당 N건)에 금방 도달. 로그에 you have been ratelimited 출력, 다음 사이클에서 자동 재시도.
향후 개선 후보
- CrowdSec LAPI
only_include_decisions_from필터로 CAPI 커뮤니티 feed 제외 → 차단 quality 향상하고 CF 10k 용량 효율화 include_scenarios_containing: ["http"]등 시나리오 필터로 포커스- Enterprise zone 업그레이드 시
total_ip_list_capacity: 50000가능
영향 및 롤백
- Worker Bouncer
netbis-cf무변경 — 병행 운영, 기존 Turnstile/captcha 동작 그대로 - 롤백:
systemctl stop crowdsec-cloudflare-bouncer && cscli bouncers delete netbis-cf-firewall+ CF IP List/Firewall Rule 수동 삭제 (Rule Listcrowdsec+ 6 zone firewall rules) - CF 요금 방어 효과는 다음 월 청구서에서 확인 가능