diff --git a/infra/apisix.md b/infra/apisix.md index ceb89c4..28c9cfb 100644 --- a/infra/apisix.md +++ b/infra/apisix.md @@ -1,6 +1,6 @@ --- title: APISIX 설정 및 운영 -updated: 2026-03-27 +updated: 2026-04-04 --- ## 아키텍처 @@ -45,16 +45,16 @@ BunnyCDN(inouter, ID 5316471) → apisix-osaka(172.233.93.180) → 백엔드 ### 서울 (K3s 새 클러스터, apisix 네임스페이스) — SafeLine WAF 전용 ``` -외부 → OpenWrt HAProxy(:9080/:9443) → MetalLB 192.168.9.50(80/443) → APISIX(replica 1) → K3s 서비스 +외부 → OpenWrt HAProxy(:9080/:9443) → MetalLB 192.168.9.50(80/443) → APISIX(replica 2) → K3s 서비스 ``` - 용도: SafeLine WAF 전용 리버스 프록시 (메인 라우팅은 Traefik으로 이전) - 클러스터: K3s 새 클러스터 (Supabase PostgreSQL 백엔드, kr2+kr1+hp2) -- 배포: K3s apisix 네임스페이스, **Deployment replica 1** (축소됨) +- 배포: K3s apisix 네임스페이스, **Deployment replica 2** (2026-04-04 HA 업그레이드) - APISIX: 3.15.0-ubuntu - SafeLine WAF 연동: `plugin_attr.chaitin-waf` → `safeline-detector:8000` (10.43.253.244) - global_rules: `chaitin-waf` (mode: block) + `limit-req` (rate 20, burst 10) - 서비스: apisix-gateway LoadBalancer 192.168.9.50 (80→9080, 443→9443) -- etcd: apisix-etcd StatefulSet (K3s 내부) +- etcd: apisix-etcd StatefulSet **3 replicas** (K3s 내부, 2026-04-04 HA 업그레이드) - Admin API: `apisix-admin` ClusterIP :9180 (라우트/upstream/SSL 수동 관리) - HAProxy: OpenWrt에서 :9080→192.168.9.50:80, :9443→192.168.9.50:443 (MetalLB) - 2026-03-25 메인 라우팅 역할을 Traefik으로 이전, APISIX는 SafeLine WAF 전용으로 축소 diff --git a/infra/crowdsec-safeline.md b/infra/crowdsec-safeline.md index e037c75..cb63213 100644 --- a/infra/crowdsec-safeline.md +++ b/infra/crowdsec-safeline.md @@ -1,6 +1,6 @@ --- title: CrowdSec 및 SafeLine WAF -updated: 2026-04-03 +updated: 2026-04-04 --- ## CrowdSec LAPI @@ -48,6 +48,75 @@ APISIX (global_rules http-logger 플러그인) | 인증 | `Authorization: apisix-crowdsec-log-2024` | | 파서 | `custom/apisix-json-logs` (로컬) | +### APISIX → log-collector → CrowdSec (sandbox-tokyo) + +``` +sandbox-tokyo APISIX http-logger + → log-collector (jp1 crowdsec 컨테이너, :8087) + → SQLite (/var/lib/log-collector/requests.db) + → CrowdSec HTTP acquisition (:8085/apisix-logs) 포워딩 +``` + +| 항목 | 값 | +|------|-----| +| log-collector | Go HTTP 서버, `/usr/local/bin/log-collector` (jp1 crowdsec 컨테이너) | +| 소스 | jp1 `~/log-collector/main.go` | +| 수신 포트 | 8087 | +| 인증 | `Authorization: apisix-crowdsec-log-2024` | +| SQLite | `/var/lib/log-collector/requests.db` | +| 기능 | APISIX 로그 수신 → SQLite 저장 → CrowdSec 포워딩, 타임스탬프 밀리초 보정 | + +### SafeLine → CrowdSec (실시간, PG LISTEN/NOTIFY) + +``` +SafeLine WAF 차단 → mgt_detect_log_basic INSERT + → PG 트리거 (notify_detect_log) → pg_notify('safeline_detect', JSON) + → safeline-listener (kr2, Go) → detail 테이블 enrichment (x-real-ip, user-agent) + → CrowdSec HTTP acquisition (:8088/safeline-logs) + → custom/safeline-http-logs 파서 + → custom/safeline-waf-blocked 시나리오 (trigger, 즉시 밴) +``` + +| 항목 | 값 | +|------|-----| +| safeline-listener | Go, `/usr/local/bin/safeline-listener` (kr2) | +| 소스 | kr2 `~/safeline-listener/main.go` | +| systemd | `safeline-listener.service` (kr2) | +| PG DSN | SafeLine CE DB (10.43.8.243:5432, safeline-ce) | +| CrowdSec 포트 | 8088 | +| 인증 | `Authorization: safeline-crowdsec-2026` | +| acquis 설정 | `/etc/crowdsec/acquis.d/safeline-http.yaml` | +| 파서 | `custom/safeline-http-logs` (`/etc/crowdsec/parsers/s01-parse/safeline-http-logs.yaml`) | +| 시나리오 | `custom/safeline-waf-blocked` (trigger 타입, 즉시 밴) | +| enrichment | req_header에서 `x-real-ip`, `user-agent` 추출, detail 테이블에서 method/payload 조회 | + +PG 트리거 (SafeLine CE DB에 설치): +```sql +CREATE OR REPLACE FUNCTION notify_detect_log() RETURNS trigger AS $$ +BEGIN + PERFORM pg_notify('safeline_detect', json_build_object( + 'id', NEW.id, 'ts', NEW.created_at, + 'src_ip', NEW.src_ip, 'host', NEW.host, + 'url_path', NEW.url_path, 'attack_type', NEW.attack_type + )::text); + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER trg_detect_log + AFTER INSERT ON mgt_detect_log_basic + FOR EACH ROW EXECUTE FUNCTION notify_detect_log(); +``` + +### ddos-detect (AI 행위 분석) + +| 항목 | 값 | +|------|-----| +| 위치 | jp1 crowdsec 컨테이너 `/var/lib/log-collector/ddos-detect/` | +| Gitea | `gitea.inouter.com/kaffa/ddos-detect` | +| 기능 | SQLite 폴링 → IP별 행위 패턴 추출 → Claude AI 분석 → cscli 자동 밴 | +| 설정 | `config.yaml` (poll 60s, Claude sonnet, ban 4h, max_workers 3) | + ### 리얼 IP 처리 | 경로 | 설정 | source IP 추출 | diff --git a/infra/infra-hosts.md b/infra/infra-hosts.md index 3c6a4f5..7b21966 100644 --- a/infra/infra-hosts.md +++ b/infra/infra-hosts.md @@ -1,6 +1,6 @@ --- title: 인프라 호스트 및 네트워크 -updated: 2026-04-03 +updated: 2026-04-04 tags: [infra, network, kr-zone, openwrt] --- @@ -17,7 +17,7 @@ tags: [infra, network, kr-zone, openwrt] | incus-kr1 | 100.84.111.28 | Incus+K3s 호스트 (서울) | GTX 1080 Ti, K3s control-plane (LAN 192.168.9.214), default 프로젝트 | | incus-kr2 | 100.119.109.41 | Incus+K3s 호스트 (서울) | K3s control-plane (LAN 192.168.9.135), default, inbest 프로젝트 | | incus-hp2 | 100.100.52.34 | Incus+K3s 호스트 (서울) | Xeon E5-2670 32코어, 188GB RAM, K3s control-plane (LAN 192.168.9.134), default, inbest 프로젝트 | -| openwrt-gw | 100.66.60.66 | OpenWrt 라우터 (서울) | HAProxy: 80/443 → MetalLB Traefik(192.168.9.53), 9080/9443 → MetalLB APISIX(192.168.9.50) | +| openwrt-gw | 100.66.60.66 | OpenWrt 라우터 (서울) | HAProxy: 80/443 → MetalLB Traefik(192.168.9.53:80/443), 9080/9443 → MetalLB APISIX(192.168.9.50:80/443) | | sandbox-tokyo | 100.79.87.48 | [[netbis]] 예비 APISIX Gateway (도쿄, Linode) | APISIX 3.15.0 + etcd, 공인 139.162.71.52, netbis 도메인 DR용 | | relay4wd (sandbox-kr2) | 100.103.161.4 | APISIX Gateway (서울, AWS Lightsail) | 공인 52.79.45.166, inbest 포트포워딩, Docker APISIX 3.15.0, Debian 12, nano $5/월, SSH: `ssh -p 2222 admin@relay4wd` (Vault CA), 포트 22는 SFTPGo 리다이렉트 | | synology | LAN 192.168.9.100 / 192.168.205.100 (2.5G) | NAS (시놀로지) | Tailscale 미사용, LAN 접근 | @@ -36,12 +36,14 @@ tags: [infra, network, kr-zone, openwrt] 게이트웨이: Traefik (메인) + APISIX (SafeLine WAF 전용), 2026-03-25 전환 - Traefik DaemonSet, MetalLB LoadBalancer 192.168.9.53 + Gateway API -- APISIX Deployment replica 1, MetalLB LoadBalancer 192.168.9.50, SafeLine WAF chaitin-waf 플러그인 연동, Admin API 수동 관리 +- APISIX Deployment **replica 2**, MetalLB LoadBalancer 192.168.9.50, SafeLine WAF chaitin-waf 플러그인 연동, Admin API 수동 관리 +- APISIX etcd StatefulSet **replica 3** (HA, 2026-04-04 업그레이드) - CoreDNS hairpin rewrite: traefik.kube-system.svc.cluster.local 트래픽 흐름: - 일반: 외부 → OpenWrt HAProxy(:80/:443) → MetalLB Traefik(192.168.9.53:80/443) → K3s 서비스 - WAF: 외부 → OpenWrt HAProxy(:9080/:9443) → MetalLB APISIX(192.168.9.50:80/443) → SafeLine WAF → K3s 서비스 +- SafeLine 실시간: SafeLine 차단 → PG NOTIFY → safeline-listener(kr2) → CrowdSec(:8088) → 즉시 IP 밴 ### Helm 릴리스 @@ -207,7 +209,7 @@ Docker: `--runtime=nvidia` 또는 `--gpus all`로 GPU 사용. Podman: CDI 방식 - **K3s datastore**: Incus etcd 3노드 클러스터 (192.168.9.214, 192.168.9.135, 192.168.9.134) - `/registry/` — K3s 클러스터 백엔드 스토어 - `/patroni/nocodb-cluster` — NocoDB PostgreSQL HA -- **APISIX etcd** (K3s 내부): apisix-etcd StatefulSet (ClusterIP 10.43.20.100:2379, prefix `/apisix`) +- **APISIX etcd** (K3s 내부): apisix-etcd StatefulSet **3 replicas** (ClusterIP 10.43.20.100:2379, prefix `/apisix`, 2026-04-04 HA 업그레이드) - **OVN 네트워크**: ovn1 (10.165.246.0/24) — hp2↔kr2 간 오버레이 - **CDN IP 필터**: BunnyCDN + Cloudflare IP만 80/443 허용, 그 외 WAN 차단 - 스크립트: `/etc/cdn-filter-update.sh` @@ -223,13 +225,22 @@ Docker: `--runtime=nvidia` 또는 `--gpus all`로 GPU 사용. Podman: CDI 방식 | 호스트 | 2.5G IP | 상태 | |--------|---------|------| -| kr2 | 192.168.205.? | ✅ 연결됨 | -| NAS | 192.168.205.100 | ✅ 연결됨 | +| kr2 | 192.168.205.135 | ✅ 연결됨 (USB r8152) | +| NAS | 192.168.205.100 | ✅ 연결됨 (USB cdc_ncm) | | kr1 | - | 예정 (2.5G NIC 추가 예정) | | hp2 | - | 예정 (2.5G NIC 추가 예정) | 목표: kr1/kr2/hp2/NAS 4대를 2.5GbE로 직접 연결 +#### USB 2.5G 안정성 이슈 (2026-04-04 해결) + +USB 2.5GbE 어댑터(r8152/cdc_ncm)가 Linux USB autosuspend에 의해 절전 모드 진입 후 드라이버 hang 발생. kr2에서 NFS hard mount가 죽은 2.5G IP로 D-state 누적되어 로드 2000+ 장애. + +**해결:** +- USB unbind/bind로 즉시 복구 +- kr2: GRUB `usbcore.autosuspend=-1`, udev rule `99-usb-ethernet.rules` (scatter-gather off) +- NAS: `/usr/local/etc/rc.d/usb-no-suspend.sh` 스타트업 스크립트 + ## 네트워크 대역 네트워크 대역: 100.0.0.0/8 (Tailscale VPN), 10.253.0.0/16 (incus-jp1 내부), 10.100.3.0/24 (incus-kr1 incusbr0), 10.100.1.0/24 (incus-kr2 incusbr0), 10.100.2.0/24 (incus-hp2 incusbr0), 10.179.99.0/24 (incus-kr2 APISIX 전용), 10.42.0.0/16 (k8s 파드), 10.43.0.0/16 (k8s 서비스 ClusterIP), 172.17.0.0/16 (Docker 브릿지, 무시), 192.168.9.0/24 (kaffa 로컬 LAN)