- Added support for multiple Proxmox hosts (pve7.0bin.in:443, Healthport PVE:8006) - Enhanced VM management APIs to accept host parameter - Fixed WebSocket URL generation bug (dynamic port handling) - Added comprehensive SSL certificate trust help system - Implemented host selection dropdown in UI - Added VNC connection failure detection and automatic SSL help redirection - Updated session management to store host_key information - Enhanced error handling for different Proxmox configurations 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
6.8 KiB
6.8 KiB
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 상태 관리 (시작/정지/상태확인)
핵심 구현:
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/<int:vm_id>: VNC 클라이언트 페이지 렌더링- API 엔드포인트들을 통한 VM 관리
로깅 시스템:
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 연결 코드:
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 엔티티 디코딩:
function decodeHtmlEntities(text) {
const textarea = document.createElement('textarea');
textarea.innerHTML = text;
return textarea.value;
}
🔐 보안 및 인증
VNC 인증 플로우
- 티켓 요청: Flask → Proxmox API (
/vncproxy) - 티켓 생성: Proxmox가 일회용 VNC 티켓 및 패스워드 생성
- WebSocket 연결: 브라우저 → Proxmox VNC WebSocket
- VNC 인증: 생성된 패스워드로 VNC 서버 인증
보안 설정
# 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 프록시 요구사항
# WebSocket 업그레이드 헤더
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
⚡ 성능 최적화
Canvas 자동 리사이징
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. 서버 사이드 테스트
cd /srv/headscale-setup/farmq-admin
python test_vnc_websocket.py
2. 로그 확인
tail -f logs/farmq-admin.log
3. 브라우저 개발자 도구
- Network 탭: WebSocket 연결 상태 확인
- Console 탭: JavaScript 에러 확인
📊 모니터링 및 로깅
로그 레벨
- INFO: 정상 동작 로그
- WARNING: 경고사항
- ERROR: 오류 발생
- DEBUG: 상세 디버깅 정보
중요 로그 포인트
- VNC 티켓 생성 성공/실패
- WebSocket 연결 시도
- VNC 인증 결과
- 연결 종료 사유
🔄 배포 및 유지보수
배포 체크리스트
- Proxmox API 연결 테스트
- Flask 애플리케이션 시작 확인
- NPM 프록시 설정 검증
- WebSocket 연결 테스트
- VNC 클라이언트 동작 확인
백업 및 복구
# Git 커밋 상태 확인
git log --oneline -10
# 안정된 버전으로 롤백
git reset --hard 1dc09101cc7afdf09ca3b8cbbc4f95e21bb5746f
📚 참고 자료
🏷️ 버전 정보
- 프로젝트: FarmQ Admin VNC Integration
- 마지막 업데이트: 2024년
- 안정 버전: commit
1dc09101cc7afdf09ca3b8cbbc4f95e21bb5746f - Python: 3.x
- Flask: 최신 안정 버전
- noVNC: 최신 버전