Proxmox VE vncproxy noVNC 配置备忘录

PVE直接封装了WebSocket, 需要调用 VNC 和 xterm的几种方案:

1. 给虚拟机配置单独的 vnc监听端口和 ip并设置密码直接连接, 或者拿websockify转WebSocket

2.重新封装转发/api2/json/nodes/{node}/qemu/{vmid}/vncwebsocket  

3.直接访问 PVE 原生接口方式。(1.直接访问 2.nginx单独封装反向代理xtermjs和novnc|)

 

前期准备

GET /api2/json/access/ticket
POST /api2/json/nodes/{node}/qemu/{vmid}/vncproxy
wss /api2/json/nodes/{node}/qemu/{vmid}/vncwebsocket

 vncproxy 和 ticket 需要一起创建,noVNC连接vncwebsocket 需要 PVEAuthCookie才能正常通信否则无法连接。

注意:请求/api2/json/access/ticket必须要用户密码获取,用root token无法创建。
PVE 的设计思路是将 VM 分配给用户,但是没给token设计获取 ticket 应该是考虑权限分离。

 

偷懒思路解决方案,直接nginx代理 PVE 的 noVNC和xterm(又不想开放 PVE 访问)

map $arg_node  $proxyhost  {
   "PVE NODE NAME-1"  "PVE IP";
   "PVE NODE NAME-1"  "PVE IP";
   "PVE NODE NAME-1"  "PVE IP";
}

location ~/(xtermjs|novnc|api2) {
     if ( $arg_console ) { set $new_uri /?$query_string;  }
        proxy_pass https://$proxyhost:8006$new_uri;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
}

如果有安装 redis 插件, 可以从 redis 存取主机 IP, 另外还有一个版本由于安全问题暂不公开。 

和代理websocket方法一样也是需要保证wss通信的时候要带上PVEAuthCookie的 cookies

 

下面的方法是实现websocket代理的重新整合 novnc 的初始方案;

nginx 配置

location /websocket/ {
#        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    proxy_read_timeout 360;
    proxy_connect_timeout 60;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_cache_bypass $http_upgrade;
    proxy_set_header Cookie "PVEAuthCookie=$arg_pveticket";
    proxy_ssl_verify off;
    proxy_set_header Host $arg_host: $arg_port1;
    proxy_pass https://$arg_host:$arg_port1/api2/json/nodes/$arg_node/$arg_type/$arg_vmid/vncwebsocket?port=$arg_vncport&vncticket=$arg_vncticket;
}

url传入数据websocket/?host=XXXX&port1=8006&node=xxx&type=qemu&vmid=xxxx&vncport=xxxx&vncticket= xxxx&pveticket

另外一种方式可以直接用 cookie 方式传入,在程序内直接对客户端写入 cookie

把nginx 从GET的$arg_ 参数换成 $cookie_获取。

noVNC vnc.html问题

使用原版本noVNC/app/ui.js中需要在 RFB 传入变量的时候需要对 url 进行解码,否则使用url传入参数会对?进行转义。

           UI.rfb = new RFB(document.getElementById('noVNC_container'),
                              url.href.replace(/%3F/g, '?'), 

配置 vnc.html

<?php     setcookie("PVEAuthCookie", urlencode($pveticket), time() + 3600, "/");    ?>
let defaults = {
   // "port": 8006,   //非 web 标准端口再启用
    "host": "<?php echo $configure['hostname']; ?>",
 "path": "websocket/?host=<?php echo $configure['hostname']; ?>&port1=8006&node=<?php echo $node; ?>&type=qemu&vmid=<?php echo $vmid; ?>&vncport=<?php echo $port;?>&vncticket=<?php echo $ticket; ?>",
  "resize": true,
  "view_only": false,
  "password": "<?php echo $ticket; ?>",

  "reconnect": true,
  "autoconnect":true
};

添加新评论 »