I have received a virtual machine for my CS assignment. I have opened it in Gnome Boxes (just by double-clicking on the VM image), but I do not want to write code there, but on my local machine and then compile trough ssh on the virtual machine. The virtual machine has an .ova extension and in Boxes Preferences it says Broker QEMU Session, Display Protocol SPICE. What should I use as remote IP for ssh? Are there any additional configurations of the VM to be made and how should I add them?


2 Answers 2


The simplest way to do that is to use reverse SSH tunneling.

From inside the VM, run:

ssh -NT -R 2222:localhost:22 user@_gateway

where user is a username in the host.

Now, you can connect from the host using

ssh -p 2222 guestuser@localhost

where guestuser is a username is the guest.

If you don't want to run a command from the guest every boot, you can use autossh from a service.


What is available with GNOME Boxes

When you double-click on an Open Virtualization Format file, GNOME Boxes imports it automatically.

GNOME Boxes does not expose guests to SSH into. You are expected to have SPICE guest additions installed on the guest to be able:

  • to copy and paste text with a shared clipboard between the host and the guest and
  • to drag and drop files into the guest.

This approach is supposed to be intuitively comprehensible for unsophisticated users, who GNOME targets with this application:

While virt-manager does a very good job as a virtual machine management software, it's very much tailored for system administration and virtual machines. Boxes, on the other hand, is targeted towards a typical desktop end-user who wants either a very safe and easy way to try out new operating systems or new (potentially unstable) versions of her/his favorite operating system(s), or needs to connect to a remote machine (home-office connection being a typical use-case). For this reason, Boxes does not provide many of the advanced options to tweak virtual machines provided by virt-manager. Instead, Boxes focuses on getting things working out of the box with very little input from user.

That said, Boxes shares a lot of code with virt-manager project, mainly in the form of libvirt, libosinfo and qemu.

For the reference, there is an inactive three-year-old proposal to implement port forwarding in Boxes.

Using different tools

If you need to SSH into your guests, you might want to use the right tool for the task to configure your setup and resort to virt-manager. Typically, it can be done by configuring either a "virtual network" (for hosts with dynamic or wireless interfaces) or a "bridge to LAN" (for hosts with static wired interfaces). On the other hand, Boxes configures guests with user mode networking, which employs a userspace SLiRP stack. You could use virt-manager to modify your existing setup and continue using your guests in Boxes afterwards if you like. I have not done this myself yet, so, if you choose to use virt-manager, you need a different tutorial.

Port forwarding

Another approach is to instruct QEMU to forward a port on the host to the port on the guest. You cannot modify the configuration file of the guest with a text editor because the changes will be disregarded and overwritten. You can modify it with visrh, which is available in libvirt-clients package (at least in Debian). You can learn the name of the domain in the second line of the "Troublshooting Log" available at the "System" tab in the guest "Properties" in Boxes. Alternatively, you can inspect the XML files in ~/.config/libvirt/qemu. For example, in my installation the name of the domain associated with the installed guest machine is "boxes-unknown". To edit the configuration of that machine, I enter:

virsh edit boxes-unknown

The existing configuration of the network for the guest in my installation:

    <interface type='user'>
      <mac address='52:54:00:3d:69:49'/>
      <model type='rtl8139'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>

Unfortunately, you cannot just modify XML to only add port forwarding from the host to the guest. This feature is not implemented in the domain XML format used by libvirt. An email from 2013 shows that there was an unsuccessful proposal for that feature. So, instead, we need to provide the relevant arguments to pass to QEMU on launching the guest. We cannot modify an existing network interface, so we just remove the XML part describing it to prevent it from being created. Instead, we have to replicate it in the arguments, which we want to pass to QEMU.

According to the the "Troubleshooting Log", in my setup the above network configuration corresponds to the following arguments:

-netdev user,id=hostnet0 \
-device rtl8139,netdev=hostnet0,id=net0,mac=52:54:00:3d:69:49,bus=pci.0,addr=0x3 \

You can check the meaning of the arguments in man qemu-system-x86_64.

We don't want to copy the bus and the address because the automatic configuration will not take into account our custom QEMU arguments. This results in occasional collisions in address allocation, which prevents the guest from starting. Instead, we just allow it to be allocated to our custom network interface automatically.

Remember the device name. For example, if I don't specify rtl8139, it seems to configure e1000 instead by default.

You need to modify the <domain type='kvm'> tag to include the XML namespace for the QEMU command line elements:

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>

After that, you can add QEMU commandline arguments at the end right before the closing </domain> tag. In my example below, I add port forwarding to be able to ssh localhost -p 2222 from the host and to be able to access a webserver at http://localhost:8080 from a browser at the host. You probably need to modify this example according to your setup and your preferences. If necessary, the syntax of hostfwd argument can be read in man qemu-system-x86_64.

    <qemu:arg value='-device'/>
    <qemu:arg value='rtl8139,netdev=hostnet0'/>
    <qemu:arg value='-netdev'/>
    <qemu:arg value='user,id=hostnet0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80'/>

The corresponding QEMU arguments are:

-device rtl8139,netdev=hostnet0 \
-netdev user,id=hostnet0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80

It was not difficult to make the above XML from that, but you can also use virsh domxml-from-native qemu-argv to have it made for you.

This seems to be all we need for forwarding ports according to QEMU wiki.

Similar approach can be used with guests in virt-manager too: https://unix.stackexchange.com/a/519067/423679

Don't skip XML validation when saving the file if virsh complains about errors. Try to fix you syntax first. Don't forget to keep backups of configuration files for just in case.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .