headscale-tailscale-replace.../farmq-admin/VNC_WebSocket_Connection_Issue_Resolution.md
시골약사 fb00b0a5fd Add multi-host Proxmox support with SSL certificate handling
- 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>
2025-09-13 00:03:25 +09:00

6.7 KiB

VNC WebSocket 연결 문제 해결 문서

Proxmox VE API 기반 VNC 접속 문제 진단 및 해결

🚨 발생한 문제

증상:

  • 브라우저에서 VNC 접속 시 WebSocket 1006 에러 (비정상 연결 종료)
  • Proxmox 로그에 TASK ERROR: connection timed out 발생
  • noVNC 클라이언트에서 검은 화면만 표시
  • HTTP 401 Unauthorized 에러 발생

영향:

  • 웹 브라우저를 통한 VM 콘솔 접속 불가능
  • 사용자가 VM에 직접 접근할 수 없는 상황

🔍 문제 진단 과정

1단계: 초기 상황 파악

# VM 상태 확인
VM 102 상태: running
VM 실행시간: 1463275초 (정상 실행 중)
VM PID: 3482
VNC 포트: N/A ← 문제 발견

2단계: VM 설정 상세 조회

# Proxmox API로 VM 설정 확인
GET /api2/json/nodes/pve7/qemu/102/config

결과:
args: -vnc 0.0.0.0:77  ← 문제의 근본 원인 발견

💡 핵심 발견: VM에 커스텀 VNC 설정 -vnc 0.0.0.0:77이 설정되어 있어서:

  • VM은 포트 5977 (5900 + 77)에서 VNC 서비스 제공
  • Proxmox VNC 프록시는 표준 포트 5900 기대
  • 포트 불일치로 인한 연결 실패

🛠️ 해결 과정

1단계: VM 설정 수정 (실제 Proxmox 서버 설정 변경)

# Python 코드로 실제 Proxmox VM 설정 수정
PUT /api2/json/nodes/pve7/qemu/102/config
data = {'args': ''}  # VNC 커스텀 설정 제거

결과:  VNC args 제거 성공

⚠️ 중요: 이는 Python 설정이 아닌 실제 Proxmox 서버의 VM 102 설정을 API를 통해 수정한 것입니다.

2단계: VM 재시작 (설정 적용)

# VM 정지
POST /api2/json/nodes/pve7/qemu/102/status/stop
결과: VM 상태가 'stopped' 변경 확인

# VM 시작  
POST /api2/json/nodes/pve7/qemu/102/status/start
결과: VM 상태가 'running'으로 변경 확인

3단계: VNC 프록시 연결 테스트

# VNC 티켓 생성
POST /api2/json/nodes/pve7/qemu/102/vncproxy
data = {
    'websocket': '1',
    'generate-password': '1'
}

결과:
 포트: 5900 (표준 포트로 정상화)
 패스워드: 자동 생성됨
 WebSocket URL: 정상 생성

4단계: 인증 문제 해결

문제: WebSocket 연결 시 HTTP 401 Unauthorized

근본 원인: Proxmox VNC WebSocket은 인증이 필요하지만 브라우저와 달리 수동으로 인증 헤더를 전달해야 함

해결: PVE 인증 쿠키를 WebSocket 헤더에 추가

# 기존 (실패) - 인증 정보 없음
async with websockets.connect(websocket_url, ssl=ssl_context)
# 결과: HTTP 401 Unauthorized

# 수정 (성공) - PVE 인증 쿠키 추가
headers = {'Cookie': f'PVEAuthCookie={client.ticket}'}
async with websockets.connect(
    websocket_url, 
    ssl=ssl_context, 
    additional_headers=headers  # 핵심: 인증 헤더 추가
)
# 결과: ✅ WebSocket 연결 성공

🔑 핵심 포인트:

  • client.ticket은 Proxmox 로그인 시 받은 인증 티켓
  • VNC 티켓(vncticket)과는 별개의 세션 인증 쿠키
  • 브라우저는 자동으로 쿠키를 전송하지만, Python WebSocket은 수동으로 헤더에 추가해야 함

해결 결과

최종 테스트 성공:

🎉 VNC WebSocket 연결 및 프로토콜 핸드셰이크 성공!
- WebSocket 연결: ✅ 성공
- VNC 프로토콜 버전: RFB 003.008
- 클라이언트 응답: ✅ 완료

📋 변경된 설정 요약

구분 변경 전 변경 후
VM args 설정 -vnc 0.0.0.0:77 '' (빈 값)
VNC 포트 5977 (5900+77) 5900 (표준)
Proxmox 프록시 포트 불일치 오류 정상 연결
WebSocket 인증 인증 헤더 누락 PVE 쿠키 추가

🔧 적용된 수정 사항

1. Proxmox 서버 VM 설정 (실제 서버 변경)

# 변경 전
VM 102 설정: args = "-vnc 0.0.0.0:77"

# 변경 후  
VM 102 설정: args = ""

2. WebSocket 테스트 코드 (test_vnc_websocket.py)

# 추가된 인증 헤더
headers = {'Cookie': f'PVEAuthCookie={client.ticket}'}
async with websockets.connect(
    websocket_url,
    ssl=ssl_context,
    additional_headers=headers
)

🚀 브라우저 클라이언트 적용 방안

이제 서버 사이드 연결이 성공했으므로, 브라우저의 noVNC 클라이언트도 같은 방식으로 수정 가능:

💡 핵심 인사이트: Claude Code 환경에서 성공한 이유는 PVE 인증 쿠키를 WebSocket 헤더에 명시적으로 추가했기 때문

브라우저에서 해결해야 할 사항:

  1. WebSocket 연결 시 PVE 인증 정보 전달

    // 현재 브라우저 코드 (인증 정보 없음)
    rfb = new RFB(document.getElementById('screen'), websocketUrl, 
                  { credentials: { password: vncPassword } });
    
    // 필요한 수정: PVE 세션 쿠키 또는 인증 헤더 추가 방법 구현
    
  2. NPM 리버스 프록시 WebSocket 업그레이드 헤더 설정

    • WebSocket 연결을 위한 Upgrade 헤더 전달
    • Cookie 헤더의 올바른 프록시 설정
  3. 브라우저 보안 정책 (CORS, Mixed Content) 검토

    • HTTPS → WSS 프로토콜 일관성
    • Same-Origin Policy 또는 적절한 CORS 설정

🎯 가장 중요한 발견: 서버 환경에서는 additional_headers={'Cookie': f'PVEAuthCookie={client.ticket}'}로 해결되었으므로, 브라우저에서도 동일한 인증 정보 전달 방식이 필요합니다.

📊 문제 해결 체크리스트

  • VM 커스텀 VNC 설정 제거
  • VM 재시작으로 설정 적용
  • VNC 티켓 생성 확인 (포트 5900)
  • WebSocket 인증 헤더 추가
  • VNC 프로토콜 핸드셰이크 성공
  • 서버 환경에서 완전한 연결 확인
  • 브라우저 클라이언트 적용 (향후 작업)
  • NPM 프록시 WebSocket 설정 개선 (향후 작업)

🎯 핵심 교훈

  1. VM 설정 충돌 주의: 커스텀 VNC 설정이 Proxmox 표준 프록시와 충돌할 수 있음
  2. 포트 일관성 중요: VM VNC 포트와 프록시 기대 포트가 일치해야 함
  3. 인증 정보 전달: WebSocket 연결 시 적절한 인증 헤더 필수
  4. API 기반 설정 변경: Proxmox API로 실시간 VM 설정 수정 가능

📅 해결 완료 시점

  • 문제 발견: Proxmox 로그 타임아웃 에러
  • 원인 분석: VM 커스텀 VNC 설정 충돌
  • 해결 완료: 2024년 (Claude Code 환경에서 완전한 VNC WebSocket 연결 성공)
  • 테스트 결과: VNC 프로토콜 핸드셰이크까지 완료

💡 참고: 이 문서는 실제 Proxmox 서버의 VM 설정을 변경한 내용을 기록한 것입니다. Python 코드는 Proxmox API 호출을 위한 클라이언트 역할만 수행했으며, 실제 변경은 Proxmox 서버에서 발생했습니다.