# VNC 웹소켓 구현 기술 문서 ## Proxmox API를 이용한 noVNC 통합 가이드 ### 📋 개요 이 문서는 Proxmox VE API를 활용하여 웹 브라우저에서 직접 가상머신에 VNC 접속할 수 있는 시스템의 기술적 구현 내용을 설명합니다. Flask 백엔드와 noVNC 클라이언트를 통해 브라우저에서 직접 VM 콘솔에 접근할 수 있도록 구현되었습니다. ### 🏗️ 시스템 아키텍처 ``` [웹 브라우저] ↓ HTTPS [NPM 리버스 프록시] ↓ HTTP [Flask 애플리케이션] ↓ HTTPS API [Proxmox VE 서버] ↓ WebSocket (WSS) [VM VNC 서버] ``` ### 🔧 핵심 구성요소 #### 1. Proxmox API 클라이언트 (`utils/proxmox_client.py`) **주요 기능:** - Proxmox VE API 인증 및 세션 관리 - VNC 티켓 생성 및 WebSocket URL 생성 - VM 상태 관리 (시작/정지/상태확인) **핵심 구현:** ```python def get_vnc_ticket(self, node: str, vmid: int) -> Optional[Dict]: """VNC 접속 티켓 생성""" data = { 'websocket': '1', 'generate-password': '1' # 자동 패스워드 생성 } response = self.session.post( f"{self.base_url}/nodes/{node}/qemu/{vmid}/vncproxy", data=data, timeout=10 ) if response.status_code == 200: vnc_data = response.json()['data'] encoded_ticket = quote_plus(vnc_data['ticket']) vnc_data['websocket_url'] = f"wss://{self.host}:443/api2/json/nodes/{node}/qemu/{vmid}/vncwebsocket?port={vnc_data['port']}&vncticket={encoded_ticket}" return vnc_data ``` **인증 방식:** - 세션 쿠키 방식 (PVEAuthCookie) - CSRF 토큰 헤더 (CSRFPreventionToken) - API 토큰 방식 지원 #### 2. Flask 웹 애플리케이션 (`app.py`) **주요 엔드포인트:** - `/vnc/`: VNC 클라이언트 페이지 렌더링 - API 엔드포인트들을 통한 VM 관리 **로깅 시스템:** ```python def setup_logging(): if not os.path.exists('logs'): os.makedirs('logs') file_handler = RotatingFileHandler( 'logs/farmq-admin.log', maxBytes=10*1024*1024, backupCount=5 ) ``` #### 3. noVNC 클라이언트 (`templates/vnc_simple.html`) **핵심 기능:** - WebSocket을 통한 VNC 프로토콜 처리 - 자동 리사이징 및 스케일링 - HTML 엔티티 디코딩 (패스워드 처리) **WebSocket 연결 코드:** ```javascript function connectVNC() { const rfb = new RFB(document.getElementById('screen'), websocketUrl, { credentials: { password: decodeHtmlEntities('{{ vnc_data.password }}') } }); rfb.addEventListener("connect", () => { console.log("VNC 연결 성공"); resizeScreen(); }); rfb.addEventListener("disconnect", (e) => { console.log(`VNC 연결 종료: ${e.detail.clean ? '정상' : '비정상'}`); }); } ``` **HTML 엔티티 디코딩:** ```javascript function decodeHtmlEntities(text) { const textarea = document.createElement('textarea'); textarea.innerHTML = text; return textarea.value; } ``` ### 🔐 보안 및 인증 #### VNC 인증 플로우 1. **티켓 요청**: Flask → Proxmox API (`/vncproxy`) 2. **티켓 생성**: Proxmox가 일회용 VNC 티켓 및 패스워드 생성 3. **WebSocket 연결**: 브라우저 → Proxmox VNC WebSocket 4. **VNC 인증**: 생성된 패스워드로 VNC 서버 인증 #### 보안 설정 ```python # SSL 검증 무시 (내부 네트워크) urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) self.session.verify = False # WebSocket URL에 티켓 인코딩 encoded_ticket = quote_plus(vnc_data['ticket']) ``` ### 🌐 네트워크 구성 #### NPM (Nginx Proxy Manager) 설정 - **외부 도메인**: `https://pve7.0bin.in` - **내부 주소**: `https://192.168.0.5:8006` - **WebSocket 지원**: Upgrade 헤더 프록시 필요 #### WebSocket 프록시 요구사항 ```nginx # WebSocket 업그레이드 헤더 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; ``` ### ⚡ 성능 최적화 #### Canvas 자동 리사이징 ```javascript function resizeScreen() { const canvas = document.querySelector('#screen canvas'); if (canvas) { const container = document.getElementById('screen'); const scaleX = container.clientWidth / canvas.width; const scaleY = container.clientHeight / canvas.height; const scale = Math.min(scaleX, scaleY, 1); canvas.style.transform = `scale(${scale})`; canvas.style.transformOrigin = 'top left'; } } ``` #### 연결 상태 관리 - 자동 재연결 로직 - 연결 품질 모니터링 - 에러 처리 및 사용자 피드백 ### 🐛 문제 해결 가이드 #### 일반적인 문제들 **1. WebSocket 1006 에러 (비정상 연결 종료)** - **원인**: NPM 프록시 WebSocket 설정 부족 - **해결**: WebSocket 업그레이드 헤더 설정 확인 **2. VNC 인증 실패 (HTTP 401)** - **원인**: 잘못된 티켓 또는 패스워드 - **해결**: `generate-password: 1` 설정 확인 **3. 빈 화면 또는 검은 화면** - **원인**: Canvas 리사이징 문제 - **해결**: `resizeScreen()` 함수 호출 확인 **4. HTML 엔티티 문제** - **원인**: 패스워드의 특수문자 인코딩 - **해결**: `decodeHtmlEntities()` 함수 적용 #### 디버깅 도구 **1. 서버 사이드 테스트** ```bash cd /srv/headscale-setup/farmq-admin python test_vnc_websocket.py ``` **2. 로그 확인** ```bash tail -f logs/farmq-admin.log ``` **3. 브라우저 개발자 도구** - Network 탭: WebSocket 연결 상태 확인 - Console 탭: JavaScript 에러 확인 ### 📊 모니터링 및 로깅 #### 로그 레벨 - **INFO**: 정상 동작 로그 - **WARNING**: 경고사항 - **ERROR**: 오류 발생 - **DEBUG**: 상세 디버깅 정보 #### 중요 로그 포인트 - VNC 티켓 생성 성공/실패 - WebSocket 연결 시도 - VNC 인증 결과 - 연결 종료 사유 ### 🔄 배포 및 유지보수 #### 배포 체크리스트 - [ ] Proxmox API 연결 테스트 - [ ] Flask 애플리케이션 시작 확인 - [ ] NPM 프록시 설정 검증 - [ ] WebSocket 연결 테스트 - [ ] VNC 클라이언트 동작 확인 #### 백업 및 복구 ```bash # Git 커밋 상태 확인 git log --oneline -10 # 안정된 버전으로 롤백 git reset --hard 1dc09101cc7afdf09ca3b8cbbc4f95e21bb5746f ``` ### 📚 참고 자료 - [Proxmox VE API 문서](https://pve.proxmox.com/pve-docs/api-viewer/) - [noVNC 프로젝트](https://github.com/novnc/noVNC) - [WebSocket RFC 6455](https://tools.ietf.org/html/rfc6455) - [VNC 프로토콜 스펙](https://tools.ietf.org/html/rfc6143) ### 🏷️ 버전 정보 - **프로젝트**: FarmQ Admin VNC Integration - **마지막 업데이트**: 2024년 - **안정 버전**: commit `1dc09101cc7afdf09ca3b8cbbc4f95e21bb5746f` - **Python**: 3.x - **Flask**: 최신 안정 버전 - **noVNC**: 최신 버전