Initial commit: Add runbooks collection

- anvil-load-test-report.md
- claude_communication_flow.md
- incus-crowdsec-architecture.md
- incus-meilisearch-manual.md
- kitty-setup-guide.md
- OpenAppSec_WAF_Operations_Guide.md
- openappsec-setup-20250817.md
- xray-proxy-guide.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
kappa
2026-01-16 00:31:54 +09:00
commit 53a655d4d5
8 changed files with 2835 additions and 0 deletions

View File

@@ -0,0 +1,305 @@
# OpenAppSec WAF 운영 가이드
## 📋 시스템 개요
**구축 환경**: incus 컨테이너 기반
**구성**: Agent (보안 엔진) + OCI (프록시)
**IP 주소**:
- Agent: 10.90.135.243
- OCI: 10.90.135.233
**메모리 사용량**: Agent 184MB + OCI 58MB = 242MB
**성능**: 290+ RPS, 15-25ms 응답시간
## 🔧 핵심 설정 파일 위치
### Agent 컨테이너 (openappsec-agent)
```bash
# 정책 파일들
/etc/cp/conf/production_policy.yaml # 운영 정책 (현재 적용)
/etc/cp/conf/local_policy_learning.yaml # Learning 모드
/etc/cp/conf/local_policy_high_confidence.yaml # High Confidence
/etc/cp/conf/local_policy_with_exceptions.yaml # Exception 규칙 포함
# 제어 스크립트
/etc/cp/scripts/open-appsec-ctl.sh # 메인 제어 스크립트
/usr/local/bin/waf-monitor.sh # 모니터링 스크립트
/usr/local/bin/waf-emergency.sh # 비상 복구 스크립트
# 로그 파일
/var/log/nano_agent/cp-nano-http-transaction-handler.log*
/var/log/waf-monitor.log # 모니터링 로그
/var/log/waf-emergency.log # 비상 작업 로그
```
### OCI 컨테이너 (openappsec-oci)
```bash
# nginx 설정
/etc/nginx/conf.d/production.conf # 운영 환경 설정
/etc/nginx/conf.d/default.conf # 기본 설정 (백업)
# 로그 파일
/var/log/nginx/access.log
/var/log/nginx/error.log
```
## 🚀 일상 운영 명령어
### 상태 확인
```bash
# WAF 전체 상태 확인
incus exec openappsec-agent -- /etc/cp/scripts/open-appsec-ctl.sh --status
# 확장 상태 정보
incus exec openappsec-agent -- /etc/cp/scripts/open-appsec-ctl.sh --status --extended
# 현재 적용 정책 확인
incus exec openappsec-agent -- /etc/cp/scripts/open-appsec-ctl.sh --view-policy
# 컨테이너 리소스 사용량
incus info openappsec-agent | grep "Memory usage"
incus info openappsec-oci | grep "Memory usage"
```
### 정책 관리
```bash
# 정책 변경 (Learning 모드)
incus exec openappsec-agent -- /etc/cp/scripts/open-appsec-ctl.sh --apply-policy /etc/cp/conf/local_policy_learning.yaml
# 정책 변경 (High Confidence)
incus exec openappsec-agent -- /etc/cp/scripts/open-appsec-ctl.sh --apply-policy /etc/cp/conf/local_policy_high_confidence.yaml
# 정책 변경 (운영 모드)
incus exec openappsec-agent -- /etc/cp/scripts/open-appsec-ctl.sh --apply-policy /etc/cp/conf/production_policy.yaml
```
### 로그 모니터링
```bash
# 실시간 보안 이벤트 확인
incus exec openappsec-agent -- tail -f /var/log/nano_agent/cp-nano-http-transaction-handler.log1
# 최근 차단/탐지 이벤트 분석
incus exec openappsec-agent -- grep "Web Request" /var/log/nano_agent/*.log* | tail -10 | jq '.eventData'
# 모니터링 로그 확인
incus exec openappsec-agent -- tail -20 /var/log/waf-monitor.log
# nginx 접근 로그
incus exec openappsec-oci -- tail -f /var/log/nginx/access.log
```
## 🆘 비상 대응 절차
### 긴급 상황별 대응
```bash
# 1. 오탐으로 정상 사용자 차단 시 (즉시 실행)
incus exec openappsec-agent -- /usr/local/bin/waf-emergency.sh bypass
# 2. WAF 서비스 문제 시
incus exec openappsec-agent -- /usr/local/bin/waf-emergency.sh restart
# 3. 심각한 서비스 장애 시
incus exec openappsec-agent -- /usr/local/bin/waf-emergency.sh disable
# 4. 정상 상태로 복구
incus exec openappsec-agent -- /usr/local/bin/waf-emergency.sh restore
```
### 롤백 절차
1. **백업 정책 복원**: 이전 정책 파일로 복구
2. **서비스 재시작**: WAF 서비스 재시작
3. **상태 확인**: 정상 동작 검증
4. **모니터링 강화**: 24시간 집중 관찰
## 📊 성능 모니터링
### 일일 체크리스트
- [ ] WAF 서비스 상태 정상
- [ ] 메모리 사용량 < 300MB
- [ ] 응답 시간 < 50ms
- [ ] 오탐 이벤트 < 5건/일
### 성능 측정 명령어
```bash
# 응답 시간 테스트
for i in {1..5}; do curl -w "응답시간: %{time_total}s\n" -s -o /dev/null "http://10.90.135.233/health"; done
# 동시 연결 처리 테스트
time (seq 1 50 | xargs -n1 -P10 -I{} curl -s -o /dev/null "http://10.90.135.233/health" 2>/dev/null)
# 메모리 사용량 상세 확인
incus exec openappsec-agent -- ps -eo pid,rss,vsz,comm,args | grep cp-nano
```
## 🔄 정책 전환 가이드
### Phase 1: Learning Mode (1-2주)
**목적**: 정상 트래픽 패턴 학습
**설정**: `detect-learn` 모드, 모든 요청 로깅
**모니터링**: 일일 로그 분석, 학습 진행도 확인
```bash
# Learning 모드 적용
incus exec openappsec-agent -- /etc/cp/scripts/open-appsec-ctl.sh --apply-policy /etc/cp/conf/local_policy_learning.yaml
# 학습 데이터 확인
incus exec openappsec-agent -- wc -l /var/log/nano_agent/*handler*.log*
```
### Phase 2: High Confidence (테스트)
**목적**: 고신뢰도 탐지만 차단, 오탐 최소화
**기준**: 일일 요청 1000+, 안정적 패턴 확립
```bash
# High Confidence 모드 적용
incus exec openappsec-agent -- /etc/cp/scripts/open-appsec-ctl.sh --apply-policy /etc/cp/conf/local_policy_high_confidence.yaml
```
**전환 조건**:
- ✅ 7-14일간 안정적 학습 데이터 축적
- ✅ 일일 오탐률 < 1%
- ✅ 모든 핵심 기능 정상 접근 확인
- ✅ 사용자 컴플레인 없음
### Phase 3: Production (운영)
**목적**: 전체 보안 기능 활성화
**설정**: `prevent` 모드, Exception 규칙 적용
## 🔍 트러블슈팅
### 일반적인 문제
**1. WAF 서비스 응답 없음**
```bash
# 프로세스 확인
incus exec openappsec-agent -- ps aux | grep cp-nano
# 포트 확인
incus exec openappsec-agent -- netstat -tlnp | grep 1200
# 재시작
incus exec openappsec-agent -- /usr/local/bin/waf-emergency.sh restart
```
**2. 높은 오탐률**
```bash
# 최근 차단 이벤트 분석
incus exec openappsec-agent -- grep "Prevent" /var/log/nano_agent/*.log* | tail -20
# Learning 모드로 임시 전환
incus exec openappsec-agent -- /usr/local/bin/waf-emergency.sh bypass
# Confidence 임계값 조정 (high로 변경)
incus exec openappsec-agent -- /etc/cp/scripts/open-appsec-ctl.sh --apply-policy /etc/cp/conf/local_policy_high_confidence.yaml
```
**3. 성능 저하**
```bash
# 메모리 사용량 확인
incus exec openappsec-agent -- free -h
incus exec openappsec-agent -- ps aux --sort=-%mem | head -10
# 로그 파일 크기 확인
incus exec openappsec-agent -- du -sh /var/log/nano_agent/
# 오래된 로그 정리
incus exec openappsec-agent -- find /var/log/nano_agent -name "*.log*" -mtime +3 -delete
```
## 📈 보안 이벤트 분석
### 이벤트 타입별 분석
```bash
# XSS 공격 탐지 현황
incus exec openappsec-agent -- grep "Cross Site Scripting" /var/log/nano_agent/*.log* | wc -l
# SQL Injection 탐지 현황
incus exec openappsec-agent -- grep "SQL Injection" /var/log/nano_agent/*.log* | wc -l
# 신뢰도별 이벤트 분석
incus exec openappsec-agent -- grep "eventConfidence" /var/log/nano_agent/*.log* | jq -r '.eventData.eventConfidence' | sort | uniq -c
```
### 공격자 IP 분석
```bash
# 최다 차단 IP 확인
incus exec openappsec-agent -- grep "sourceIP" /var/log/nano_agent/*.log* | jq -r '.eventData.sourceIP' | sort | uniq -c | sort -nr | head -10
# 특정 IP 차단 이력
incus exec openappsec-agent -- grep "1.2.3.4" /var/log/nano_agent/*.log* | jq '.eventData'
```
## 🔐 보안 정책 튜닝
### Exception 규칙 추가
```yaml
# /etc/cp/conf/local_policy_with_exceptions.yaml 수정 예시
exceptions:
- rule-id: "admin-panel"
uri-prefix: "/admin"
source-ip: ["10.90.135.0/24", "192.168.1.0/24"]
- rule-id: "api-endpoints"
uri-prefix: "/api"
specific-protections: ["csrf-protection"]
- rule-id: "file-upload"
uri-prefix: "/upload"
specific-protections: ["open-redirect"]
```
### Confidence 임계값 조정
- `low`: 모든 의심 활동 탐지 (높은 오탐)
- `medium`: 균형잡힌 탐지 (권장)
- `high`: 고신뢰도만 탐지 (낮은 오탐)
- `critical`: 매우 확실한 공격만 탐지
## 📅 정기 점검 일정
### 일일 (평일 오전 9시)
- WAF 서비스 상태 확인
- 전날 보안 이벤트 검토
- 메모리/CPU 사용량 확인
### 주간 (매주 월요일)
- 오탐 패턴 분석
- 성능 지표 리뷰
- 로그 용량 관리
### 월간 (매월 첫째 주)
- 전체 보안 정책 검토
- Exception 규칙 업데이트
- 백업 및 복구 테스트
- 보안 이벤트 통계 리포트
## 📞 에스컬레이션 연락처
**Level 1**: 일반 운영 이슈
**Level 2**: 보안 이벤트 급증
**Level 3**: 서비스 전면 장애
---
**문서 최종 업데이트**: 2025-08-17
**다음 검토 예정일**: 2025-09-17
## 🔖 빠른 참조
### 자주 사용하는 명령어
```bash
# 상태 확인
incus exec openappsec-agent -- /etc/cp/scripts/open-appsec-ctl.sh --status
# 비상 bypass
incus exec openappsec-agent -- /usr/local/bin/waf-emergency.sh bypass
# 로그 확인
incus exec openappsec-agent -- tail -f /var/log/nano_agent/cp-nano-http-transaction-handler.log1
# 성능 테스트
curl -w "응답시간: %{time_total}s\n" -s -o /dev/null "http://10.90.135.233/health"
```
### 정책 파일 경로 요약
- Learning: `/etc/cp/conf/local_policy_learning.yaml`
- High Confidence: `/etc/cp/conf/local_policy_high_confidence.yaml`
- Production: `/etc/cp/conf/production_policy.yaml`
- With Exceptions: `/etc/cp/conf/local_policy_with_exceptions.yaml`

406
anvil-load-test-report.md Normal file
View File

@@ -0,0 +1,406 @@
# Anvil 부하테스트 및 성능 최적화 보고서
**작성일**: 2026-01-10
**환경**: Incus jp1 → k8s (k3s) → anvil namespace
---
# Part 1. 핵심 요약
## 1. 아키텍처
```
┌─────────────────────────────────────────┐
│ k8s (k3s, max-pods=200) │
│ │
[Client] ──▶ Cloudflare ─┼─▶ Traefik (x3) │
(권장) │ │ │
│ ▼ │
│ Nginx (x2~15, HPA) │
│ │ │
│ ▼ │
│ PHP-FPM (x5~30, HPA) ─▶ Redis │
│ │ (Session) │
│ ▼ │
│ ProxySQL (Cache 256MB) │
│ │ │
└───────┼─────────────────────────────────┘
┌────────────┴────────────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ MariaDB-1 │ │ MariaDB-2 │
│ (Primary) │──Repl───▶ │ (Replica) │
└─────────────┘ └─────────────┘
```
---
## 2. 최종 성능 결과
### 2.1 Gnuboard5 (실제 애플리케이션)
| 항목 | Origin Only | + Cloudflare (예상) |
|------|-------------|---------------------|
| **최대 RPS** | **505.9** | **2,000+** |
| 성공률 | 100% | 100% |
| 평균 응답 | 390ms | ~50ms (캐시 HIT) |
### 2.2 simple-db.php (단순 쿼리)
| 항목 | 값 |
|------|-----|
| **최대 RPS** | **3,466** |
| 성공률 | 100% |
| 평균 응답 | 56ms |
### 2.3 예상 동시 접속자
| 시나리오 | Gnuboard5 |
|----------|-----------|
| Origin Only | ~1,700명 |
| **Cloudflare 70% 캐시** | **~5,600명** |
| **Cloudflare 80% 캐시** | **~8,500명** |
---
## 3. 최적화 적용 현황
| 영역 | 최적화 | 효과 | 상태 |
|------|--------|------|------|
| ProxySQL | Query Cache 256MB | DB 부하 99% 감소 | ✅ |
| ProxySQL | Read Replica 활용 | +21% RPS | ✅ |
| PHP | OPcache 256MB | PHP 컴파일 캐시 | ✅ |
| PHP | Redis 세션 | 세션 공유/속도 | ✅ |
| HPA | minReplicas 설정 | Cold Start 방지 | ✅ |
| MariaDB | Buffer Pool 512MB | 99.998% 히트율 | ✅ |
| **CDN** | **Cloudflare** | **+300% 예상** | ⏳ 권장 |
---
## 4. 핵심 설정값
### 4.1 HPA 설정
| Deployment | Min | Max | CPU Target |
|------------|-----|-----|------------|
| nginx | 2 | 15 | 70% |
| php-fpm | 5 | 30 | 70% |
### 4.2 리소스 설정
| 구성요소 | 설정 | 값 |
|----------|------|-----|
| MariaDB | max_connections | 500 |
| ProxySQL | Query Cache | 256MB, TTL 5초 |
| ProxySQL | Read Replica | hostgroup 1 |
| PHP | OPcache | 256MB, 20K files |
| PHP | Session | Redis |
| k3s | max-pods | 200 |
### 4.3 업로드 제한
| 구성요소 | 값 |
|----------|-----|
| Nginx | 100MB |
| PHP | 100MB |
---
## 5. 운영 체크리스트
### 필수 확인 사항
- [ ] HPA minReplicas 설정 확인 (nginx: 2, php-fpm: 5)
- [ ] ProxySQL Read Replica 설정 확인 (hostgroup 1)
- [ ] ProxySQL PVC 마운트 확인 (설정 영구 저장)
- [ ] OPcache 활성화 확인
- [ ] Redis 세션 연결 확인
- [ ] Cloudflare 적용 (권장)
### 모니터링 명령어
```bash
# k9s 실행
k9s
# HPA 상태
kubectl get hpa -n anvil
# Pod 리소스
kubectl top pods -n anvil
# ProxySQL 캐시 상태
kubectl exec -n anvil deploy/proxysql -- mysql -h127.0.0.1 -P6032 -uadmin -padmin \
-e "SELECT * FROM stats.stats_mysql_global WHERE Variable_Name LIKE '%Query_Cache%';"
```
---
## 6. 변경 이력
| 일시 | 변경 내용 | 효과 |
|------|----------|------|
| 2026-01-09 | MariaDB max_connections 151→500 | 연결 여유 확보 |
| 2026-01-09 | nginx/php-fpm CPU 2코어 | 처리량 증가 |
| 2026-01-09 | ProxySQL Query Cache 256MB | +17% RPS |
| 2026-01-09 | k3s max-pods 200 | Pod 확장성 |
| 2026-01-09 | OPcache 최적화 | PHP 성능 향상 |
| 2026-01-09 | HPA minReplicas 설정 | +6% RPS |
| 2026-01-09 | ProxySQL Read Replica | +21% RPS |
| 2026-01-09 | Real IP 설정 | 클라이언트 IP 추적 |
| 2026-01-09 | 파일 업로드 100MB | 대용량 파일 지원 |
| 2026-01-10 | 최종 문서 정리 | - |
---
# Part 2. 상세 설정 (참고)
## A. ProxySQL 설정
### Query Cache 설정
```sql
-- ProxySQL Admin (포트 6032) 접속
SET mysql-query_cache_size_MB = 256;
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;
-- SELECT 쿼리 캐시 + Read Replica 라우팅
INSERT INTO mysql_query_rules
(rule_id, active, match_digest, cache_ttl, destination_hostgroup, apply)
VALUES
(100, 1, '^SELECT', 5000, 1, 1);
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
```
### Hostgroup 구성
| Hostgroup | 서버 | 용도 |
|-----------|------|------|
| 0 | Primary (10.253.101.133) | Write |
| 1 | Primary + Replica | Read (캐시 + 부하분산) |
### 캐시 동작 흐름
```
요청 ──▶ ProxySQL
├─ Cache HIT (99.5%) ──▶ 즉시 응답 (0.1ms)
└─ Cache MISS (0.5%) ──▶ MariaDB (Primary/Replica)
└──▶ 캐시 저장 ──▶ 응답
```
---
## B. PHP 설정
### OPcache (opcache.ini)
```ini
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.fast_shutdown=1
opcache.interned_strings_buffer=16
```
### 세션 (session.ini)
```ini
session.save_handler = redis
session.save_path = "tcp://redis:6379"
```
### 업로드 (upload.ini)
```ini
upload_max_filesize = 100M
post_max_size = 100M
max_file_uploads = 20
max_execution_time = 300
max_input_time = 300
```
---
## C. Nginx 설정
### nginx.conf
```nginx
worker_processes auto;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
# Real IP
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
# Gzip
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript;
}
```
### default.conf (주요 부분)
```nginx
upstream php-upstream {
server php-fpm:9000;
keepalive 32;
}
server {
client_max_body_size 100m;
location ~ \.php$ {
fastcgi_pass php-upstream;
fastcgi_keep_conn on;
fastcgi_buffer_size 32k;
fastcgi_buffers 16 16k;
}
}
```
---
## D. Traefik Real IP 설정
```yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: traefik
namespace: kube-system
spec:
valuesContent: |-
additionalArguments:
- "--entryPoints.web.forwardedHeaders.insecure=true"
- "--entryPoints.websecure.forwardedHeaders.insecure=true"
```
---
## E. HPA 설정
### Cold Start 방지
```bash
kubectl patch hpa nginx-hpa -n anvil -p '{"spec":{"minReplicas":2}}'
kubectl patch hpa php-fpm-hpa -n anvil -p '{"spec":{"minReplicas":5}}'
```
---
## F. k3s 설정
### max-pods 증가
```bash
# /etc/rancher/k3s/config.yaml
kubelet-arg:
- "max-pods=200"
```
---
## G. MariaDB 상태 (참고)
| 지표 | 값 | 평가 |
|------|-----|------|
| Buffer Pool Size | 512MB | 적정 |
| Buffer Pool Hit Rate | 99.998% | 최상 |
| max_connections | 500 | 적정 |
| Slow Queries | 0 | 최상 |
---
## H. Cloudflare 설정 가이드 (권장)
### Cache Rules 설정
**Rule 1: 정적 파일**
```
If: File extension = css, js, jpg, png, gif, ico, woff2
Then: Cache (Edge TTL: 1 month)
```
**Rule 2: 게시판 페이지 (비로그인)**
```
If: URI contains "/gb5/" AND Cookie NOT contains "ck_mb_id"
Then: Cache (Edge TTL: 5 minutes)
```
**Rule 3: 관리자/글쓰기 제외**
```
If: URI contains "/adm" OR "/bbs/write" OR Cookie contains "ck_mb_id"
Then: Bypass cache
```
### 예상 효과
| 캐시 히트율 | 유효 RPS |
|------------|----------|
| 50% | ~1,000 |
| 70% | ~1,700 |
| 80% | ~2,500 |
---
## I. 성능 튜닝 히스토리
| 설정 | RPS | 성공률 | 비고 |
|------|-----|--------|------|
| 초기 상태 | ~150 | 93% | Cold Start |
| + CPU 2코어 | ~370 | 99% | - |
| + minReplicas | 419 | 99.98% | +6% |
| **+ Read Replica** | **505.9** | **100%** | **+21%** |
---
## J. 부하 테스트 명령어
```bash
# Gnuboard5 테스트
hey -n 20000 -c 200 -t 20 -host "gnu.anvil.it.com" "http://10.253.103.124/gb5/"
# simple-db.php 테스트
hey -n 20000 -c 200 -t 20 -host "gnu.anvil.it.com" "http://10.253.103.124/simple-db.php"
# ProxySQL 캐시 히트율 확인
kubectl exec -n anvil deploy/proxysql -- mysql -h127.0.0.1 -P6032 -uadmin -padmin \
-e "SELECT * FROM stats.stats_mysql_global WHERE Variable_Name LIKE '%Query_Cache%';"
```
---
## K. k9s 단축키
| 키 | 기능 |
|----|------|
| `:ns` | 네임스페이스 선택 |
| `:pod` | Pod 목록 |
| `:hpa` | HPA 목록 |
| `l` | 로그 보기 |
| `s` | Shell 접속 |
| `d` | Describe |
| `/` | 필터링 |

View File

@@ -0,0 +1,61 @@
# Claude Code 통신 흐름 시각화
## 1. 기본 통신 구조
```
┌─────────┐ ┌─────────┐ ┌─────────┐
│ User │ ──1──> │ Claude │ ──2──> │ API │
│ You │ <──4── │ Code │ <──3── │ Server │
└─────────┘ └─────────┘ └─────────┘
1: 질문 전송 (1-10 KB)
2: API 요청
3: 응답 생성
4: 결과 표시 (1-100 KB)
```
## 2. 통신 속도와 응답의 관계
```
빠른 네트워크 (100 Mbps+)
User ━━━━━━━━━━━━━━━━━━━━━━> Claude
<━━━━━━━━━━━━━━━━━━━━━━
전송: 0.1초 | 처리: 2초 | 수신: 0.1초
총 시간: ~2.2초
느린 네트워크 (1 Mbps)
User ────────────────────────> Claude
<────────────────────────
전송: 1초 | 처리: 2초 | 수신: 1초
총 시간: ~4초
```
## 3. 데이터 흐름 크기
```
┌────────────────────────────────────┐
│ 요청 타입별 데이터 크기 │
├────────────────────────────────────┤
│ 텍스트 질문 │ ▓░░░░░░░░░ │ 1-10 KB │
│ 코드 작업 │ ▓▓▓▓░░░░░░ │ 10-100 KB │
│ 파일 검색 │ ▓▓▓▓▓▓▓░░░ │ 100 KB-1 MB│
│ 이미지 처리 │ ▓▓▓▓▓▓▓▓▓▓ │ 1-10 MB │
└────────────────────────────────────┘
```
## 4. 처리 시간 구성
```
전체 응답 시간 = 네트워크 지연 + 처리 시간 + 전송 시간
┌─────────────────────────────────────────┐
│ 빠른 응답 (단순 질문) │
│ [▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░] 1-2초 │
│ └─처리시간─┘ │
│ │
│ 느린 응답 (복잡한 코드 분석) │
│ [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 5-10초 │
│ └────────처리시간──────────┘ │
└─────────────────────────────────────────┘
```
## 5. 핵심 포인트
- 🚀 **처리 시간은 고정**: 네트워크 속도와 무관
- 📡 **네트워크는 전송만 영향**: 느리면 기다리는 시간만 증가
- 🤖 **AI는 속도 인지 못함**: 단지 요청 받고 응답할 뿐

View File

@@ -0,0 +1,346 @@
# Multi-Layer Security Architecture with CrowdSec and OpenAppSec
## 🏗️ Infrastructure Overview
This document describes a multi-layer security architecture implemented using Incus containers, featuring CrowdSec community-driven threat intelligence and OpenAppSec ML-based WAF protection.
## 📋 Container Inventory
| Container | IP Address | Role | Technology |
|-----------|------------|------|------------|
| `ab-test` | 10.90.135.123 | Attack Simulation | curl/testing tools |
| `openresty` | 10.90.135.17 | Layer 1 Security | OpenResty + CrowdSec Bouncer |
| `crowdsec` | 10.90.135.49 | Threat Intelligence | CrowdSec Engine |
| `openappsec` | 10.90.135.186 | Layer 2 Security | ML-based WAF |
| `caddy` | 10.90.135.16 | Backend Server | Caddy HTTP Server |
| `php-auth` | 10.90.135.83 | Test Endpoint | PHP Authentication Service |
## 🏗️ Architecture Diagram
```
┌─────────────────────────────────────────────────────────────────┐
│ Incus Container Infrastructure │
│ (10.90.135.0/24) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 🌐 External Traffic Entry Point │
│ │
│ ┌─────────────────┐ │
│ │ ab-test │ ← Attack simulation container │
│ │ 10.90.135.123 │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 🛡️ Layer 1: Community-Driven Threat Intelligence │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ openresty │◄──►│ crowdsec │ │
│ │ 10.90.135.17 │ │ 10.90.135.49 │ │
│ │ │ │ │ │
│ │ • OpenResty │ │ • Threat Intel │ │
│ │ • CrowdSec │ │ • Scenarios │ │
│ │ Bouncer │ │ • Community DB │ │
│ │ • Rate Limiting │ │ • API Server │ │
│ │ • IP Blocking │ │ • Log Analysis │ │
│ └─────────────────┘ └─────────────────┘ │
│ │ │ │
│ └──── nginx-logs ────────┘ │
│ (Shared Volume: /var/log/nginx) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 🧠 Layer 2: ML-Based Application Security │
│ │
│ ┌─────────────────┐ │
│ │ openappsec │ │
│ │ 10.90.135.186 │ │
│ │ │ │
│ │ • ML WAF │ │
│ │ • Simple Model │ │
│ │ V1.0 │ │
│ │ • Zero-day │ │
│ │ Detection │ │
│ │ • No Signatures │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 🔗 Layer 3: Backend Application Server │
│ │
│ ┌─────────────────┐ │
│ │ caddy │ │
│ │ 10.90.135.16 │ │
│ │ │ │
│ │ • HTTP Server │ │
│ │ • Reverse Proxy │ │
│ │ • Auto HTTPS │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 🧪 Supporting Services │
│ │
│ ┌─────────────────┐ │
│ │ php-auth │ ← Authentication test endpoint │
│ │ 10.90.135.83 │ (Returns 401 for brute force testing) │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
## 📊 Traffic Flow & Security Processing
```
🌐 Attack Request
┌─────────────────┐
│ openresty │ ← CrowdSec Bouncer
│ 10.90.135.17 │ • Community threat intel
│ │ • Behavioral analysis
│ │ • IP reputation
│ │ • Rate limiting
└─────────────────┘
│ ✅ Allowed
┌─────────────────┐
│ openappsec │ ← ML-based WAF
│ 10.90.135.186 │ • Zero-day detection
│ │ • ML pattern analysis
│ │ • Application-layer security
└─────────────────┘
│ ✅ Clean
┌─────────────────┐
│ caddy │ ← Backend Server
│ 10.90.135.16 │ • Content delivery
│ │ • Application logic
└─────────────────┘
```
## 🔒 Security Layers Detail
### Layer 1: CrowdSec Community Intelligence
**Container**: `openresty` + `crowdsec`
**Key Features**:
- 🌍 Global threat intelligence sharing
- 🔍 HTTP brute force detection (`LePresidente/http-generic-401-bf`)
- 📊 Scenario-based behavioral analysis
- ⏱️ Real-time IP blocking (4-hour default ban)
- 🔄 Dynamic bouncer integration with OpenResty
**Scenarios Enabled**:
- `crowdsecurity/http-generic-bf` - Generic HTTP brute force detection
- `crowdsecurity/http-admin-interface-probing` - Admin interface scanning
- `crowdsecurity/http-probing` - General HTTP probing
- `crowdsecurity/http-cve-probing` - CVE exploitation attempts
- `crowdsecurity/http-sqli-probing` - SQL injection attempts
**Configuration**:
```yaml
# CrowdSec Acquisition
filenames:
- /var/log/nginx/access.log
- /var/log/nginx/error.log
labels:
type: nginx
```
### Layer 2: OpenAppSec ML WAF
**Container**: `openappsec`
**Key Features**:
- 🧠 Machine learning-based attack detection
- 🆕 Zero-day vulnerability protection
- 📝 No signature updates required
- ⚡ Simple Model V1.0 for fast processing
- 🔄 Automatic threat adaptation
**ML Model**: Simple Model V1.0
- Behavioral analysis
- Pattern recognition
- Anomaly detection
- Real-time learning
### Layer 3: Backend Application
**Container**: `caddy`
**Key Features**:
- 🔐 Automatic HTTPS with Let's Encrypt
- 🔄 Reverse proxy capabilities
- 📈 High-performance HTTP/2 support
- 🎯 Clean traffic processing
## 🧪 Testing Infrastructure
### Attack Simulation
- **Container**: `ab-test`
- **Purpose**: Simulate various attack patterns for testing
- **Tools**: curl, custom scripts
### Authentication Endpoint
- **Container**: `php-auth`
- **Purpose**: Generate 401/403 responses for brute force testing
- **Endpoint**: `/login.php` - Always returns 401 Unauthorized
## 🔧 Implementation Details
### Volume Mounts
```bash
# Shared nginx logs between openresty and crowdsec
nginx-logs: /var/log/nginx
```
### Network Configuration
- **Network**: incus default bridge (10.90.135.0/24)
- **Traffic Flow**: ab-test → openresty → openappsec → caddy
- **Special Routes**: `/admin/login` → php-auth (testing)
### Security Configuration
#### CrowdSec Bouncer
```yaml
API_URL: http://10.90.135.49:8080
API_KEY: s0ENc/6Tw+6m6tr0Qkjt/WAYU1QlC5/MzH7SQOCJX50
```
#### OpenResty Configuration
```nginx
upstream openappsec_backend {
server 10.90.135.186:80;
}
upstream auth_backend {
server 10.90.135.83:8080;
}
server {
listen 80;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location /admin/login {
proxy_pass http://auth_backend/login.php;
}
location / {
proxy_pass http://openappsec_backend;
}
}
```
## ✅ Testing Results
### Successful Test Cases
1. **Brute Force Detection**
- ✅ 6 failed login attempts → CrowdSec alert triggered
- ✅ IP `10.90.135.123` automatically banned
- ✅ Scenario: `LePresidente/http-generic-401-bf`
2. **IP Blocking**
- ✅ Banned IP receives `403 Forbidden`
- ✅ Traffic completely blocked at Layer 1
3. **IP Unbanning**
- ✅ Manual unban via `cscli decisions delete`
- ✅ Immediate traffic restoration
4. **Multi-Layer Coordination**
- ✅ OpenResty logs → CrowdSec analysis
- ✅ Real-time threat intelligence updates
- ✅ Seamless traffic flow through all layers
### Attack Patterns Tested
- HTTP brute force attacks (401 responses)
- Multiple rapid authentication attempts
- IP-based blocking and recovery
## 🚀 Deployment Commands
### Container Management
```bash
# List all containers
incus list
# Start security stack
incus start crowdsec openresty openappsec caddy
# Monitor CrowdSec
incus exec crowdsec -- cscli alerts list
incus exec crowdsec -- cscli decisions list
incus exec crowdsec -- cscli metrics
```
### Security Operations
```bash
# Ban an IP manually
incus exec crowdsec -- cscli decisions add --ip 1.2.3.4 --duration 4h --reason "manual-ban"
# Unban an IP
incus exec crowdsec -- cscli decisions delete --ip 1.2.3.4
# Check bouncer status
incus exec crowdsec -- cscli bouncers list
# View real-time logs
incus exec openresty -- tail -f /var/log/nginx/access.log
```
### Testing Commands
```bash
# Simulate brute force attack
incus exec ab-test -- bash -c 'for i in {1..6}; do
curl -X POST http://10.90.135.17/admin/login -d "username=admin&password=wrong$i"
sleep 1
done'
# Test blocked IP
incus exec ab-test -- curl -X POST http://10.90.135.17/admin/login -d "test=blocked"
```
## 🔍 Monitoring & Alerting
### CrowdSec Metrics
- **Acquisition**: Lines read, parsed, whitelisted
- **Scenarios**: Active scenarios, overflows, instantiations
- **Decisions**: Active bans, ban duration, ban reasons
- **API**: Bouncer heartbeats, decision pulls
### Log Locations
- **OpenResty**: `/var/log/nginx/access.log`, `/var/log/nginx/error.log`
- **CrowdSec**: Built-in metrics via `cscli metrics`
- **OpenAppSec**: Container logs via `incus exec openappsec -- logs`
## 📚 Key Learnings
1. **Whitelist Management**: Internal IP ranges need careful configuration for testing
2. **Log Format Compatibility**: OpenResty logs work well with CrowdSec nginx parsers
3. **Volume Sharing**: Critical for log analysis between containers
4. **Response Codes**: 401/403 responses trigger different CrowdSec scenarios
5. **Real-time Detection**: Sub-minute detection and blocking capabilities
## 🔮 Future Enhancements
- [ ] Custom CrowdSec scenarios for application-specific attacks
- [ ] Integration with external threat intelligence feeds
- [ ] Automated incident response workflows
- [ ] Performance monitoring and optimization
- [ ] Distributed deployment across multiple nodes
- [ ] SSL/TLS termination at OpenResty layer
- [ ] Rate limiting configuration fine-tuning
---
**Created**: 2025-08-17
**Last Updated**: 2025-08-17
**Architecture Version**: 1.0
**Status**: Production Ready ✅

312
incus-meilisearch-manual.md Normal file
View File

@@ -0,0 +1,312 @@
# Incus에서 Meilisearch 실행 매뉴얼
## 목차
1. [기본 실행](#1-기본-실행)
2. [환경변수 설정](#2-환경변수-설정)
3. [포트 포워딩](#3-포트-포워딩)
4. [볼륨 마운트](#4-볼륨-마운트)
5. [Docker Compose 변환](#5-docker-compose-변환)
6. [컨테이너 관리](#6-컨테이너-관리)
7. [문제 해결](#7-문제-해결)
---
## 1. 기본 실행
### 간단한 실행
```bash
incus launch docker.io/getmeili/meilisearch meilisearch-container
```
### 리소스 제한과 함께 실행
```bash
incus launch docker.io/getmeili/meilisearch meilisearch-container \
--config limits.cpu=2 \
--config limits.memory=1GB
```
---
## 2. 환경변수 설정
### 컨테이너 생성 시 환경변수 설정
```bash
incus launch docker.io/getmeili/meilisearch meilisearch-container \
--config environment.MEILI_MASTER_KEY=your-secret-key \
--config environment.MEILI_ENV=production \
--config environment.MEILI_DB_PATH=/data.ms
```
### 실행 중인 컨테이너에 환경변수 추가
```bash
# 컨테이너 중지
incus stop meilisearch-container
# 환경변수 설정
incus config set meilisearch-container environment.MEILI_MASTER_KEY=your-secret-key
incus config set meilisearch-container environment.MEILI_ENV=production
incus config set meilisearch-container environment.MEILI_DB_PATH=/data.ms
# 또는 한 번에 여러 개 설정
incus config set meilisearch-container \
environment.MEILI_MASTER_KEY=your-secret-key \
environment.MEILI_ENV=production \
environment.MEILI_DB_PATH=/data.ms
# 컨테이너 재시작
incus restart meilisearch-container
```
### 환경변수 확인 및 삭제
```bash
# 모든 설정 확인
incus config show meilisearch-container
# 특정 환경변수 확인
incus config get meilisearch-container environment.MEILI_MASTER_KEY
# 환경변수 삭제
incus config unset meilisearch-container environment.MEILI_MASTER_KEY
```
---
## 3. 포트 포워딩
### 포트 7700 포워딩
```bash
incus config device add meilisearch-container http proxy \
listen=tcp:0.0.0.0:7700 \
connect=tcp:127.0.0.1:7700
```
### 여러 포트 포워딩
```bash
# HTTP 포트
incus config device add meilisearch-container http proxy \
listen=tcp:0.0.0.0:7700 \
connect=tcp:127.0.0.1:7700
# 추가 포트 (예: metrics)
incus config device add meilisearch-container metrics proxy \
listen=tcp:0.0.0.0:8080 \
connect=tcp:127.0.0.1:8080
```
### 포트 포워딩 확인
```bash
incus config device show meilisearch-container
```
---
## 4. 볼륨 마운트
### 데이터 디렉토리 마운트
```bash
# 호스트 디렉토리를 컨테이너에 마운트
incus config device add meilisearch-container data disk \
source=/home/user/meilisearch-data \
path=/data.ms
```
### 스토리지 풀 사용
```bash
# 스토리지 풀 생성
incus storage create meilisearch-pool dir
# 볼륨 생성
incus storage volume create meilisearch-pool meilisearch-data
# 볼륨 연결
incus config device add meilisearch-container data disk \
pool=meilisearch-pool \
source=meilisearch-data \
path=/data.ms
```
---
## 5. Docker Compose 변환
### Docker Compose 예시
```yaml
version: '3'
services:
meilisearch:
image: getmeili/meilisearch:latest
environment:
- MEILI_MASTER_KEY=masterKey
- MEILI_ENV=production
- MEILI_DB_PATH=/data.ms
ports:
- "7700:7700"
volumes:
- ./data:/data.ms
restart: always
```
### Incus 명령어로 변환
```bash
#!/bin/bash
# meilisearch-setup.sh
# 1. 컨테이너 생성 및 환경변수 설정
incus launch docker.io/getmeili/meilisearch:latest meilisearch \
--config environment.MEILI_MASTER_KEY=masterKey \
--config environment.MEILI_ENV=production \
--config environment.MEILI_DB_PATH=/data.ms
# 2. 포트 포워딩 설정
incus config device add meilisearch http proxy \
listen=tcp:0.0.0.0:7700 \
connect=tcp:127.0.0.1:7700
# 3. 볼륨 마운트
incus config device add meilisearch data disk \
source=$(pwd)/data \
path=/data.ms
# 4. 자동 재시작 설정
incus config set meilisearch boot.autostart=true
```
---
## 6. 컨테이너 관리
### 기본 명령어
```bash
# 시작
incus start meilisearch-container
# 중지
incus stop meilisearch-container
# 재시작
incus restart meilisearch-container
# 삭제
incus delete meilisearch-container --force
# 상태 확인
incus list meilisearch-container
```
### 로그 및 모니터링
```bash
# 로그 확인
incus logs meilisearch-container
# 실시간 로그
incus logs meilisearch-container --follow
# 컨테이너 접속
incus exec meilisearch-container -- /bin/bash
# 프로세스 확인
incus exec meilisearch-container -- ps aux
```
### 리소스 모니터링
```bash
# CPU/메모리 사용량
incus info meilisearch-container
# 상세 정보
incus config show meilisearch-container
```
---
## 7. 문제 해결
### 포트 접속 안 될 때
```bash
# 포트 포워딩 확인
incus config device show meilisearch-container
# 컨테이너 내부에서 서비스 확인
incus exec meilisearch-container -- netstat -tlnp
# 방화벽 확인 (호스트)
sudo ufw status
```
### 환경변수 적용 안 될 때
```bash
# 환경변수 확인
incus exec meilisearch-container -- env | grep MEILI
# 재시작
incus restart meilisearch-container
```
### 데이터 영속성 문제
```bash
# 마운트 확인
incus config device show meilisearch-container
# 권한 확인
incus exec meilisearch-container -- ls -la /data.ms
```
---
## 실전 예제
### Production 환경 설정
```bash
#!/bin/bash
# 변수 설정
CONTAINER_NAME="meilisearch-prod"
MASTER_KEY="$(openssl rand -base64 32)"
DATA_PATH="/var/lib/meilisearch"
# 데이터 디렉토리 생성
sudo mkdir -p $DATA_PATH
# 컨테이너 생성
incus launch docker.io/getmeili/meilisearch:latest $CONTAINER_NAME \
--config limits.cpu=4 \
--config limits.memory=4GB \
--config environment.MEILI_MASTER_KEY=$MASTER_KEY \
--config environment.MEILI_ENV=production \
--config environment.MEILI_DB_PATH=/data.ms \
--config environment.MEILI_LOG_LEVEL=INFO
# 포트 설정
incus config device add $CONTAINER_NAME http proxy \
listen=tcp:0.0.0.0:7700 \
connect=tcp:127.0.0.1:7700
# 볼륨 마운트
incus config device add $CONTAINER_NAME data disk \
source=$DATA_PATH \
path=/data.ms
# 자동 시작 설정
incus config set $CONTAINER_NAME boot.autostart=true
echo "Meilisearch Master Key: $MASTER_KEY"
echo "Access URL: http://localhost:7700"
```
---
## 참고 사항
- Meilisearch 기본 포트: 7700
- 프로덕션 환경에서는 반드시 `MEILI_MASTER_KEY` 설정
- 데이터 영속성을 위해 볼륨 마운트 권장
- 리소스 제한 설정으로 시스템 안정성 확보
- 정기적인 백업 필요 (데이터 디렉토리 백업)
---
## 추가 리소스
- [Meilisearch 공식 문서](https://docs.meilisearch.com/)
- [Incus 공식 문서](https://linuxcontainers.org/incus/docs/main/)
- [Docker Hub - Meilisearch](https://hub.docker.com/r/getmeili/meilisearch)

321
kitty-setup-guide.md Normal file
View File

@@ -0,0 +1,321 @@
# Kitty Terminal 완벽 설정 가이드
최적화된 kitty 터미널 환경 구성 가이드입니다. Fira Code Nerd Font, Dracula 테마, Fish Shell, tmux 통합이 포함되어 있습니다.
## 📋 목차
- [설치된 구성 요소](#설치된-구성-요소)
- [폰트 설정](#폰트-설정)
- [테마 설정](#테마-설정)
- [Shell Integration](#shell-integration)
- [tmux 통합](#tmux-통합)
- [키보드 단축키](#키보드-단축키)
- [유용한 명령어](#유용한-명령어)
- [설정 파일 위치](#설정-파일-위치)
## 🚀 설치된 구성 요소
### 폰트
- **Fira Code Nerd Font**: 리가처와 아이콘 지원
- **D2Coding**: 한글 최적화 (주석 처리됨, 필요시 활성화 가능)
### 테마
- **Dracula Theme**: 눈에 편한 어두운 테마
### Shell 통합
- **Fish Shell**: 스마트한 자동완성과 구문 강조
- **Fisher**: Fish 플러그인 매니저
- **플러그인들**:
- `done`: 명령어 완료 알림
- `pisces`: 자동 괄호 닫기
- `fzf.fish`: 퍼지 파인더 통합
### 멀티플렉서
- **tmux**: 세션 관리와 창 분할
- **Dracula 테마**: kitty와 일치하는 색상
## 🎨 폰트 설정
### 현재 설정
```conf
# 폰트 패밀리 (Fira Code Nerd Font)
font_family FiraCode Nerd Font
bold_font FiraCode Nerd Font Bold
italic_font FiraCode Nerd Font Light
bold_italic_font FiraCode Nerd Font SemiBold
# 폰트 크기
font_size 17.0
```
### 리가처 예시
- `!=``≠`
- `>=``≥`
- `=>``⇒`
- `->``→`
- `===``≡`
## 🧛‍♂️ Dracula 테마
### 색상 팔레트
- **배경**: `#282a36` (어두운 보라)
- **전경**: `#f8f8f2` (밝은 회색)
- **보라**: `#bd93f9`
- **핑크**: `#ff79c6`
- **청록**: `#8be9fd`
- **녹색**: `#50fa7b`
- **노랑**: `#f1fa8c`
### 설정 방법
```conf
# Dracula 테마 적용
include dracula.conf
```
## 🐚 Shell Integration
### kitty + Fish 통합 기능
#### 자동 설치된 플러그인
```bash
# Fisher 플러그인 매니저
fisher install jorgebucaran/fisher
# 유용한 플러그인들
fisher install franciscolourenco/done # 명령어 완료 알림
fisher install laughedelic/pisces # 자동 괄호 닫기
fisher install PatrickF1/fzf.fish # 퍼지 파인더
```
#### kitty 전용 명령어
```bash
icat image.png # 터미널에서 이미지 보기
kdiff file1 file2 # kitty diff 도구
kssh user@server # kitty SSH (ssh로 alias됨)
preview # fzf 파일 미리보기
# kitten 유틸리티 (새로 추가됨)
img filename.png # 이미지 보기 (icat 간편 alias)
imgls # 현재 폴더 이미지들 갤러리로 보기
clipboard # 클립보드 히스토리 관리
unicode # 유니코드 문자 입력기
hgrep pattern files # 클릭 가능한 grep 결과
```
#### SSH 최적화
```bash
# fish config에서 ssh가 kssh로 alias됨
alias ssh=kssh
# kitty SSH의 장점:
# - 테마 동기화 (Dracula 테마가 원격에서도 적용)
# - 드래그&드롭 파일 전송
# - 이미지 표시 지원
# - 고급 키보드 프로토콜
```
## 📺 tmux 통합
### tmux Dracula 테마
```bash
# 상태바 색상
set -g status-style 'bg=#282a36 fg=#f8f8f2'
set -g status-left '#[fg=#282a36,bg=#bd93f9,bold] #S #[fg=#bd93f9,bg=#282a36] '
set -g status-right '#[fg=#50fa7b,bg=#282a36] %Y-%m-%d #[fg=#8be9fd,bg=#282a36] %H:%M #[fg=#282a36,bg=#ff79c6,bold] #h '
# 패널 경계선
set -g pane-border-style 'fg=#6272a4 bg=#282a36'
set -g pane-active-border-style 'fg=#bd93f9 bg=#282a36'
```
### kitty 최적화
```bash
# tmux.conf에서 kitty 지원
set -g default-terminal "xterm-kitty"
set -g terminal-overrides "xterm-kitty:Tc"
set -s extended-keys on
set -as terminal-features 'xterm-kitty:extkeys'
```
## ⌨️ 키보드 단축키
### kitty 기본 단축키
```bash
# 폰트 크기 조절
Cmd + =/-/0 # 크기 증가/감소/초기화
# 탭 관리
Cmd + T # 새 탭
Cmd + W # 탭 닫기
Cmd + 1-5 # 탭 이동
# 창 분할
Cmd + Shift + D # 파일 diff 뷰어 (kitten)
Cmd + Shift + V # 하단 분할
# 설정 다시 로드
Cmd + Shift + R # kitty 설정 재로드
# kitten 통합 기능 (새로 추가됨)
Cmd + Shift + H # 클립보드 히스토리 관리
Cmd + Shift + I # 현재 폴더 이미지 갤러리 보기
Cmd + Shift + U # 유니코드 문자 입력기
```
### tmux 통합 단축키
```bash
# tmux 세션 관리 (kitty에서)
Cmd + Shift + N # 새 tmux 세션
Cmd + Shift + A # tmux 세션 연결/생성
Cmd + Shift + S # tmux 세션 선택
# tmux 패널 이동 (kitty에서)
Cmd + Shift + 화살표 # tmux 패널 이동
# Fish shell 기능
Cmd + Shift + Z/X # 이전/다음 프롬프트로 이동
Cmd + Shift + O # 마지막 명령어 출력 보기
Ctrl + G # 히스토리 검색 (fish에서)
```
### tmux 기본 단축키
```bash
# Prefix: Ctrl + A
Ctrl + A, | # 세로 분할
Ctrl + A, - # 가로 분할
Ctrl + A, h/j/k/l # 패널 이동 (vim 스타일)
Ctrl + A, r # 설정 다시 로드
# Alt 키 조합 (Prefix 불필요)
Alt + 화살표 # 패널 이동
Shift + 좌우화살표 # 창 이동
```
## 💻 유용한 명령어
### tmux 세션 관리
```bash
tm # tmux 시작
tma work # 'work' 세션에 연결
tmn project # 'project' 새 세션 생성
tml # 세션 목록 보기
tmk work # 'work' 세션 종료
```
### kitty 도구들
```bash
icat image.png # 이미지 터미널에서 보기
kdiff file1 file2 # 파일 비교
ssh user@server # kitty SSH (테마 동기화)
preview # fzf 파일 미리보기
```
### Fish 고급 기능
```bash
# fzf 통합
Ctrl + R # 명령어 히스토리 검색
Ctrl + Alt + F # 파일 검색
Ctrl + Alt + S # git 상태 검색
# 자동 완성
Tab # 스마트 자동완성
Tab Tab # 모든 옵션 보기
```
## 🐱 kitten 통합 기능
### 새로 추가된 kitten 기능들
```bash
# 키보드 단축키로 접근
Cmd + Shift + H # 클립보드 히스토리 관리
Cmd + Shift + I # 현재 폴더 이미지 갤러리
Cmd + Shift + U # 유니코드 문자 입력기
Cmd + Shift + D # 파일 diff 뷰어
# 터미널 명령어로 접근
img image.png # 이미지 보기
imgls # 폴더 내 이미지들 갤러리
clipboard # 클립보드 히스토리
unicode # 유니코드 입력
hgrep pattern files # 클릭 가능한 grep
```
### kitten 활용 팁
- **이미지 갤러리**: 디자인 작업시 폴더 내 이미지들을 빠르게 미리보기
- **클립보드 히스토리**: 복사한 내용들을 기록해서 나중에 재사용
- **diff 뷰어**: 파일 비교를 터미널에서 깔끔하게
- **유니코드 입력**: 특수문자나 이모지를 쉽게 입력
## 📁 설정 파일 위치
### kitty 설정
```
~/.config/kitty/kitty.conf # 메인 설정 파일
~/.config/kitty/dracula.conf # Dracula 테마 파일
```
### Fish 설정
```
~/.config/fish/config.fish # Fish 메인 설정
~/.config/fish/fish_plugins # 설치된 플러그인 목록
```
### tmux 설정
```
~/.tmux.conf # tmux 설정 파일
```
## 🔧 설정 커스터마이징
### 테마 변경
이전 테마로 돌아가려면:
```conf
# kitty.conf에서
# include dracula.conf # 이 줄을 주석 처리
# 그리고 기존 색상 설정들의 주석을 해제
```
### 한글 폰트 활성화
D2Coding을 한글에 사용하려면:
```conf
# kitty.conf에서 23번 줄 주석 해제
symbol_map U+AC00-U+D7A3,U+1100-U+11FF,U+3130-U+318F,U+A960-U+A97F,U+D7B0-U+D7FF,U+302E-U+302F D2Coding
```
### 폰트 크기 변경
```conf
# kitty.conf 9번 줄
font_size 17.0 # 원하는 크기로 변경
```
## 🚀 추가 최적화 아이디어
### 더 많은 Fish 플러그인
```bash
fisher install jethrokuan/z # 스마트 디렉토리 점프
fisher install franciscolourenco/bass # Bash 스크립트 실행
fisher install edc/bass # 환경 변수 관리
```
### 추가 tmux 플러그인
```bash
# ~/.tmux.conf에 추가
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'tmux-plugins/tmux-resurrect'
```
### 기타 kitty 개선
- ✅ kitten 통합 완료 (클립보드, 이미지, diff, 유니코드)
- 추가 테마 설치 (Tokyo Night, Catppuccin 등)
- 더 많은 kitten 탐색 (session, transfer 등)
---
## 📝 노트
이 설정은 macOS와 kitty 0.42.2 버전을 기준으로 작성되었습니다. 다른 OS나 버전에서는 일부 설정이 다를 수 있습니다.
설정에 문제가 있거나 개선이 필요한 부분이 있다면 각 설정 파일을 개별적으로 수정할 수 있습니다.
**Happy coding! 🎉**

View File

@@ -0,0 +1,276 @@
# OpenAppSec Separate Container 구성 완료 보고서
## 📋 프로젝트 개요
**목표**: OpenAppSec을 incus 환경에서 Separate Container 방식으로 구성하여 1000명 동시접속 처리
**완료일**: 2025-08-17
**환경**: incus 컨테이너 플랫폼, 8코어 CPU, 15.6GB RAM
---
## 🏗️ 최종 아키텍처
### Separate Container 구조
```
Client Request
nginx-attachment (10.90.135.233)
↓ (Unix Socket via /dev/shm)
OpenAppSec Agent (10.90.135.243)
↓ (ML Security Analysis)
Backend Decision (Allow/Block)
Caddy Server (10.90.135.16)
```
### 컨테이너 구성
| 컨테이너명 | 이미지 | IP 주소 | 역할 | 리소스 |
|-----------|--------|---------|------|---------|
| **openappsec-oci** | `ghcr.io/openappsec/nginx-attachment:latest` | 10.90.135.233 | nginx + attachment | 4 CPU, 4GB RAM |
| **openappsec-agent** | `ghcr.io/openappsec/agent:latest` | 10.90.135.243 | ML 보안 엔진 | 4 CPU, 4GB RAM |
---
## 🔧 핵심 설정
### 1. IPC 통신 구성
```bash
# 두 컨테이너 모두 호스트 IPC 네임스페이스 공유
incus config set openappsec-oci raw.lxc="lxc.namespace.share.ipc=1"
incus config set openappsec-agent raw.lxc="lxc.namespace.share.ipc=1"
# 호스트 공유 메모리 마운트
incus config set openappsec-oci raw.lxc="lxc.namespace.share.ipc=1"$'\n'"lxc.mount.entry=/dev/shm dev/shm none bind,create=dir 0 0"
incus config set openappsec-agent raw.lxc="lxc.namespace.share.ipc=1"$'\n'"lxc.mount.entry=/dev/shm dev/shm none bind,create=dir 0 0"
```
### 2. 스토리지 볼륨 구성
```bash
# 정책 파일용 영구 스토리지
incus storage volume create default appsec
incus config device add openappsec-oci appsec-volume disk pool=default source=appsec path=/ext/appsec
```
### 3. 보안 정책 설정
```yaml
# /ext/appsec/local_policy.yaml
policies:
default:
mode: detect # 학습 모드
practices: [appsec-best-practice]
triggers: [appsec-log-trigger]
custom-response: 403-forbidden
practices:
- name: appsec-best-practice
web-attacks:
minimum-confidence: medium
override-mode: detect
max-body-size-kb: 1000
log-triggers:
- name: appsec-log-trigger
appsec-logging:
detect-events: true
prevent-events: true
log-destination:
stdout:
format: json
file:
path: /ext/appsec/security.log
format: json
max-file-size-mb: 100
max-files: 5
```
---
## ✅ 검증 결과
### 1. 컨테이너 상태
```bash
$ incus list | grep openappsec
| openappsec-agent | RUNNING | 10.90.135.243 (eth0) | CONTAINER (APP) |
| openappsec-oci | RUNNING | 10.90.135.233 (eth0) | CONTAINER (APP) |
```
### 2. IPC 통신 확인
```bash
$ incus exec openappsec-oci -- ls -la /dev/shm/check-point/
srw-rw-rw- 1 root root 0 Aug 17 06:07 cp-nano-attachment-registration
srw-rw-rw- 1 root root 0 Aug 17 06:07 cp-nano-http-transaction-handler-1
srw-rw-rw- 1 root root 0 Aug 17 06:07 cp-nano-http-transaction-handler-2
srw-rw-rw- 1 root root 0 Aug 17 06:07 cp-nano-http-transaction-handler-3
srw-rw-rw- 1 root root 0 Aug 17 06:07 cp-nano-http-transaction-handler-4
```
### 3. Agent 프로세스 확인
```bash
$ incus exec openappsec-agent -- ps aux | grep cp-nano
root 952 /etc/cp/orchestration/cp-nano-orchestration --orchestration-mode=hybrid_mode
root 985 /etc/cp/attachmentRegistrator/cp-nano-attachment-registrator
root 1036 /etc/cp/agentCache/cp-nano-agent-cache 127.0.0.1:6379
```
### 4. 네트워크 테스트
```bash
$ curl -s http://10.90.135.233/health
OCI OpenAppSec OK
$ curl -s -I http://10.90.135.233/ | grep X-Security
X-Security: OpenAppSec-OCI
```
---
## 🚀 성능 최적화
### 1000명 동시접속 대응 설정
#### nginx-attachment 최적화
```nginx
# /etc/nginx/nginx.conf
worker_processes 4; # 1000명/4 = 250명/워커
worker_connections 512; # 안전 여유분 포함
client_body_buffer_size 64k; # 메모리 효율성
keepalive_timeout 10s; # 빠른 연결 회전
```
#### 리소스 제한
```bash
# 각 컨테이너 4 CPU, 4GB RAM으로 제한
incus config set openappsec-oci limits.cpu=4 limits.memory=4GB
incus config set openappsec-agent limits.cpu=4 limits.memory=4GB
```
---
## 🔍 문제 해결 과정
### 1. 초기 문제: nginx-attachment만으로는 보안 기능 미작동
**원인**: attachment 모듈만 있고 실제 보안 분석을 담당하는 agent가 없음
**해결**: Separate Container 방식으로 agent 컨테이너 추가
### 2. IPC 통신 문제
**원인**: incus에서 `lxc.namespace.share.ipc=host` 문법 오류
**해결**: `lxc.namespace.share.ipc=1` (PID 1) 사용
### 3. Unix Socket 공유 문제
**원인**: 각 컨테이너가 독립적인 tmpfs 사용
**해결**: 호스트 `/dev/shm` 디렉토리를 두 컨테이너에 바인드 마운트
---
## 📊 Separate Container vs Unified Container 비교
| 구분 | Separate Container | Unified Container |
|------|-------------------|-------------------|
| **구성 복잡도** | 높음 (2개 컨테이너) | 낮음 (1개 컨테이너) |
| **리소스 효율성** | 독립적 스케일링 가능 | 고정적 리소스 할당 |
| **장애 격리** | 우수 (agent 장애 시 nginx 계속 동작) | 보통 (전체 장애) |
| **업데이트 유연성** | 독립적 업데이트 가능 | 통합 업데이트 필요 |
| **성능** | Unix Socket 오버헤드 | 프로세스 간 직접 통신 |
| **운영 복잡도** | 높음 | 낮음 |
---
## 🎯 장점 및 활용 방안
### Separate Container 방식의 장점
1. **확장성**
- nginx 트래픽 증가 시: attachment 컨테이너만 스케일 아웃
- 보안 처리 부하 증가 시: agent 컨테이너만 리소스 증설
2. **멀티 서비스 지원**
- 하나의 agent로 여러 nginx 인스턴스 처리 가능
- 중앙 집중식 보안 정책 관리
3. **운영 유연성**
- 독립적인 업데이트 및 배포
- 컴포넌트별 모니터링 및 로깅
### 향후 확장 계획
1. **고가용성 구성**
```bash
# Agent 이중화
incus copy openappsec-agent openappsec-agent-backup
# nginx-attachment 로드밸런싱
incus copy openappsec-oci openappsec-oci-2
```
2. **모니터링 구성**
- nginx-attachment: 응답 속도, 처리량 모니터링
- agent: 위협 탐지율, ML 정확도 모니터링
3. **보안 정책 고도화**
- 학습 모드 → 차단 모드 전환
- 도메인별 차별화된 보안 정책
---
## 📋 체크리스트
### 필수 구성 요소
- [x] nginx-attachment 컨테이너 (ghcr.io/openappsec/nginx-attachment:latest)
- [x] agent 컨테이너 (ghcr.io/openappsec/agent:latest)
- [x] IPC 네임스페이스 공유 설정
- [x] 공유 메모리 마운트 (/dev/shm)
- [x] 보안 정책 파일 (local_policy.yaml)
- [x] 영구 스토리지 볼륨 (appsec)
### 검증 항목
- [x] 컨테이너 정상 실행
- [x] Unix Socket 생성 확인
- [x] Agent 프로세스 실행 확인
- [x] 웹 서비스 응답 확인
- [x] 보안 헤더 확인
### 성능 테스트
- [x] 기본 응답 속도 테스트
- [x] 1000명 동접 리소스 계산
- [x] 컨테이너 리소스 제한 설정
---
## 🛡️ 보안 고려사항
1. **IPC 네임스페이스 공유 위험성**
- 호스트 IPC 자원에 접근 가능
- 프로덕션 환경에서는 추가 격리 방안 검토 필요
2. **정책 파일 보안**
- `/ext/appsec/local_policy.yaml` 파일 권한 관리
- 민감한 설정 정보 암호화 검토
3. **로깅 및 모니터링**
- 보안 이벤트 로그 중앙 집중화
- 실시간 위협 탐지 알림 구성
---
## 📞 지원 및 문의
**OpenAppSec 공식 문서**: https://docs.openappsec.io/
**GitHub Repository**: https://github.com/openappsec/openappsec
**Community Forum**: https://community.openappsec.io/
---
## 📅 버전 정보
- **OpenAppSec nginx-attachment**: latest (2025-08-17)
- **OpenAppSec agent**: latest (2025-08-17)
- **incus**: 최신 버전
- **nginx**: 1.25.4
- **정책 파일 버전**: v1.0 (detect 모드)
---
**문서 작성**: Claude Code SuperClaude Framework
**최종 수정**: 2025-08-17
**상태**: 구성 완료 ✅

808
xray-proxy-guide.md Normal file
View File

@@ -0,0 +1,808 @@
# Xray 프록시 완벽 가이드: XHTTP & Reality
> 검열 우회를 위한 스텔스 프록시 구축 가이드
>
> 참고 영상: [How to Hide a Proxy Inside a Real Website (Xray + XHTTP)](https://www.youtube.com/watch?v=NziF6Srh-08) - LinuxCloudHacks
---
## 목차
1. [핵심 개념](#핵심-개념)
2. [프로토콜 스택 이해](#프로토콜-스택-이해)
3. [XHTTP 설정](#xhttp-설정)
4. [Reality 설정](#reality-설정)
5. [XHTTP vs Reality 비교](#xhttp-vs-reality-비교)
6. [TLS와 검열 우회 원리](#tls와-검열-우회-원리)
7. [트러블슈팅](#트러블슈팅)
8. [참고 자료](#참고-자료)
---
## 핵심 개념
### 현대 검열의 문제점
기존 VPN/프록시가 차단되는 이유:
| 방식 | 탐지 방법 |
|------|----------|
| 일반 VPN | VPN 프로토콜 시그니처 탐지 |
| Shadowsocks | 랜덤 노이즈 패턴 → DPI가 "비정상" 판단 |
| 단순 프록시 | 특이한 포트, 서버 프로빙 시 프록시 응답 |
### 해결책: 섞여들기 (Blending In)
> "현대 검열은 숨김으로 이기는 게 아니라, **섞여들어감**으로 이긴다"
- 일반 HTTPS 트래픽처럼 보이게 위장
- 실제 웹사이트 또는 대형 사이트의 TLS를 활용
- 클라이언트와 서버 양쪽 모두 위장 필요
---
## 프로토콜 스택 이해
### 3계층 구조
```
┌─────────────────────────────────────────┐
│ TLS (누구처럼) │
│ - 암호화 │
│ - 핑거프린트 위장 (UTLS → Chrome 흉내) │
├─────────────────────────────────────────┤
│ XHTTP (어떻게) │
│ - HTTP POST/GET으로 데이터 전송 │
│ - 일반 API 트래픽처럼 보임 │
├─────────────────────────────────────────┤
│ VLESS (무엇을) │
│ - 프록시 프로토콜 │
│ - 경량, 상태 비저장 │
│ - UUID 기반 인증 │
└─────────────────────────────────────────┘
```
### VLESS 프레임 구조
```
[버전][클라이언트ID][명령][포트][주소타입][주소][페이로드...]
1B 16B 1B 2B 1B 가변 가변
```
- **명령**: 1=TCP, 2=UDP
- **주소타입**: 1=IPv4, 2=도메인, 3=IPv6
- **암호화 없음** → 전송 계층(TLS)에서 처리
### XHTTP 동작 방식
```
클라이언트 → 서버: HTTP POST (세션ID + VLESS 프레임)
서버 → 클라이언트: HTTP GET (스트리밍 응답)
```
- 세션 ID로 다중 연결 관리
- 병렬 POST 요청 가능 (Head-of-line blocking 회피)
- 일반 REST API 호출처럼 보임
---
## XHTTP 설정
### 아키텍처
```
[클라이언트]
↓ HTTPS (일반 브라우저처럼 보임)
[Nginx - Port 443]
├── / (루트) → 실제 게임 웹사이트
└── /api/stream (비밀 경로) → Xray (Port 8080)
[인터넷]
```
### 준비물
- Linux 서버 (VPS/클라우드)
- **도메인** (필수)
- DNS 제공자 (Cloudflare 등)
- 포트 80, 443 오픈
### 서버 설정
#### 1. Nginx + Certbot 설치
```bash
apt update && apt install -y nginx certbot python3-certbot-nginx
```
#### 2. 위장용 웹사이트 배포
```bash
# 기본 페이지 삭제 후 게임 템플릿 다운로드
rm /var/www/html/index.html
wget -O /var/www/html/index.html https://example.com/game-template.html
```
#### 3. SSL 인증서 발급
```bash
certbot certonly --webroot -w /var/www/html -d yourdomain.com
```
#### 4. Xray 설치
```bash
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
```
#### 5. UUID 생성
```bash
xray uuid
# 출력 예: a3482e88-686a-4a58-8126-99c9df64b060
```
#### 6. Xray 서버 설정
`/usr/local/etc/xray/config.json`:
```json
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"port": 8080,
"listen": "127.0.0.1",
"protocol": "vless",
"settings": {
"clients": [
{
"id": "여기에-UUID-입력"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "xhttp",
"xhttpSettings": {
"path": "/api/stream"
}
}
}
],
"outbounds": [
{
"protocol": "freedom"
}
]
}
```
#### 7. Nginx 설정
`/etc/nginx/sites-available/xray`:
```nginx
server {
listen 80;
server_name yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# 루트: 실제 웹사이트 (위장용)
location / {
root /var/www/html;
index index.html;
}
# 비밀 경로: Xray로 프록시
location /api/stream {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Connection "";
proxy_buffering off;
proxy_read_timeout 300s;
}
}
```
```bash
ln -sf /etc/nginx/sites-available/xray /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
nginx -t && systemctl reload nginx
systemctl restart xray
```
### 클라이언트 설정
#### CLI (config.json)
```json
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"port": 1080,
"listen": "127.0.0.1",
"protocol": "socks"
}
],
"outbounds": [
{
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "yourdomain.com",
"port": 443,
"users": [
{
"id": "서버와-동일한-UUID",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "xhttp",
"security": "tls",
"tlsSettings": {
"serverName": "yourdomain.com",
"fingerprint": "chrome"
},
"xhttpSettings": {
"path": "/api/stream"
}
}
}
]
}
```
#### V2rayN GUI 설정
| 항목 | 값 |
|------|-----|
| Address | yourdomain.com |
| Port | 443 |
| UUID | 서버와 동일 |
| Network | xhttp |
| Path | /api/stream |
| TLS | 활성화 |
| SNI | yourdomain.com |
| Fingerprint | chrome |
---
## Reality 설정
### Reality란?
> **도메인/인증서 없이, 대형 사이트의 TLS를 빌려 쓰는 기술**
```
[클라이언트] --TLS(SNI: www.microsoft.com)--> [내 서버:443]
Reality가 TLS 처리
(microsoft.com 인증서 흉내)
[인터넷]
```
외부에서 보이는 것: `www.microsoft.com`에 접속
실제: 내 VPS를 통해 터널링
### 준비물
- Linux 서버 (VPS/클라우드)
- 포트 443 오픈
- **도메인 불필요!**
### 서버 설정
#### 1. Xray 설치
```bash
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
```
#### 2. 키 생성
```bash
# UUID 생성
xray uuid
# 출력 예: a3482e88-686a-4a58-8126-99c9df64b060
# X25519 키쌍 생성
xray x25519
# 출력 예:
# Private key: 2KZ4uouMKgI8nR-LDJNP1_MHisCJOmKGj9jUjZLncVU
# Public key: Z84J2IelR9ch3k8VtlVhhs5ycBUlXA7wHBWcBrjqnAw
# Short ID 생성
openssl rand -hex 8
# 출력 예: 6ba85179e30d4fc2
```
#### 3. 위장 사이트 선택
**선택 기준**:
| 조건 | 설명 |
|------|------|
| 외국 사이트 | 검열 대상이 아닌 사이트 |
| TLSv1.3 지원 | 필수 |
| H2 지원 | HTTP/2 지원 필요 |
| 리다이렉트 없음 | URL이 다른 곳으로 이동하지 않음 |
| 서버와 가까운 지역 | 보너스 (속도 향상) |
**추천 사이트**:
- `www.microsoft.com`
- `www.apple.com`
- `www.amazon.com`
- `www.cloudflare.com`
- `www.yahoo.com`
#### 4. 서버 설정 파일
`/usr/local/etc/xray/config.json`:
```json
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"listen": "0.0.0.0",
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "여기에-UUID-입력",
"flow": "xtls-rprx-vision"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"dest": "www.microsoft.com:443",
"serverNames": [
"www.microsoft.com",
"microsoft.com"
],
"privateKey": "여기에-Private-Key-입력",
"shortIds": [
"여기에-Short-ID-입력"
]
}
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "direct"
}
]
}
```
```bash
systemctl restart xray
systemctl status xray
```
### 클라이언트 설정
#### CLI (config.json)
```json
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"listen": "127.0.0.1",
"port": 1080,
"protocol": "socks"
}
],
"outbounds": [
{
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "서버-IP-주소",
"port": 443,
"users": [
{
"id": "서버와-동일한-UUID",
"encryption": "none",
"flow": "xtls-rprx-vision"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"fingerprint": "chrome",
"serverName": "www.microsoft.com",
"publicKey": "서버의-Public-Key",
"shortId": "서버와-동일한-Short-ID"
}
},
"tag": "proxy"
},
{
"protocol": "freedom",
"tag": "direct"
}
]
}
```
#### V2rayN GUI 설정
| 항목 | 값 |
|------|-----|
| Address | 서버 IP |
| Port | 443 |
| UUID | 생성한 UUID |
| Flow | xtls-rprx-vision |
| Network | tcp |
| TLS | reality |
| SNI | www.microsoft.com |
| Fingerprint | chrome |
| Public Key | 서버에서 생성한 공개키 |
| Short ID | 서버와 동일 |
### Docker로 설정 (간편)
#### docker-compose.yml
```yaml
services:
xray:
image: ghcr.io/xtls/xray-core:latest
container_name: xray-reality
restart: unless-stopped
volumes:
- ./config.json:/usr/local/etc/xray/config.json:ro
ports:
- "443:443/tcp"
```
#### 키 생성 (Docker)
```bash
docker run --rm ghcr.io/xtls/xray-core x25519
docker run --rm ghcr.io/xtls/xray-core uuid
```
#### 실행
```bash
docker compose up -d
```
---
## XHTTP vs Reality 비교
### 기능 비교
| 구분 | XHTTP | Reality |
|------|-------|---------|
| 도메인 | 필요 | **불필요** |
| SSL 인증서 | 필요 (Let's Encrypt) | **불필요** |
| Nginx | 필요 | **불필요** |
| 설정 시간 | 30분+ | **5분** |
| CDN 통과 | **가능** | 불가 |
| 위장 방식 | 실제 웹사이트 운영 | 대형 사이트 TLS 흉내 |
| SNI 노출 | 내 도메인 | 대형 사이트 (microsoft.com 등) |
### 사용 시나리오
#### Reality 사용
| 상황 | 이유 |
|------|------|
| 도메인 없음 | 도메인 구매/관리 불필요 |
| 빠른 설정 | 키 생성만으로 완료 |
| VPS만 있음 | IP 하나로 바로 시작 |
| 단순 우회 목적 | 복잡한 구성 불필요 |
| SNI 노출 걱정 | 대형 사이트로 위장 |
#### XHTTP 사용
| 상황 | 이유 |
|------|------|
| CDN 필요 | Cloudflare 등 CDN 뒤에 숨기기 |
| IP 차단 환경 | VPS IP가 이미 차단된 경우 |
| 실제 서비스 운영 | 웹사이트 + 프록시 동시 운영 |
| 다수 사용자 | 여러 명에게 서비스 제공 |
| 서버 프로빙 대응 | 443 접속 시 실제 웹사이트 표시 |
### 결정 가이드
```
도메인이 없다 ──────────────────→ Reality
↓ 있다
VPS IP가 차단됐다 ─────────────→ XHTTP + CDN
↓ 아니다
SNI 노출이 걱정된다 ───────────→ Reality
↓ 괜찮다
실제 웹사이트도 운영할 것이다 ──→ XHTTP
↓ 아니다
빠른 설정을 원한다 ────────────→ Reality
```
---
## TLS와 검열 우회 원리
### TLS 핸드셰이크 구조
```
[클라이언트] [서버]
│ │
│─── Client Hello ──────────→│ 평문! (SNI 노출)
│ │
│←── Server Hello ───────────│
│←── Certificate ────────────│
│←── Server Key Exchange ────│
│ │
│─── Client Key Exchange ───→│
│─── Finished ──────────────→│
│ │
│←── Finished ───────────────│
│ │
[암호화 통신 시작]
```
### Client Hello 구조
```
TLS Record Layer
├── Content Type: 0x16 (Handshake)
├── Version: 0x0301
└── Handshake Protocol
├── Type: 0x01 (Client Hello)
└── Client Hello Data
├── Version: 0x0303 (TLS 1.2)
├── Random: 32바이트
├── Session ID
├── Cipher Suites (암호화 목록)
├── Compression Methods
└── Extensions
├── SNI (server_name) ← 평문 노출!
├── Supported Versions
├── Signature Algorithms
└── ...
```
### SNI 노출 문제
**SNI(Server Name Indication)**는 TLS 암호화 **전**에 평문으로 전송됨:
```
Extension: server_name
├── Type: 0x0000 (SNI)
└── Server Name
└── Name: "www.microsoft.com" ← ISP가 볼 수 있음
```
| 방식 | SNI에 보이는 것 | 위험도 |
|------|----------------|--------|
| XHTTP | `myproxy.com` (내 도메인) | 도메인 차단 가능 |
| Reality | `www.microsoft.com` | 차단 어려움 |
### DPI 핑거프린팅
검열 시스템이 Client Hello를 분석하는 방식:
```
Client Hello 수신
특징 추출:
- Cipher Suite 개수 및 순서
- Extension 목록 및 순서
- Supported Groups
- 전체 패킷 길이
데이터베이스 비교:
- Chrome: 일치 ✓
- Firefox: 불일치
- Python requests: 불일치
결과: "Chrome 브라우저로 판단"
```
### UTLS를 통한 위장
Xray는 **UTLS** 라이브러리를 사용하여 실제 브라우저의 Client Hello를 **바이트 단위로** 복제:
```json
{
"tlsSettings": {
"fingerprint": "chrome" // Chrome의 정확한 핑거프린트 사용
}
}
```
복제하는 요소:
- Cipher Suites (암호화 알고리즘 목록 + 순서)
- Extensions (확장 목록 + 순서)
- Supported Groups (지원 곡선)
- Signature Algorithms (서명 알고리즘)
- ALPN (프로토콜 협상)
- Key Share (키 교환 데이터)
### 서버 측 위장의 필요성
**양방향 모두 위장 필요**:
| 방향 | 검사 대상 | 위장 주체 |
|------|----------|----------|
| Client → Server | Client Hello, SNI | 클라이언트 (UTLS) |
| Server → Client | 인증서, Server Hello | 서버 설정 |
#### Reality 서버의 프로빙 대응
```
정상 클라이언트 (올바른 shortId/publicKey):
서버: "인증된 클라이언트"
Reality 터널 연결 ✓
프로빙/스캐너 (shortId 없음):
서버: "모르는 요청"
실제 microsoft.com으로 포워딩
스캐너: "그냥 microsoft.com이네" → 의심 없음
```
#### XHTTP 서버의 프로빙 대응
```
일반 접속 (루트 경로):
Nginx: 게임 웹사이트 표시 ✓
프록시 클라이언트 (비밀 경로):
Nginx: Xray로 프록시 ✓
```
---
## 트러블슈팅
### 공통 문제
| 문제 | 원인 | 해결 |
|------|------|------|
| 연결 안됨 | 방화벽 | 443 포트 오픈 확인 |
| 인증 실패 | UUID 불일치 | 서버/클라이언트 UUID 동일한지 확인 |
| 느린 속도 | 서버 위치 | 더 가까운 VPS 선택 |
### XHTTP 문제
| 문제 | 원인 | 해결 |
|------|------|------|
| 502 Bad Gateway | Xray 미실행 | `systemctl status xray` 확인 |
| SSL 에러 | 인증서 만료 | `certbot renew` 실행 |
| 경로 불일치 | path 설정 | Nginx와 Xray의 path 동일한지 확인 |
### Reality 문제
| 문제 | 원인 | 해결 |
|------|------|------|
| TLS 에러 | 위장 사이트 문제 | TLSv1.3 지원 사이트로 변경 |
| shortId 에러 | ID 불일치 | 서버/클라이언트 shortId 확인 |
| 키 에러 | 공개키/개인키 혼동 | 서버=개인키, 클라이언트=공개키 |
### 연결 테스트
```bash
# 서버에서 Xray 상태 확인
systemctl status xray
journalctl -u xray -f
# 클라이언트에서 연결 테스트
curl -x socks5h://127.0.0.1:1080 https://ipinfo.io
```
---
## 참고 자료
### 공식 문서
- [Project X 공식 문서](https://xtls.github.io/en/config/)
- [XTLS/Xray-core GitHub](https://github.com/XTLS/Xray-core)
### 튜토리얼
- [Xray REALITY Tutorial - cscot](https://cscot.pages.dev/2023/03/02/Xray-REALITY-tutorial/)
- [XRAY XTLS Reality in Docker](https://linuxguidance.net/xray-xtls-reality-in-docker/)
- [XRAY XHTTP Behind Cloudflare CDN](https://linuxguidance.net/xray-xhttp-server-behind-cloudflares-cdn-in-docker/)
- [Coexisting Xray VLESS with XHTTP-Reality](https://henrywithu.com/coexisting-xray-vless-tcp-xtls-vision-and-vless-xhttp-reality-on-a-single-port/)
### GitHub Discussions
- [VLESS + TCP + REALITY + VISION 설정](https://github.com/XTLS/Xray-core/discussions/3518)
- [Xray + VLESS + Reality + Caddy](https://github.com/XTLS/Xray-core/discussions/4542)
### 클라이언트 앱
- **Windows**: [v2rayN](https://github.com/2dust/v2rayN)
- **macOS**: [V2rayU](https://github.com/yanue/V2rayU)
- **Android**: [v2rayNG](https://github.com/2dust/v2rayNG)
- **iOS**: Shadowrocket (유료), Quantumult X
---
## 부록: 빠른 설정 체크리스트
### Reality 설정 (5분)
- [ ] VPS 준비 (포트 443 오픈)
- [ ] Xray 설치
- [ ] UUID 생성
- [ ] X25519 키쌍 생성
- [ ] Short ID 생성
- [ ] 서버 config.json 작성
- [ ] 클라이언트 설정
### XHTTP 설정 (30분)
- [ ] VPS 준비 (포트 80, 443 오픈)
- [ ] 도메인 준비 + DNS 설정
- [ ] Nginx 설치
- [ ] 위장용 웹사이트 배포
- [ ] Certbot으로 SSL 인증서 발급
- [ ] Xray 설치
- [ ] UUID 생성
- [ ] Xray config.json 작성
- [ ] Nginx 설정 (루트 + 비밀 경로)
- [ ] 클라이언트 설정
---
*마지막 업데이트: 2025-01*