kappa 1dcf2f448e Initial commit: CrowdSec BunnyCDN bouncer
- sync/bouncer.py: CrowdSec LAPI → bloom filter → BunnyCDN Edge Script
- edge/middleware.ts: BunnyCDN edge middleware with bloom filter + Turnstile CAPTCHA
- README.md: architecture and deployment docs
2026-03-15 13:16:11 +09:00

CrowdSec BunnyCDN Bouncer

CrowdSec LAPI에서 탐지한 악성 IP를 BunnyCDN 에지에서 선제 차단하는 bouncer.

아키텍처

[CrowdSec LAPI (jp1, 10.253.100.240:8080)]
       ↓ 크론잡 (3분 간격)
       ↓ /v1/decisions/stream API
       ↓
[bouncer.py]
  → IP 목록 → Bloom filter 생성
  → BunnyCDN Compute API로 Edge Script 코드 업데이트
       ↓
[BunnyCDN Edge Script (middleware.ts)]
  → X-Real-Ip 헤더에서 클라이언트 IP 추출
  → Bloom filter로 IP 매칭
  → 매칭되면 Turnstile CAPTCHA 챌린지
  → 캡차 통과하면 4시간 검증 (verified_ips DB)
  → Bloom filter에 없으면 오리진으로 통과

구성 요소

sync/bouncer.py

CrowdSec LAPI → BunnyCDN Edge Script 동기화 스크립트.

  • CrowdSec LAPI stream endpoint에서 ban 결정 fetch
  • IP 목록을 bloom filter (FNV-1a 해시)로 변환
  • BunnyCDN Compute API로 Edge Script 코드 내 BLOOM_B64 상수 교체
  • 스크립트 퍼블리시

edge/middleware.ts

BunnyCDN Edge Script 미들웨어 (현재 inouter 풀존에 배포됨, script ID: 64811).

  • @bunny.net/edgescript-sdk 사용
  • Bloom filter 기반 IP 차단
  • Cloudflare Turnstile CAPTCHA로 false positive 대응
  • LibSQL DB로 verified IP 4시간 캐싱
  • HMAC 서명 쿠키로 세션 유지
  • Clean IP 캐시 (네거티브 캐시, 최대 50K)

환경 변수

bouncer.py

변수 설명 기본값
CROWDSEC_LAPI_URL CrowdSec LAPI URL http://10.253.100.240:8080
CROWDSEC_BOUNCER_KEY Bouncer API key (required)
BUNNY_API_KEY BunnyCDN account API key (required)
BUNNY_SCRIPT_ID Edge Script ID 64811
STATE_FILE 상태 파일 경로 /var/lib/crowdsec-bouncer/state.json

Edge Script Variables

변수 설명
TURNSTILE_SITE_KEY Cloudflare Turnstile site key
TURNSTILE_SECRET_KEY Cloudflare Turnstile secret key
CACHE_MODE 캐시 모드 (auto)
BUNNY_DATABASE_URL LibSQL database URL
BUNNY_DATABASE_AUTH_TOKEN LibSQL auth token

배포

1. CrowdSec bouncer 등록

# jp1 crowdsec 컨테이너에서
cscli bouncers add bunny-cdn-bouncer
# 출력된 API key를 Vault에 저장

2. Vault에 시크릿 저장

vault kv put secret/infra/crowdsec-bunny-bouncer \
  bouncer_key=<CROWDSEC_BOUNCER_KEY>

3. Incus 컨테이너에 배포

# jp1 infra-tool 컨테이너
pip3 install -r sync/requirements.txt
cp sync/bouncer.py /opt/crowdsec-bouncer/bouncer.py

4. Cron 설정

# /etc/cron.d/crowdsec-bunny-bouncer
*/3 * * * * root CROWDSEC_BOUNCER_KEY="..." BUNNY_API_KEY="..." /usr/bin/python3 /opt/crowdsec-bouncer/bouncer.py >> /var/log/crowdsec-bouncer.log 2>&1
# 매시 정각: 전체 동기화 (startup mode)
3 * * * * root CROWDSEC_BOUNCER_KEY="..." BUNNY_API_KEY="..." /usr/bin/python3 /opt/crowdsec-bouncer/bouncer.py --startup >> /var/log/crowdsec-bouncer.log 2>&1

테스트

# 테스트 IP 추가
ssh incus-jp1 "incus exec crowdsec -- cscli decisions add -i 198.51.100.1 -d 10m -R 'test'"

# 동기화 실행
python3 sync/bouncer.py --startup -v

# 테스트 IP 제거
ssh incus-jp1 "incus exec crowdsec -- cscli decisions delete -i 198.51.100.1"
python3 sync/bouncer.py -v

풀존 적용 현황

풀존 ID 미들웨어 상태
inouter 5316471 64811 적용됨
actions 5330178 - 미적용

Bloom Filter 세부

  • 해시 함수: FNV-1a (32-bit) double hashing
  • False positive rate: 0.1%
  • 헤더: 8 bytes (m: uint32 LE, k: uint32 LE)
  • 페이로드: bit array
  • 버전: MD5 해시 앞 16자 (변경 감지용)

Edge Script Pricing

항목 단가
요청 $0.20 / 1M
CPU 시간 $0.02 / 1,000초

처음 25M 요청은 무료. CDN 대역폭 비용은 별도.

License

MIT

Description
CrowdSec Bouncer for Bunny CDN — syncs ban decisions to Shield Access Lists
Readme 62 KiB
Languages
Python 56.9%
TypeScript 42.7%
Dockerfile 0.4%