docs: add MC Domain Filter Proxy spec

This commit is contained in:
tkrmagid
2026-05-20 16:25:37 +09:00
parent 979dd577c7
commit b45e884633

223
mc-domain-filter.md Normal file
View File

@@ -0,0 +1,223 @@
# MC Domain Filter Proxy
마인크래프트 서버 접속 시 특정 도메인(`mc.tkrmagid.kr`)으로만 접속 가능하게 필터링하는 프록시 + 웹 관리 대시보드
---
## 프로젝트 개요
### 목적
- 외부 IP 직접입력, 다른 도메인으로 접속 시 차단
- `mc.tkrmagid.kr` 도메인으로만 마인크래프트 서버 접속 허용
- Fabric, Paper, Spigot, NeoForge 등 **어떤 서버 종류든 무관하게** 동작
### 동작 원리
마인크래프트 클라이언트는 접속 시 첫 핸드셰이크 패킷에 사용자가 입력한 주소(서버 주소창의 문자열)를 담아 전송한다.
이 프록시는 해당 패킷을 읽어 허용된 도메인이 아니면 연결을 즉시 차단한다.
### 네트워크 구조
```
외부 인터넷
공유기 (포트포워딩 25565 → Proxmox IP)
Proxmox Docker 컨테이너 (MC Domain Filter)
게임PC 내부IP:25565 (실제 마인크래프트 서버)
```
---
## 기술 스택
| 구성 요소 | 기술 |
|-----------|------|
| 프록시 코어 | Python (asyncio) |
| 웹 대시보드 | React + Vite (또는 Next.js) |
| 백엔드 API | FastAPI |
| 설정 저장 | JSON 파일 (sqlite도 가능) |
| 컨테이너 | Docker + docker-compose |
| 리버스 프록시 | nginx (대시보드용) |
---
## 기능 요구사항
### 핵심 기능 (프록시)
- [ ] Minecraft 핸드셰이크 패킷 파싱 (varint 포함)
- [ ] 허용 도메인 리스트와 비교 후 차단/통과 결정
- [ ] 통과된 패킷을 백엔드 서버로 투명하게 중계
- [ ] 첫 패킷 이후 양방향 TCP 터널링
### 웹 대시보드 (NPM 스타일 UI)
- [ ] **허용 도메인 관리** - 추가 / 삭제 / 활성화 토글
- [ ] **백엔드 서버 설정** - 게임PC IP, 포트 변경
- [ ] **실시간 접속 로그** - 허용/차단 내역, 접속 IP, 사용 도메인, 시각
- [ ] **대시보드 홈** - 현재 상태, 총 접속 수, 차단 수 통계 카드
- [ ] **프록시 on/off** 토글
- [ ] 설정 변경 후 프록시 재시작 없이 즉시 반영 (hot reload)
### UI 디자인 레퍼런스
- **Nginx Proxy Manager Plus** 스타일
- 다크/라이트 모드
- 사이드바 네비게이션
- 카드 기반 레이아웃
- 토글 스위치, 모달 폼
---
## 프로젝트 구조
```
mc-domain-filter/
├── docker-compose.yml
├── proxy/
│ ├── Dockerfile
│ ├── main.py # asyncio TCP 프록시
│ ├── config.py # 설정 로드/저장
│ ├── handshake.py # MC 핸드셰이크 파서
│ └── requirements.txt
├── api/
│ ├── Dockerfile
│ ├── main.py # FastAPI 백엔드
│ ├── routes/
│ │ ├── config.py # 설정 CRUD
│ │ └── logs.py # 로그 조회
│ └── requirements.txt
├── frontend/
│ ├── Dockerfile
│ ├── src/
│ │ ├── pages/
│ │ │ ├── Dashboard.jsx
│ │ │ ├── Domains.jsx
│ │ │ └── Logs.jsx
│ │ └── components/
│ └── package.json
├── nginx/
│ └── nginx.conf
└── data/
├── config.json # 설정 파일 (볼륨 마운트)
└── logs.db # 접속 로그
```
---
## 설정 파일 구조 (config.json)
```json
{
"proxy": {
"listen_port": 25565,
"enabled": true
},
"backend": {
"host": "192.168.0.xx",
"port": 25565
},
"allowed_domains": [
{
"domain": "mc.tkrmagid.kr",
"enabled": true,
"note": "메인 도메인"
}
]
}
```
---
## Minecraft 핸드셰이크 파싱
```
패킷 구조:
[varint] Packet Length
[varint] Packet ID (0x00)
[varint] Protocol Version
[varint] Server Address Length
[string] Server Address ← 이게 클라이언트가 입력한 주소
[ushort] Server Port
[varint] Next State (1=status, 2=login)
```
서버 주소 끝에 `\x00` 널 문자가 붙는 경우 있음 → strip 처리 필요
---
## docker-compose.yml 예시
```yaml
version: '3.8'
services:
proxy:
build: ./proxy
ports:
- "25565:25565"
volumes:
- ./data:/data
restart: unless-stopped
network_mode: bridge
api:
build: ./api
expose:
- "8000"
volumes:
- ./data:/data
restart: unless-stopped
frontend:
build: ./frontend
expose:
- "3000"
restart: unless-stopped
nginx:
image: nginx:alpine
ports:
- "8080:80" # 대시보드 접근 포트
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
depends_on:
- api
- frontend
restart: unless-stopped
```
---
## API 엔드포인트
| 메서드 | 경로 | 설명 |
|--------|------|------|
| GET | `/api/config` | 전체 설정 조회 |
| PUT | `/api/config` | 설정 저장 |
| GET | `/api/domains` | 도메인 목록 |
| POST | `/api/domains` | 도메인 추가 |
| DELETE | `/api/domains/{domain}` | 도메인 삭제 |
| PATCH | `/api/domains/{domain}` | 도메인 활성화/비활성화 |
| GET | `/api/logs` | 접속 로그 (페이지네이션) |
| GET | `/api/status` | 프록시 상태, 통계 |
| POST | `/api/proxy/restart` | 프록시 재시작 |
---
## 환경 정보
### Proxmox 서버 스펙 (프록시 실행 환경)
- CPU: Intel Core i3-10100 (4코어 8스레드, 3.6GHz, 최대 4.3GHz)
- RAM: DDR4 32GB (Samsung 16GB × 2, 3200 MT/s, 듀얼채널)
- 가상화: VT-x 지원
### 게임PC (실제 MC 서버)
- 같은 공유기 내 LAN 환경
- 내부 IP로 통신
---
## 주의사항
- 프록시와 FastAPI는 `data/config.json`을 공유 볼륨으로 사용
- 설정 변경 시 프록시 프로세스에 SIGHUP 또는 내부 이벤트로 hot reload
- 게임PC의 MC 서버는 포트 변경 불필요 (프록시가 25565→25565 그대로 중계)
- 대시보드는 Proxmox 내부 IP:8080 으로 접근
- 대시보드 포트(8080)는 외부에 포트포워딩 하지 않을 것 권장