1. Overview

QEMU enables us to run various guest operating systems within our host environment. But how do we effectively interact with the virtual machines and host? Luckily, the Secure Shell (SSH) protocol is helpful here. OpenSSH helps us in setting the communication path between the two.

In this tutorial, we’ll see how to establish SSH connectivity from our host machine to a guest OS running under QEMU.

2. Prerequisites

Before getting started, some prerequisites must be met:

  • the host has QEMU/KVM installed and configured
  • the guest VM image is created in qcow2 format
  • the guest OS has an OpenSSH server installed and enabled
  • user accounts exist on both the host and guest

Specifically, we’re using a qcow2 format Parrot OS for our guest machine. We’ve chosen the qcow2 format due to its support for advanced features. For instance, these features include snapshotting, copy-on-write, and compression.

Other possible options, for example, raw and vmdk, are less suitable for QEMU setups. For example, raw images lack compression and snapshotting capabilities. While vmdk (VMware Disk Format) doesn’t support incremental data processing. Moreover, it has limited interoperability and feature availability in QEMU environment.

Also, Ubuntu 22.04 is our host machine.

3. Using QEMU Command-Line Options

QEMU comes with a basic bridge network configuration out of the box. This enables the VM to be connected to any other computer on the local network. However, we can also create a new one.

Let’s see how to configure a QEMU bridge network on our host machine.

3.1. Creating a Bridge Interface

To create a bridge network, first, we create a bridge interface using the brctl command.

Let’s name this bridge br0:

$ sudo brctl addbr br0

Next, we attach our host’s network interface (e.g., enp0s3) to the bridge:

$ sudo brctl addif br0 enp0s3

This step effectively bridges the host’s network connection with the virtual machines.

Then, we bring up the bridge interface:

$ sudo ip link set up dev br0

Finally, we add the bridge interface, br0, to the network:

$ sudo ip addr add dev br0

This new network coincides with the host network. Thus, both the guest and host machine can use the same network.

3.2. ACL Configuration

To use the new bridge interface, we need to set the minimum permissions to the /etc/qemu/bridge.conf file on the host machine.

Let’s create the file and add a basic rule enabling connections to the bridge br0:

$ cat /etc/qemu/bridge.conf
allow br0

Moving on, we set the required permission:

$ sudo chmod 644 /etc/qemu/bridge.conf

Specifically, we can also allow all bridges if we want to.

3.3. Launching the VM

We’re now ready to launch the VM with the qemu-system-x86_64 command:

$ sudo qemu-system-x86_64 \
  -drive file=/var/lib/libvirt/images/Parrot.qcow2,format=qcow2 \
  -m 4G \
  -smp 2 \
  -enable-kvm \
  -netdev bridge,id=mynet0,br=br0 \
  -device virtio-net,netdev=mynet0

Let’s break down the above options:

  • -drive file=/var/lib/libvirt/images/Parrot.qcow2,format=qcow2: the path to our VM image
  • -m 4G: the RAM size for the VM
  • -smp 2: sets the number of virtual CPU cores
  • -netdev bridge,id=mynet0,br=br0: configures a network device using the br0 bridge.
  • -device virtio-net,netdev=mynet0: associates the VM with the mynet0 network device using the virtio-net model
  • -enable-kvm: enable KVM hardware virtualization

Consequently, this launches a KVM virtual machine with 4GB RAM, 2 CPUs, bridged networking, and Parrot OS.

3.4. Testing the SSH Connectivity

Let’s check the VM’s IP once it has fully booted:

$ip a
    inet brd ...

Next, we connect through SSH:

$ ssh [email protected] 
The authenticity of host '

Thus, the SSH connection is successful.

Alternatively, QEMU can be used directly from the graphical interface. This provides more flexibility than the command line option.

4. Using virt-manager

The virt-manager GUI provides an easy way to create and manage KVM VMs. We’ll launch a VM through it and connect with OpenSSH.

4.1. Setting up VM and Configuring Networking

First, we’ll use the same bridge network interface, br0, which we used earlier with the QEMU command.

Further, we open the virtual machine manager from the Application menu:

Creating New VMNext, we select the Import existing disk image option:

Importing Disk Image
Then, we choose the storage path for the disk image of Parrot OS:

Selecting Disk Image

Also, we select the OS type as Ubuntu 22.04 from the bottom search box:

Selecting OS Type

Further, we select the Memory and CPU for the VM:

Selecting Memory and CPU

Finally, we select Bridge device under the Network selection option. Then, we enter br0 for Device name and click Finish:

Final Setup and Network Config

The br0 interface is the same one we used earlier with the QEMU command line option.

4.2. Launching the VM

Finally, the virtual machine starts and we can log in to it.

Let’s check the assigned IP address to the machine using the ip command:

$ip a
    inet brd ...

We can now use this IP to connect to the VM from the host over SSH.

4.3. Testing SSH Connectivity

We now head to the host machine to start an SSH session to the guest VM.

Let’s use the ssh command to connect to the VM:

$ ssh [email protected]
The authenticity of host ' (' can't be established.
[email protected]'s password:
Linux parrot 6.1.0-1parrot1-amd64 #1 SMP PREEMPT_DYNAMIC Parrot ...
 ____                      _     ____            
|  _ \ __ _ _ __ _ __ ___ | |_  / ___|  ___  ___ 
| |_) / _` | '__| '__/ _ \| __| \___ \ / _ \/ __|
|  __/ (_| | |  | | | (_) | |_   ___) |  __/ (__ 
|_|   \__,_|_|  |_|  \___/ \__| |____/ \___|\___|

Consequently, the connection is successful.

5. Conclusion

In this article, we discussed launching QEMU/KVM VMs using either virt-manager or QEMU command line option. In both cases, bridged networking and SSH connectivity enable remote management of the headless VM guest from the host. This is a vital technique for working with Linux VMs.

Inline Feedbacks
View all comments