APISIX WAF 연동 완료: plugin_metadata, Juice Shop 테스트, waf-kr zone, DNAT 규칙
This commit is contained in:
@@ -54,6 +54,24 @@ BunnyCDN(inouter, ID 5316471) → apisix-osaka(172.233.93.180) → 백엔드
|
|||||||
- 2026-03-25 메인 라우팅 역할을 Traefik으로 이전, APISIX는 SafeLine WAF 전용으로 축소
|
- 2026-03-25 메인 라우팅 역할을 Traefik으로 이전, APISIX는 SafeLine WAF 전용으로 축소
|
||||||
- Ingress Controller + Gateway API CRD 제거됨 (GatewayProxy 모드에서 ApisixRoute CRD 미지원, HTTPRoute에 플러그인 개별 적용 불가 문제)
|
- Ingress Controller + Gateway API CRD 제거됨 (GatewayProxy 모드에서 ApisixRoute CRD 미지원, HTTPRoute에 플러그인 개별 적용 불가 문제)
|
||||||
|
|
||||||
|
#### plugin_metadata (etcd 직접 등록)
|
||||||
|
|
||||||
|
chaitin-waf 플러그인은 `plugin_attr`(config.yaml)이 아닌 **`plugin_metadata`(etcd)**에서 detector 노드를 읽음. 반드시 etcd에 등록해야 함.
|
||||||
|
|
||||||
|
```
|
||||||
|
etcdctl put /apisix/plugin_metadata/chaitin-waf '{"id":"chaitin-waf","nodes":[{"host":"10.43.253.244","port":8000}],"config":{"connect_timeout":1000,"send_timeout":1000,"read_timeout":1000,"req_body_size":1024,"real_client_ip":true}}'
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 등록된 라우트 (etcd 직접 등록)
|
||||||
|
|
||||||
|
| Route ID | 호스트 | upstream | chaitin-waf | 비고 |
|
||||||
|
|----------|--------|----------|-------------|------|
|
||||||
|
| juiceshop | juiceshop.keepanker.cv | juiceshop:3000 (juiceshop ns) | block | WAF 테스트용 OWASP Juice Shop |
|
||||||
|
|
||||||
|
#### real_ip 설정 (ConfigMap 직접 수정)
|
||||||
|
|
||||||
|
`real_ip_header: X-Forwarded-For`, `real_ip_from: 0.0.0.0/0` (BunnyCDN 경유이므로 전체 허용). Helm values로는 반영 안 되어 ConfigMap 직접 패치.
|
||||||
|
|
||||||
#### 이전 사유 (2026-03-25)
|
#### 이전 사유 (2026-03-25)
|
||||||
- Ingress Controller 2.0 GatewayProxy 모드가 ApisixRoute CRD를 sync하지 않음
|
- Ingress Controller 2.0 GatewayProxy 모드가 ApisixRoute CRD를 sync하지 않음
|
||||||
- Gateway API HTTPRoute에 플러그인 개별 적용 방법이 없음
|
- Gateway API HTTPRoute에 플러그인 개별 적용 방법이 없음
|
||||||
|
|||||||
@@ -83,7 +83,33 @@ Bouncer 목록: [[apisix]]-waf-bouncer, bunny-cdn-bouncer, cs-[[cloudflare|cf]]-
|
|||||||
| NoSQLi (JSON) | 401 | 통과 (PostgreSQL이라 무효, 인증에서 차단) |
|
| NoSQLi (JSON) | 401 | 통과 (PostgreSQL이라 무효, 인증에서 차단) |
|
||||||
| WP scan | 404 | 통과 (존재하지 않는 경로) |
|
| WP scan | 404 | 통과 (존재하지 않는 경로) |
|
||||||
|
|
||||||
|
### waf-kr BunnyCDN Pull Zone (2026-03-25)
|
||||||
|
|
||||||
|
APISIX SafeLine WAF 전용 CDN zone.
|
||||||
|
|
||||||
|
| 항목 | 값 |
|
||||||
|
|------|-----|
|
||||||
|
| Zone ID | 5554681 |
|
||||||
|
| Name | waf-kr |
|
||||||
|
| Origin | https://220.120.65.245:9443 |
|
||||||
|
| 경로 | 인터넷 → BunnyCDN(waf-kr) → OpenWrt HAProxy(:9443) → APISIX NodePort(31137) → SafeLine WAF → K3s 서비스 |
|
||||||
|
|
||||||
|
등록된 호스트: `juiceshop.keepanker.cv` (OWASP Juice Shop, WAF 테스트용)
|
||||||
|
|
||||||
|
### Juice Shop WAF 테스트 결과 (2026-03-25)
|
||||||
|
|
||||||
|
| 요청 | 결과 | WAF Action |
|
||||||
|
|------|------|------------|
|
||||||
|
| 일반 GET / | 200 | pass |
|
||||||
|
| SQLi (`?id=1 OR 1=1`) | 403 | reject (SafeLine) |
|
||||||
|
| XSS (`?q=<script>alert(1)</script>`) | 403 | reject (SafeLine) |
|
||||||
|
|
||||||
|
### 다음 단계: CrowdSec 자동 차단
|
||||||
|
|
||||||
|
계획: SafeLine WAF 차단 로그 → APISIX http-logger → jp1 CrowdSec → 커스텀 시나리오 (3회 차단 시 ban) → bouncer로 APISIX ip-restriction 적용
|
||||||
|
|
||||||
### 참고
|
### 참고
|
||||||
- BunnyCDN WAF 차단 시 오리진에 로그 안 옴 → CrowdSec에 미수신
|
- BunnyCDN WAF 차단 시 오리진에 로그 안 옴 → CrowdSec에 미수신
|
||||||
- 리얼 IP: 외부 트래픽은 `X-Forwarded-For`로 정상 전달, LAN은 `127.0.0.1`
|
- 리얼 IP: 외부 트래픽은 `X-Forwarded-For`로 정상 전달, LAN은 `127.0.0.1`
|
||||||
- OpenWrt에 CrowdSec firewall bouncer 설치 가능하나 DNAT 구조라 리얼 IP 매칭 불가
|
- OpenWrt에 CrowdSec firewall bouncer 설치 가능하나 DNAT 구조라 리얼 IP 매칭 불가
|
||||||
|
- chaitin-waf 플러그인은 `plugin_attr`이 아닌 **`plugin_metadata`(etcd)**에서 detector 노드를 읽음 — 주의
|
||||||
|
|||||||
@@ -88,6 +88,19 @@ WAN TCP 80/443 → 192.168.9.1:80/443 (HAProxy)로 DNAT.
|
|||||||
| 03:30 | `/usr/local/bin/backup-openwrt.sh` | 설정 백업 → NAS |
|
| 03:30 | `/usr/local/bin/backup-openwrt.sh` | 설정 백업 → NAS |
|
||||||
| 04:00 | `/etc/cdn-filter-update.sh` | BunnyCDN+Cloudflare IP 갱신 |
|
| 04:00 | `/etc/cdn-filter-update.sh` | BunnyCDN+Cloudflare IP 갱신 |
|
||||||
|
|
||||||
|
## WAN DNAT (fw4)
|
||||||
|
|
||||||
|
`/etc/config/firewall`의 redirect 규칙. firewall restart 시 `dstnat_wan` 체인에 반영.
|
||||||
|
|
||||||
|
| Name | Port | 대상 | 비고 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| APISIX-HTTP | :80 | 192.168.9.1:80 | Traefik 메인 |
|
||||||
|
| APISIX-HTTPS | :443 | 192.168.9.1:443 | Traefik 메인 |
|
||||||
|
| APISIX-WAF-HTTP | :9080 | 192.168.9.1:9080 | APISIX WAF |
|
||||||
|
| APISIX-WAF-HTTPS | :9443 | 192.168.9.1:9443 | APISIX WAF |
|
||||||
|
|
||||||
|
DNAT 없으면 `input_wan` → `reject_from_wan`으로 차단됨. DNAT이 있어야 `ct status dnat accept`로 통과.
|
||||||
|
|
||||||
## 관련 문서
|
## 관련 문서
|
||||||
|
|
||||||
- [[infra-hosts]] — 서버 목록
|
- [[infra-hosts]] — 서버 목록
|
||||||
|
|||||||
Reference in New Issue
Block a user