December 18, 2016
Virtual machines are a very common practice nowadays, for reasons ranging from emulation to sandboxing. But when it comes to virtualization platforms, which solutions are there? Basically the big players are VMware and VirtualBox. There is another one that deserves interest: QEMU.
QEMU is a free software member of the Software Freedom Conservancy, meaning it does respect your freedom and your privacy. You can build it yourself but you’ll likely use your distribution’s package manager to install it, e.g.
$ sudo apt-get install qemu
Binaries for Windows are also available, but the points of the discussion will focus on the GNU/Linux host and guest operating systems, and take advantage of it. This article will go over the essentials of QEMU. We’ll also cover a practical setup configuration and how to seamlessly integrate the virtual machines into the host environment.
First, create an image for your virtual machine :
$ qemu-img create -f qcow2 my_vm.qcow2 16G
Note that QEMU supports VMware and VirtualBox formats, respectively
vdi. However, you will likely want to use QEMU’s specific
qcow2 format, as unlike the aforementioned, this format is easily manipulated by QEMU’s tool to resize, modify and convert the image. Now you can use an ISO image to boot from in order to install the OS of your choice:
$ qemu-system-x86_64 -drive file=my_vm.img -boot d -cdrom image.iso -m 512
Once the installation is complete, boot your machine with more specific configuration options:
$ qemu-system-x86_64 -drive file=my_vm.img -enable-kvm -smp 4 -m 8G
The options given here are the essential basics:
drive : virtual machine image
enable-kvm : if you run a virtual machines with the same architecture as your host, this option will greatly improve performances. It enables the Linux Kernel-based Virtual Machine (KVM), which turns your kernel into a hypervisor. To be able to activate this you need KVM module in your kernel. To verify that you have the necessary module, check your configuration :
$ grep KVM_INTEL /boot/config-$(uname -r)
If you have an Intel processor, or in the case of AMD :
$ grep KVM_AMD /boot/config-$(uname -r)
smp : number of CPU cores to let the virtual machine use from the host.
m : amount of RAM to dedicate to the virtual machine.
Additionally, you may want to use the
-nographic option to disable the graphic output of the virtual machine. It provides a lightweight emulation if you only want a server with which you would interact through SSH for example.
If you need something more like RDP, the SPICE protocol is the best choice. It offers copy-paste, resolution adjustments and much more. Refer to the wiki page for a detailed explanation.
If you want file sharing, here are two options.
-fsdev local,id=share,path=/path/to/share,security_model=none -device virtio-9p-pci,fsdev=share,mount_tag=share
These switches provide support for Plan9 file sharing protocol between the GNU/Linux host and a suitable UNIX guest (we still assume GNU/Linux for simplicity). It’s an efficient file sharing protocol. However, kernel support is required both on the host and guest operating systems. For a GNU/Linux system, this feature is enabled through a specific kernel module. Just make sure your distributions have it enabled, or add the module yourself. You can check your current kernel config again :
$ grep 9P /boot/config-$(uname -r)
You should have at least these enabled:
CONFIG_NET_9P CONFIG_NET_9P_VIRTIO CONFIG_NET_9P_FS CONFIG_NET_9P
On the guest, mount the shared path:
$ mount -t 9p -o version=9p2000.L,trans=virtio share /path/to/mount-point
After you get it to work, you can add it to your fstab :
share /mnt/share 9p trans=virtio,version=9p2000.L 0 0
More details can be looked up in the QEMU wiki.
This is a pragmatic approach, as SSH provides all you need on the guest side. You only need to install SSHFS on the host. It is not as fast as the 9p protocol, but for transfers between a VM and host, the difference is unremarkable.
Once your VM is all set up, deploy a SSH server on it. We’ll use QEMU’s TCP port forwarding to easily access it :
-net user,hostfwd=tcp:127.0.0.1:[port]:22 -net nic
[port] with a TCP port of your choice. The
-net nic option adds a network interface card to the VM, which is necessary to enable port forwarding.
A common approach to SSH authentication is to proceed using a key pair instead of typical password authentication. You can enforce it by setting this parameter in
Next, generate a RSA keypair for authenticating with this VM:
$ ssh-keygen -b 4096 # Follow the on-screen instructions.
Then append the public key in file
~/.ssh/authorized_keys for the user to authenticate as on the guest system. Then you can add an entry to your SSH config for this VM:
host my_vm Hostname localhost Identityfile %d/.ssh/my_vm_key.priv Port [forwarded port] User [guest user]
To log on:
$ ssh my_vm
A nice feature about X11, the system for running mouse-keyboard graphical applications on most GNU/Linux systems, is that it has networking capabilities. You can easily use it with SSH-based X forwarding to run applications from into the guest operating system onto your host X server. It has the advantage of being directly integrated in your environment. Manage the window as if it was part of your host, native copy-paste, notifications directly on the host… many perks. If you want to enable X forwarding for this connection you may add :
to your SSH config file. Or if you want to specify it in your command argument, add this switch:
$ ssh -Y [...]
And from there launch any graphical application, they will appear as if they were part of your system.
QEMU, unlike commercial solutions, requires additional configurations and understanding. There is an extensive man page that provides all the information you need and online examples to help with the basics. However, once the initial learning curve has passed, it provides a free and extensible solution that can easily integrate in any environment. If this article has sparked interest and has shed light on a new solution, it has fulfilled it’s purpose.