JetKVM이 Cloudflare Tunnel 너머에서 USB가 disconnected — WebRTC가 막힌다
Web UI는 잘 뜨는데 키보드/마우스 입력이 안 먹는다. 자료가 거의 없는 구체적 함정을 직접 부딪혀 정리.
목차
JetKVM은 라즈베리파이 크기의 KVM-over-IP다. 서버에 USB+HDMI 꽂아두면 어디서든 브라우저로 BIOS까지 진입 가능. GPU 패스스루 셋업 막혔을 때 산 게 이거.
문제는 외부 노출 방식. 공유기 포트 안 열고 Cloudflare Tunnel로 노출하려 했는데 — Web UI는 뜨는데 키보드/마우스/USB가 안 먹는다.
검색해도 자료 거의 없어서 직접 정리.
증상
1. 로컬 IP로 직접 접속 (192.168.x.x:80) → 모든 기능 정상
2. Cloudflare Tunnel로 접속 (kvm.lab-it.net) → Web UI 뜨고 화면 보이지만:
- 키보드 입력이 게스트 OS에 안 들어감
- 마우스 클릭이 안 됨
- USB 가상 디스크가 "disconnected" 상태
- 그러나 화면은 정상적으로 흐름
원인 — WebRTC가 막힘
JetKVM Web UI 자체는 HTTP 위에서 동작 (정적 파일 + WebSocket 컨트롤). 화면은 MJPEG/H264 스트림으로 HTTP 또는 WebSocket으로 옴.
키보드/마우스/USB는 WebRTC 데이터 채널 로 처리한다. 저지연이 필수라 WebSocket보다 WebRTC를 쓰는 듯.
WebRTC는 UDP 기반. ICE/STUN/TURN으로 NAT 뚫고 P2P 연결.
Cloudflare Tunnel은 TCP 기반 reverse proxy다. UDP는 프록시 못 한다.
따라서:
- HTTP/WebSocket(TCP) → Cloudflare Tunnel 통과 ✓
- WebRTC(UDP) → 차단 ✗
화면은 뜨지만 입력 못 함의 정확한 원인.
시도했지만 안 된 것들
1) Cloudflare WebSockets 토글
대시보드 Network → WebSockets ON. WebSocket은 어차피 동작하던 거라 효과 없음.
2) --protocol http2 옵션
cloudflared 시작 옵션에 HTTP/2 강제. WebRTC와 무관.
3) Cloudflare Spectrum
Spectrum은 임의 TCP/UDP 노출 가능하지만 유료 (Enterprise). 학생 인프라엔 부담.
4) UDP 프록시 별도 설정
cloudflared에 UDP 라우팅 추가 시도. WireGuard용 udp 라우팅은 제공되지만 일반 WebRTC용 동적 포트엔 안 맞음.
실제로 작동한 해결책
WebRTC를 우회 — JetKVM이 WebRTC fallback으로 WebSocket을 쓸 수 있는지 확인.
JetKVM 문서엔 명시 없고, 펌웨어 코드를 보니 ?fallback=ws 같은 쿼리 파라미터도 없었다. 사실상 WebRTC가 강제.
최종 결론: Cloudflare Tunnel로 JetKVM 풀기능 노출은 불가능. UDP 프록시 가능한 다른 방법이 필요.
대안:
- Tailscale — WireGuard 기반 메시 VPN, UDP 통과. Tailscale 무료 플랜으로 vm0 + Mac 연결 → JetKVM 로컬 IP로 접근. 이게 정답.
- Cloudflare Tunnel + WARP — 일부 시나리오에서 WARP 클라이언트로 WebRTC 가능할 수 있다는 글이 있음. 미확인.
- 공유기 UDP 포트 포워딩 — 가능하지만 그게 싫어서 Tunnel 쓴 건데 본말 전도.
Tailscale 셋업
Tailscale을 vm0과 Mac에 깔면 둘이 직접 P2P (UDP NAT-traversal 자동).
# vm0 (Proxmox 호스트)
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up
# Mac
brew install tailscale
tailscale up
이제 vm0의 Tailscale IP(100.x.x.x)로 어디서든 접근. JetKVM이 vm0 내부 LAN에 있으면 Tailscale → vm0 → JetKVM 라우팅 가능 (tailscale up --advertise-routes=192.168.0.0/24).
검색해도 안 나온 이유
이 문제 원인이 정확히 잡혀야:
- “JetKVM Cloudflare Tunnel” — 자료 없음 (제품 자체가 신생)
- “WebRTC behind reverse proxy not working” — 너무 일반적
- “cloudflared WebRTC support” — Cloudflare 측 명시적 답변 부재
키워드를 정확히 합쳐도 글이 거의 없다. 누군가 같은 함정에 빠지면 이 글이 검색되길.
같은 패턴으로 막히는 다른 도구
WebRTC를 쓰는 KVM-over-IP/원격 도구는 거의 같은 함정.
| 도구 | WebRTC 사용 | Cloudflare Tunnel 통과? |
|---|---|---|
| JetKVM | ✓ | ✗ |
| TinyPilot | ✗ (MJPEG/HID over USB) | ✓ |
| PiKVM | △ (모드에 따라) | △ |
| MeshCentral | ✓ | ✗ |
| RustDesk | ✓ | ✗ |
| Apache Guacamole | ✗ (HTML5 over WebSocket) | ✓ |
WebRTC 안 쓰는 TinyPilot이나 Guacamole은 Tunnel과 잘 맞는다. 도구 고를 때 미리 확인.
만들면서 알게 된 것들
Cloudflare Tunnel은 TCP만이다. 무료 + 강력해서 만능처럼 보이지만 UDP는 못 한다. WebRTC, WireGuard, 게임 서버 등 UDP 의존 서비스엔 부적합.
Tailscale은 UDP의 답. WireGuard 기반이라 UDP 직접 프록시. Cloudflare Tunnel과 보완 관계: Tunnel은 공개 노출, Tailscale은 비공개 메시.
“화면 보이는데 입력 안 됨”은 UDP 막힌 거의 결정적 시그널. 영상 스트림은 TCP로 종종 fallback 가능, 입력은 저지연이 필수라 UDP 강제. 이 비대칭이 진단 단서.
처음에 글을 시작할 때 “Cloudflare Tunnel로 다 됨”이라 자신했는데, 한 번 더 경계의 비용을 배웠다. 모든 도구는 자기 가정이 있고, 그 가정 밖에선 안 통한다.