Security Research

Connecting to Proxmox VE OpenVZ containers using VNC

Proxmox VE has an administrative panel that allows connecting to KVM and OpenVZ virtual machines using a Java applet and the VNC protocol (RFB). The issue is that Java is a show-stopper for me, it’s unsafe, bloated and barely runs as a browser plugin. A lot of Proxmox users complain about this part of the implementation, and try to find alternative ways to directly connect to the virtual VGA adapter of their machines.

Seen the amount of VNC implementations that use modern HTML5, WebSockets and Canvas this seems a really poor choice to me. Proxmox’s devs if you are listening please implement this!

While it’s possible to directly “enter” in an OpenVZ container by issuing a “vzctl” command, this would require a shell access on the server node:

vzctl enter 101

There are many reasons that would make you prefer a VNC access to the guest machine, one for all avoid giving access to the host node to a sysadmin or a customer.

For KVM there are solution available (manually editing the KVM configuration of the virtual machine to enable the VNC server) but for OpenVZ I wasn’t able to find a decent solution.

As in Xen a component called “vncterm” is used to connect to OpenVZ, or any other interactive command. Internally it uses X11VNC (http://www.karlrunge.com/x11vnc/x11vnc_opts.html).

The main issue was that the VNC server was offering a security type unsupported to most VNC clients (the infamous “Server did not offer supported security type” error).

$ vncviewer localhost::6900
Connected to RFB server, using protocol version 3.8
Server did not offer supported security type

Luckily vncterm allows passing arguments to x11vnc, by usign a mix of such arguments we can re-enable a standard, password based,  unencrypted VNC server that works with most clients. The command is like the following (please change the “test” password to a stronger one!):

ssh -L 6901:localhost:6901 root@pve-node 'vncterm -nossl -nopw -vencrypt never -passwd test -rfbport 6901 -listen localhost -localhost -timeout 20 -c vzctl enter 101'

It creates an SSH TCP tunnel between the localhost:6901 port on the server to the localhost:6901 port on the client (the sysadmin notebook, for example). Then the admin will be able to connect using a standard vncviewer client:

vncviewer localhost::6901

This will work without the annoying VNC security type error and can be easily tweaked to work from inetd/xinetd or stunnel if you need encryption.

For me it was a complete life saver!

Francesco `ascii` Ongaro
https://linkedin.com/in/ongaro

Standard