Files
HexaHost-Panel/scripts/console-ws-proxy.mjs
2026-05-17 13:26:14 +02:00

50 lines
1.7 KiB
JavaScript

#!/usr/bin/env node
/**
* WebSocket-Proxy: Browser → Panel → Proxmox VNC
* Start: CONSOLE_PROXY_SECRET=... CONSOLE_VALIDATE_URL=https://panel/api/console/validate node scripts/console-ws-proxy.mjs
*/
import http from 'http';
import { WebSocketServer, WebSocket } from 'ws';
const PORT = parseInt(process.env.CONSOLE_PROXY_PORT || '6090', 10);
const SECRET = process.env.CONSOLE_PROXY_SECRET || '';
const VALIDATE = process.env.CONSOLE_PROXY_VALIDATE_URL || 'http://127.0.0.1:8000/api/console/validate';
const server = http.createServer();
const wss = new WebSocketServer({ server, path: '/ws/vm' });
wss.on('connection', async (clientWs, req) => {
const token = req.url?.split('/').pop()?.split('?')[0];
if (!token) {
clientWs.close(4001, 'missing token');
return;
}
try {
const res = await fetch(`${VALIDATE}/${token}`, {
headers: { 'X-Console-Proxy-Secret': SECRET },
});
if (!res.ok) {
clientWs.close(4003, 'invalid session');
return;
}
const data = await res.json();
const proxmoxWs = new WebSocket(data.proxmox_ws_url, ['binary']);
proxmoxWs.on('open', () => {
clientWs.on('message', (msg) => proxmoxWs.readyState === WebSocket.OPEN && proxmoxWs.send(msg));
proxmoxWs.on('message', (msg) => clientWs.readyState === WebSocket.OPEN && clientWs.send(msg));
});
proxmoxWs.on('error', () => clientWs.close(1011, 'upstream error'));
clientWs.on('close', () => proxmoxWs.close());
proxmoxWs.on('close', () => clientWs.close());
} catch {
clientWs.close(1011, 'proxy error');
}
});
server.listen(PORT, '127.0.0.1', () => {
console.log(`Console WS proxy on 127.0.0.1:${PORT}/ws/vm/{token}`);
});