# MC Domain Filter Proxy 마인크래프트 서버 앞단에 두는 **도메인 화이트리스트 프록시 + 웹 관리 대시보드**. 클라이언트가 마인크래프트 서버 주소창에 입력한 도메인이 허용 목록과 일치할 때만 백엔드 MC 서버로 연결을 통과시킵니다. 외부에서 공유기의 공인 IP를 직접 입력해서 접속하는 경로를 차단할 수 있습니다. ## 기능 - 마인크래프트 핸드셰이크 패킷에서 클라이언트가 입력한 server address 파싱 - 허용 도메인 화이트리스트 매칭, 불일치 시 즉시 연결 종료 - 통과한 연결은 백엔드 MC 서버로 투명 TCP 중계 (Fabric / Paper / Spigot / NeoForge 등 서버 종류 무관) - 설정 파일(`data/config.json`) 변경을 프록시가 자동 감지해 hot reload (재시작 불필요) - 모든 연결 시도(허용 / 차단 / 에러)를 SQLite 에 기록 - 웹 대시보드 (NPM 스타일): 도메인 관리, 실시간 로그, 통계 카드, 백엔드/포트 설정 ## 네트워크 구조 ``` 외부 인터넷 ↓ 공유기 (포트포워딩 25565 → Proxmox) ↓ mc-filter-proxy 컨테이너 (25565) ↓ 게임PC 내부IP:25565 (실제 마인크래프트 서버) ``` ## 빠른 시작 1. 저장소 클론 ```bash git clone https://git.tkrmagid.kr/tkrmagid/mc_domain_proxy.git cd mc_domain_proxy ``` 2. (선택) 초기 설정 파일을 미리 생성. 생략하면 프록시 첫 기동 시 기본값으로 자동 생성됩니다. ```bash mkdir -p data cat > data/config.json <<'EOF' { "proxy": { "listen_port": 25565, "enabled": true }, "backend": { "host": "192.168.0.20", "port": 25565 }, "allowed_domains": [ { "domain": "mc.tkrmagid.kr", "enabled": true, "note": "메인 도메인" } ] } EOF ``` 3. 전체 스택 빌드 & 실행 ```bash docker compose up -d --build ``` 4. 접속 - **마인크래프트 클라이언트**: `mc.tkrmagid.kr` (또는 등록한 도메인) - **대시보드**: `http://:8080` ## 구성 요소 | 서비스 | 포트 | 설명 | |-------------|-----------------|----------------------------------------| | `proxy` | 25565 (외부) | asyncio TCP 프록시, 핸드셰이크 파싱 | | `api` | 8000 (내부) | FastAPI, 설정/로그/통계 REST API | | `frontend` | 3000 (내부) | React + Vite SPA | | `nginx` | 8080 (외부) | 대시보드 리버스 프록시 | `data/` 디렉터리는 모든 서비스가 공유 볼륨으로 마운트해 `config.json`, `logs.db` 를 공용합니다. ## API | 메서드 | 경로 | 설명 | |--------|---------------------------------|----------------------------------------| | GET | `/api/config` | 전체 설정 조회 | | PUT | `/api/config` | 전체 설정 저장 | | GET | `/api/domains` | 허용 도메인 목록 | | POST | `/api/domains` | 도메인 추가 | | PATCH | `/api/domains/{domain}` | 활성/메모 변경 | | DELETE | `/api/domains/{domain}` | 도메인 삭제 | | GET | `/api/logs?limit&offset&action` | 접속 로그 (페이지네이션) | | GET | `/api/status` | 프록시 상태 + 통계 | | POST | `/api/proxy/restart` | config 파일 touch (프록시 재로드 트리거) | ## Hot reload 동작 - API 가 `data/config.json` 을 atomic rename (`tempfile + os.replace`) 으로 갱신 - 프록시가 2초 간격으로 mtime 폴링, 변경 감지 시 메모리 캐시 재로드 - `listen_port` 나 `proxy.enabled` 가 바뀌면 리스너 자체를 재시작, 그 외(도메인/백엔드)는 다음 연결부터 즉시 적용 ## 보안 권장 - **대시보드 포트(8080)는 외부 포트포워딩 금지.** Proxmox 내부망 / VPN / SSH 터널을 통해서만 접근하세요. - API 에는 인증이 없으므로 외부에 노출해야 하는 경우 nginx 앞단에 basic auth 또는 OAuth proxy 를 추가하세요. - 프록시 컨테이너는 핸드셰이크 단계에서만 패킷을 검사하고, 그 외에는 단순 TCP 중계라서 MC 프로토콜 변경에 영향을 받지 않습니다. ## 디렉터리 구조 ``` . ├── proxy/ # asyncio TCP 프록시 │ ├── main.py │ ├── handshake.py │ ├── config.py │ ├── requirements.txt │ └── Dockerfile ├── api/ # FastAPI 백엔드 │ ├── main.py │ ├── config_io.py │ ├── routes/ │ │ ├── config.py │ │ ├── domains.py │ │ ├── logs.py │ │ └── status.py │ ├── requirements.txt │ └── Dockerfile ├── frontend/ # React + Vite 대시보드 │ ├── src/ │ │ ├── pages/ │ │ │ ├── Dashboard.jsx │ │ │ ├── Domains.jsx │ │ │ ├── Logs.jsx │ │ │ └── Settings.jsx │ │ ├── App.jsx │ │ ├── api.js │ │ ├── main.jsx │ │ └── styles.css │ ├── index.html │ ├── vite.config.js │ ├── package.json │ └── Dockerfile ├── nginx/ │ └── nginx.conf ├── data/ # 런타임 데이터 (git 무시; config.json, logs.db) └── docker-compose.yml ``` ## 로컬 개발 (Docker 없이) 각 서비스는 독립적으로 실행 가능합니다. ```bash # proxy cd proxy MC_CONFIG_PATH=$(pwd)/../data/config.json \ MC_LOG_DB=$(pwd)/../data/logs.db \ python main.py # api (다른 터미널) cd api pip install -r requirements.txt MC_CONFIG_PATH=$(pwd)/../data/config.json \ MC_LOG_DB=$(pwd)/../data/logs.db \ uvicorn main:app --reload --port 8000 # frontend (또 다른 터미널) cd frontend npm install npm run dev # http://localhost:3000, /api 는 8000 으로 자동 프록시 ``` ## 환경 변수 | 변수 | 기본값 | 적용 서비스 | |-------------------|--------------------|-------------------| | `MC_CONFIG_PATH` | `/data/config.json`| proxy, api | | `MC_LOG_DB` | `/data/logs.db` | proxy, api | ## 라이선스 내부 사용 (TkrMagid).