Qemu SSH tunnel

First written onApril 24, 2017
Last updated onDecember 29, 2021

Hello readers,

I was in need to run a virtual machine to do some experiments on archiso (sic) and parabolaiso.

My Intel(R) Core(TM)2 Quad CPU Q8200 @ 2.33GHz PC desktop processor does not support virtualization technology which means that when I run a virtual machine it’s very, very slow (barely usable). So I thought: why not use the home server which has newer hardware and supports virtualization:

$ lscpu | grep Virtualization
Virtualization:        VT-x

Please note that most steps described here have been integrated in the qvm.py script. For this reason you should follow the instructions reported in the documentation

Now, some time ago I’ve written a simple script to handle QEMU easily. VirtualBox is not available on Parabola and I don’t like the available QEMU frontends.

So, after about 1 hour of information retrieval throughout Internet articles I was able to connect all the dots… Here it is.

Premise #

The technique used here is called “SSH tunneling” and enables you to use an SSH server as an intermediary between the client and a remote server. Let’s see a trivial scheme of the VNC setup

            port 22               port 5900
    client <--> server.ssh_interface <--> server.vnc_interface
      | port 5901
    $ vncviewer (:1 is equivalent to :5901)

Terminology #

Note: server.vnc_interface is in a localhost location in respect to the server.ssh_interface, so we will not use the term intermediary server anymore.

Server #

First thing: since my server does not have a GUI I installed the qemu-headless package.

This line does the magic:

-monitor pty -vnc

Make sure to have the following configurations in the OpenSSH configuration (/etc/ssh/sshd_config) otherwise the next steps won’t work

AllowTcpForwarding yes

In case you don’t, you must also restart the SSH daemon.

You can now use the appropriate QVM vnc command.

Client #

Download the QVM script on the client also.

You must now install one of the vnc clients like gtk-vnc or TigerVNC. I’ve noticed that TigerVNC seems to handle window resizes better, so I decided to go for that one.

Before starting the VNC client, an SSH socket (tunnel) is created.

$ ssh -N -f -L 5901: server-user@server.address

TigerVNC is then called on the forwarded port.

$ vncviewer

You should now see the virtual machine.


The next thing was to connect to the SSH daemon on the virtual machine just like what qvm enables you to do. I thought I could use the same method of VNC.

Once the SSH daemon is up and running you can connect to it with the following command from the server:

$ ssh -p 2222 vm-user@

The SSH port of the virual machine is the default one (22). qvm exposes the port 2222 by default so you can connect from localhost with it.

We need another step to be able to connect remotely and directly to the virtual machine from our client:

$ ssh -N -f -L 2223: server-user@server.address


$ ssh -p 2223 vm-user@

You should now see the login.

A simpler way to connect through SSH #

As I later found out, it is possible to connect to SSH, as well as any ohter service, by simply using the host address and the forwarded port, for example:

$ ssh -p 2222 vm-user@server.address

This happens because with this configuration the guest network is bridged with the host network.

Final considerations #

You can use this method also for internet browsing and lots of other stuff. Infact, using SSH implies that the traffic between the client and remote server is encrypted, but using VNC directly by default is NOT so pay attention.