obsidian 정합성 정정 — bouncer 단일화 잔존 stale 정리
- infra/compute/infra-hosts.md: jp1 default 20→19, cs-cf-worker-bouncer 컨테이너 라인에서 제거 - services/bunnycdn-security.md: Edge Script 64811 / bloom filter / 국가차단 / Turnstile inouter-bunny 폐기 반영. 현재 layer (Bunny Shield + Rate Limit + 대역폭 한도) 중심 재작성 - infra/network/apisix.md: Edge Script 64811 attach 라인 폐기 표시 - infra/security/cloudflare.md: Workers 인벤토리 + Worker 라우트 + CF proxy 패턴 + cfb-manager 절 모두 폐기 반영 - infra/security/crowdsec-safeline.md: cs-cf-worker-bouncer 운영 중 문장 폐기 표시 - ops-agents/overview.md: Syn 영역 정의에서 폐기 자산 명시 - history/_index.md: 누락된 2026-04-25-netbis-npm-vector-msg-rewrite, 2026-04-26-bouncer-consolidation 등록 + frontmatter updated
This commit is contained in:
@@ -1,57 +1,41 @@
|
||||
---
|
||||
title: BunnyCDN 엣지 보안 (CrowdSec + 국가 차단)
|
||||
updated: 2026-04-10
|
||||
tags: [cdn, bunnycdn, security, crowdsec, edge-script]
|
||||
title: BunnyCDN 엣지 보안 (Shield + Rate Limit + 대역폭 한도)
|
||||
updated: 2026-04-26 bouncer 단일화로 Edge Script 64811 + bloom filter + Turnstile inouter-bunny 모두 폐기 반영
|
||||
tags: [cdn, bunnycdn, security]
|
||||
---
|
||||
|
||||
## 구성
|
||||
> [!warning] 2026-04-26 bouncer 단일화로 다음 layer 폐기
|
||||
> - **Edge Script 64811** (`crowdsec-bouncer-middleware`) — 전 풀존에서 detach + 스크립트 자체 삭제
|
||||
> - **CrowdSec bloom filter 동기화** — `infra-tool` 컨테이너의 `/opt/crowdsec-bouncer/bouncer.py` 정지 + 삭제
|
||||
> - **국가 차단 layer** — Edge Script 64811 안에 구현됐던 분기라 함께 사라짐
|
||||
> - **Turnstile `inouter-bunny-middleware` 위젯** — 미들웨어 env에서만 사용했어서 함께 폐기
|
||||
>
|
||||
> 정리 경과: [[../history/2026-04-26-bouncer-consolidation|history]]
|
||||
> CrowdSec ban은 이제 `netbis-cf-firewall` (Cloudflare Firewall Rule, netbis 6 zone에만 적용) 만 enforce. BunnyCDN 풀존 (iron-jp / iron-kr 등)에는 IP-list 기반 차단 layer 없음.
|
||||
|
||||
- 엣지 스크립트: `crowdsec-bouncer-middleware` (ID `64811`, ScriptType `2` Middleware)
|
||||
- 연결된 Pull Zone: **iron-kr (5555227)**, **iron-jp (5555247)** — 둘 다 `MiddlewareScriptId: 64811` 공유
|
||||
- 미장착 풀존: `iron-git` (git smart HTTP 보호 우회, 의도), `iron-kr-waf` (SafeLine 다운스트림), `i-gate` (idle)
|
||||
- bloom filter 동기화: jp1 `infra-tool` 컨테이너의 `/opt/crowdsec-bouncer/bouncer.py` (3분 delta + 매시 full sync)
|
||||
- 소스: [[crowdsec-safeline|CrowdSec]] bloom filter (FNV-1a 임베디드 `BLOOM_B64`) + Cloudflare Turnstile 캡차
|
||||
|
||||
`cfb-manager` (K8s `default/cfb-manager`) 는 **Cloudflare Worker bouncer 관리 API** 이며 BunnyCDN 미들웨어 64811 와 무관.
|
||||
|
||||
## 동작 순서
|
||||
## 현재 보호 layer (2026-04-26 기준)
|
||||
|
||||
```
|
||||
요청 → BunnyCDN 엣지
|
||||
1. 국가 차단 (Cdn-RequestCountryCode 헤더 기반)
|
||||
- 차단 국가 → 403 반환
|
||||
2. CrowdSec bloom filter (악성 IP 판별)
|
||||
- hit → 캡차 또는 403
|
||||
- miss → 통과
|
||||
3. 캡차 (Cloudflare Turnstile)
|
||||
- bloom hit IP 에게 캡차 제시
|
||||
- 통과 시 4시간 허용 (DB + 쿠키)
|
||||
4. 정상 → Origin 으로 전달
|
||||
1. Bunny Shield WAF (OWASP CRS) — 모든 풀존 활성
|
||||
2. Bunny Shield Rate Limiting — 풀존당 1개 (IPBurst200per10s)
|
||||
3. MonthlyBandwidthLimit — 풀존당 100GB (i-gate 10GB)
|
||||
4. Origin 전달
|
||||
```
|
||||
|
||||
## 차단 국가
|
||||
|
||||
북미·유럽·구소련 권역:
|
||||
|
||||
`US, CA, GB, DE, FR, IT, ES, NL, BE, AT, CH, SE, NO, DK, FI, PL, CZ, PT, IE, RO, HU, BG, HR, SK, SI, LT, LV, EE, LU, MT, CY, GR, IS, UA, RU, BY`
|
||||
|
||||
## 주의사항
|
||||
|
||||
- **BunnyCDN Traffic Manager 국가 차단은 사용하지 않음** — Let's Encrypt 검증 및 Origin Shield fetch 를 막아서 Free SSL 발급 실패 + 500 에러 유발
|
||||
- 엣지 스크립트의 국가 차단은 `Cdn-RequestCountryCode` 헤더 기반 → CDN 내부 요청 (Let's Encrypt, Origin Shield) 에는 이 헤더가 없으므로 영향 없음
|
||||
- Free SSL 자동 발급/갱신 정상 동작
|
||||
IP-list 기반 차단/국가 차단은 현재 layer에 없음. CrowdSec 시나리오 발동 IP는 `netbis-cf-firewall` 경로 (netbis 6 zone) 또는 SafeLine WAF / APISIX limit-req 경로로만 차단.
|
||||
|
||||
## Pull Zone
|
||||
|
||||
| ID | 이름 | OriginUrl | Middleware | Smart Cache | IgnoreQS | BlockNoRef | 비고 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 5555227 | `iron-kr` | `https://220.120.65.245` | 64811 | ✅ | false | true | 메인 inouter.com 계열 |
|
||||
| 5555247 | `iron-jp` | `https://172.233.93.180` | 64811 | ✅ | false | true | **미사용 (2026-04-17 호스트네임 전부 제거)** |
|
||||
| 5555224 | `iron-kr-waf` | `https://220.120.65.245:9443` | null | ❌ | true | true | SafeLine WAF 다운스트림 보호 |
|
||||
| 5584382 | `iron-git` | `https://220.120.65.245` | null | ❌ | true | false | git smart HTTP 보호 우회 (의도) |
|
||||
| 5557897 | `i-gate` | `https://172.233.93.180` | null | ❌ | true | true | idle 슬롯 |
|
||||
| ID | 이름 | OriginUrl | Smart Cache | IgnoreQS | BlockNoRef | 비고 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 5555227 | `iron-kr` | `https://220.120.65.245` | ✅ | false | true | 메인 inouter.com 계열 |
|
||||
| 5555247 | `iron-jp` | `https://172.233.93.180` | ✅ | false | true | **미사용 (2026-04-17 호스트네임 전부 제거)** |
|
||||
| 5555224 | `iron-kr-waf` | `https://220.120.65.245:9443` | ❌ | true | true | SafeLine WAF 다운스트림 보호 |
|
||||
| 5584382 | `iron-git` | `https://220.120.65.245` | ❌ | true | false | git smart HTTP — Rate Limit 미적용 |
|
||||
| 5557897 | `i-gate` | `https://172.233.93.180` | ❌ | true | true | idle 슬롯 |
|
||||
|
||||
공통 설정: `EnableLogging: true`, `EnableWebSockets: true (max 500)`, `EnableGeoZone*: true (전 지역)`, `BlockedCountries: []`, `BlockedIps: []`, `EdgeRules: []` (모든 분기는 미들웨어 코드 안에서), `OriginType: 0 (URL)`, `VerifyOriginSSL: false`, `EnableOriginShield: false`. `OptimizerEnabled` 는 `iron-kr` / `iron-jp` 만 `true`.
|
||||
전 풀존 `MiddlewareScriptId: null` (2026-04-26 Edge Script 64811 폐기 후 자동 정리). 공통 설정: `EnableLogging: true`, `EnableWebSockets: true (max 500)`, `EnableGeoZone*: true`, `BlockedCountries: []`, `BlockedIps: []`, `EdgeRules: []`, `OriginType: 0 (URL)`, `VerifyOriginSSL: false`, `EnableOriginShield: false`.
|
||||
|
||||
## 호스트네임 인벤토리
|
||||
|
||||
@@ -72,52 +56,11 @@ tags: [cdn, bunnycdn, security, crowdsec, edge-script]
|
||||
| iron-git | `gitea.inouter.com` | |
|
||||
| i-gate | `i-gate.b-cdn.net` | ✅ |
|
||||
|
||||
총 13 (사용자 8 + 시스템 5). 전부 `HasCertificate: true` (Let's Encrypt 자동 발급/갱신). Bunny API 응답에는 인증서 만료일이 노출되지 않아 만료 모니터링은 외부 cert 체크 또는 Bunny 대시보드 알림에 의존.
|
||||
|
||||
## Edge Script / Middleware attach
|
||||
|
||||
| Script ID | 이름 | Type | 부착 풀존 |
|
||||
|---|---|---|---|
|
||||
| 64811 | `crowdsec-bouncer-middleware` | 2 (Middleware) | iron-kr, iron-jp |
|
||||
|
||||
기타 풀존 미장착 사유: `iron-git` 은 git smart HTTP 바이너리 보호 불가라 의도적 우회, `iron-kr-waf` 는 SafeLine 이 담당, `i-gate` 는 idle.
|
||||
|
||||
## CrowdSec bloom filter 동기화
|
||||
|
||||
```
|
||||
CrowdSec LAPI (jp1, 10.253.100.240:8080) → decision stream
|
||||
↓
|
||||
infra-tool 컨테이너 /opt/crowdsec-bouncer/bouncer.py
|
||||
├ 3분 delta sync
|
||||
└ 매시 full sync
|
||||
↓
|
||||
bloom filter (FNV-1a) base64 → BunnyCDN compute API
|
||||
→ Edge Script 64811 코드의 BLOOM_B64 / BLOOM_VERSION 상수 정규식 교체
|
||||
→ publish
|
||||
↓
|
||||
엣지 스크립트가 요청마다 client IP 를 bloom filter 로 체크
|
||||
hit → Turnstile 캡차 (verified 4h 쿠키)
|
||||
miss → origin 통과
|
||||
```
|
||||
|
||||
## Turnstile sitekey
|
||||
|
||||
미들웨어 64811 의 `TURNSTILE_SITE_KEY` 와 `TURNSTILE_SECRET_KEY` 는 env 변수로 주입 (코드에 hardcoded 아님). 현재 값은 [[cloudflare#Turnstile 위젯]] 의 `inouter-bunny-middleware` (`0x4AAAAAAC3otPWhldI96Aks`). 이 위젯은 cs-cf-worker-bouncer 의 이름 패턴 (`crowdsec-cloudflare-worker-bouncer-widget`) 과 다르므로 bouncer rotation 대상 외 — 수동 관리.
|
||||
|
||||
위젯 교체 절차:
|
||||
1. 신규 위젯 생성 (이름에 `bouncer` 포함 금지)
|
||||
2. Vault `secret/cloud/cloudflare/turnstile-inouter-bunny` 에 `sitekey`, `secret`, `name` 저장
|
||||
3. 미들웨어 64811 의 `TURNSTILE_SITE_KEY` / `TURNSTILE_SECRET_KEY` env 두 변수 **동시** 갱신 + publish
|
||||
4. 옛 sitekey 가 미들웨어 env 에 남아있지 않은지 검증 (grep), 옛 위젯 삭제 가능
|
||||
|
||||
## 특이사항
|
||||
|
||||
- **i-gate (5557897)**: 시스템 호스트 1개, 0 byte 트래픽. 빈 슬롯 — 용도 부여 또는 제거 필요
|
||||
- ~~**Turnstile sitekey zone gap**~~: 2026-04-17 해결. `inouter-bunny-middleware` 위젯 domains에 `inouter.com`, `anvil.it.com`, `actions.it.com`, `n8n.anvil.it.com`, `tg.anvil.it.com`, `linode.actions.it.com`, `iron-kr.b-cdn.net`, `iron-jp.b-cdn.net` 등록 완료. Cloudflare Turnstile는 루트 도메인 등록 시 서브도메인 자동 커버 (inouter.com → *.inouter.com). 위젯 도메인 상한 10개.
|
||||
총 13 (사용자 8 + 시스템 5). 전부 `HasCertificate: true` (Let's Encrypt 자동 발급/갱신).
|
||||
|
||||
## DDoS 과금 정책 (2026-04-17 지원팀 확인, Ticket #386429)
|
||||
|
||||
- **WAF 차단 요청**: 과금됨. 차단 응답도 outgoing bandwidth로 집계. 단, Origin 응답보다 크기가 작아 비용은 적음
|
||||
- **WAF 차단 요청**: 과금됨. 차단 응답도 outgoing bandwidth로 집계. 단 Origin 응답보다 크기가 작아 비용은 적음
|
||||
- **DDoS PoW 챌린지 페이지**: 과금 안 됨. 챌린지는 Bunny 소유 별도 도메인에서 호스팅되어 내 계정 대역폭 미포함
|
||||
- **DDoS 크레딧/보호**: 공식 보장 없음. Shield가 정상 동작했음에도 피해가 큰 경우 케이스별 goodwill 크레딧 검토 가능 (보장 아님)
|
||||
- **대응**: Rate Limiting으로 불필요한 차단 응답 자체를 줄이고, MonthlyBandwidthLimit으로 비용 상한 설정
|
||||
@@ -149,11 +92,23 @@ DDoS 비용 폭탄 방지용. 정상 월 사용량 ~1.2GB 대비 약 40배 여
|
||||
|
||||
무료 플랜 1/2 슬롯 사용. MidRate 규칙은 NAT/공유기 환경 오탐 + 비브라우저 클라이언트(git, API) 호환 문제로 삭제 (2026-04-17).
|
||||
|
||||
⚠️ **iron-git (101013)은 rate limit 규칙 없음** — git smart HTTP는 push/pull 시 단기간에 대량 요청을 보내므로 rate limit에 걸림. git 클라이언트는 Challenge도 통과 불가. 2026-04-17 rate limit으로 인한 접속 장애 발생 후 규칙 전부 삭제.
|
||||
또한 iron-git에 `MiddlewareScriptId: 64811`이 장착되어 있음 (Obsidian 기존 기록과 불일치 — 확인 필요).
|
||||
⚠️ **iron-git (5584382)은 rate limit 규칙 없음** — git smart HTTP는 push/pull 시 단기간에 대량 요청을 보내므로 rate limit에 걸림. git 클라이언트는 Challenge도 통과 불가. 2026-04-17 rate limit으로 인한 접속 장애 발생 후 규칙 전부 삭제.
|
||||
|
||||
## 폐기된 자산 (참고 — 재가동 시 history 참조)
|
||||
|
||||
| 자산 | 폐기일 | 비고 |
|
||||
|---|---|---|
|
||||
| Edge Script 64811 `crowdsec-bouncer-middleware` | 2026-04-26 | DELETE `/compute/script/64811` HTTP 204. iron-jp/iron-kr/iron-kr-waf/iron-git MiddlewareScriptId 자동 null |
|
||||
| `infra-tool:/opt/crowdsec-bouncer/bouncer.py` (bloom sync) | 2026-04-26 | cron + 디렉토리 삭제 |
|
||||
| Turnstile `inouter-bunny-middleware` (`0x4AAAAAAC3otPWhldI96Aks`) | 2026-04-26 | env baked-in, 미들웨어 폐기와 함께 |
|
||||
| 국가 차단 layer (Edge Script 코드 내 분기) | 2026-04-26 | 미들웨어 코드 자체가 사라짐 |
|
||||
| Vault `secret/cloud/cloudflare/turnstile-inouter-bunny` | 보존 | 폐기 결정 후속 |
|
||||
| Gitea `kaffa/crowdsec-bunny-bouncer` (소스) | 보존 | 재구축 reference |
|
||||
|
||||
상세: [[../history/2026-04-26-bouncer-consolidation|history]]
|
||||
|
||||
## 관련 문서
|
||||
|
||||
- [[bunnycdn]] — BunnyCDN API 레퍼런스
|
||||
- [[crowdsec-safeline]] — CrowdSec 및 SafeLine WAF 설정
|
||||
- [[cloudflare]] — Cloudflare DNS/CDN (Turnstile 위젯 정본)
|
||||
- [[../infra/security/crowdsec-safeline|crowdsec-safeline]] — CrowdSec 및 SafeLine WAF 설정
|
||||
- [[../infra/security/cloudflare|cloudflare]] — Cloudflare DNS/CDN (Turnstile 위젯 정본)
|
||||
|
||||
Reference in New Issue
Block a user