How to get started with libvirt on Linux

Nemanja Tomic

Sep 13, 2025 7 min read

Thumbnail

Virtualization is a great technology for everyone working in IT. Whenever you want to try out something new or test out a blueprint for your infrastructure, virtualization will help you tremendously in terms of time efficiency. And if you break something, it isn't half as bad as if you did on your bare metal machine since you can easily just spin up a new VM (virtual machine) in a matter of seconds. And I promise, once you have set up a system for managing your VMs, the rest is a piece of cake.

In this tutorial, we will go through the process of setting up a system that can create, manage and use virtual machines. We will use Arch Linux on our host OS, but it works on basically any other Linux distribution aswell (I tested it on Ubuntu and Fedora).

For our hypervisor, we will use KVM (Kernel-based Virtual Machine), mainly because it has been the most popular hypervisor for Linux for over 10 years now, and there is no real reason to use another one than KVM. And because we don't want to read the 1000 pages long documentation of KVM, we will also use libvirt on top of KVM.

Libvirt is an abstraction layer that gives us a few handy tools for creating and managing our VMs. The great thing about libvirt is that it brings the complexity of KVM to a human understandable level, making our lives that much easier. With libvirt, we also get access to several GUI and CLI tools like virt-manager or virt-clone, that allow us to do virtually anything we want with your VMs.

Requirements

  • Basic understanding of how virtualization works. Check out my other blog post to learn more.
  • Basic understanding of the Linux CLI.
  • No knowledge of KVM or other virtualization tools are required.

Installing dependencies

Before we begin, we need to make sure some dependencies are installed on the system. The tools are as follows.

Key system tools: These are the key tools/services/features that enable virtualization:

  • kvm
    • Kernel-based Virtual Machine.
    • Kernel module that handles CPU and memory communication.
  • qemu
    • Quick EMUlator
    • Emulates many hardware resources such as disk, network, and USB. While it can emulate CPU, you'll exposed to qemu/kvm, which delegates concerns like that to the KVM.
    • Memory relationship between qemu/kvm is a little more complicated but can be read about here.
  • libvirt
    • Exposes a consistent API atop many virtualization technologies. APIs are consumed by client tools for provisioning and managing VMs.

User/client tools: These tools can be interacted with by users / services.

  • virsh
    • Command-line tools for communicating with libvirt.
  • virt-manager
    • GUI to manage KVm, qemu/kvm, xen, and lxc.
    • Contains a VNC and SPICE client for direct graphical access to VMs.
    • GUI alternative to virsh, albeit less capable.
  • virt-install
    • Helper tools for creating new VM guests.
    • Part of the virt-manager project.
  • virt-viewer
    • UI for interacting with VMs via VNC/SPICE.
    • Part of the virt-mangaer project.

Ancillary system tools: These tools are used to support the system tools listed above.

  • dnsmasq: light-weight DNS/DHC server. Primarily used for allocating IPs to VMs.
  • dhclient: used for DHCP resolution; probably on your distro already.
  • dmidecode: prints computers SMBIOS table in readable format. Optional dependency, depending on your package manager.
  • ebtables: used for setting up NAT networking on the host.
  • bridge-utils: used to create bridge interfaces easily.
  • openbsd-netcat: enables remote management over SSH.

To install all the packages and dependencies listed above, run this command:

pacman -Sy --needed \
  qemu \
  dhclient \
  openbsd-netcat \
  virt-viewer \
  libvirt \
  dnsmasq \
  dmidecode \
  ebtables \
  virt-install \
  virt-manager \
  bridge-utils

Now I know I just said that the process is the same for all Linux distributions, but this step might be a bit different because the names for the packages might not be exactly the same. So if you are not using Arch at the moment, I advise you to ask AI what the corresponding package names for your distribution are to get a quick and easy answer. We won't need to install KVM because it comes preinstalled with the Kernel.

Enable the libvirt daemon

The next thing we have to do is to enable the libvirtd service. Suppose your system uses systemd for managing system processes (most modern systems do), we can enable and start the libvirtd service with the following command.

sudo systemctl enable --now libvirtd

Now libvirtd is alive and can talk to the backend systems, which means our tools that we're going to use are now working.

Libvirt keels its files at /var/lib/libvirt. There are multiple directories within.

drwx--x--x. 1 root root   0 Jun 20 02:00 boot/
drwxr-xr-x. 1 root root 118 Sep 13 12:12 dnsmasq/
drwx--x--x. 1 root root   0 Jun 20 02:00 filesystems/
drwx--x--x. 1 root root   0 Jun 20 02:00 images/
drwx------. 1 root root  30 Sep 13 10:58 libxl/
drwx------. 1 root root   0 Jun 20 02:00 lxc/
drwx------. 1 root root   0 Jun 20 02:00 network/
drwxr-x--x. 1 qemu qemu  68 Jun 20 02:00 qemu/
drwx--x--x. 1 root root   0 Jun 20 02:00 swtpm/

The images directory is the default location a VM's disk image will be stored (e.g. (qcow2)[https://en.wikipedia.org/wiki/Qcow]).

Permissions

The primary tricky bit is getting permissions correct. There are a few key pieces to configure so your using can interact with qemu:///system. This enables VMs to run as root, which is generally what you'll want. This is also the default used by virt-manager. (Check out this blog post form Colin Robinson, which calls out the differences)[https://blog.wikichoon.com/2016/01/qemusystem-vs-qemusession.html].

virsh will use qemu://session by default, which means CLI calls not run as sudo will be looking at a different user. To ensure all client utilities default to qemu:///system, add the following configuration to your .config directory.

sudo cp -rv /etc/libvirt/libvirt.conf ~/.config/libvirt/
sudo chown ${YOURUSER}:${YOURGROUP} ~/.config/libvirt/libvirt.conf

Don't forget to uncomment the last line in the file after you copied it to your local configurations. Otherwise, your virsh will still use the user context instead of the system context.

Depending on the option you go with, you may need to re-login or at least restart libvirtd (see below).

Pro tip

When using qemu:///system, access is dictated by polkit. If you don't want to enter your password everytime you start virt-manager, create a file at /etc/polkit-1/rules.d/50-libvirt.rules and paste the following in.

edit /etc/polkit-1/rules.d/50-libvirt.rules

/* Allow users in wheel group to manage the libvirt
daemon without authentication */
polkit.addRule(function(action, subject) {
    if (action.id == "org.libvirt.unix.manage" &&
        subject.isInGroup("wheel")) {
            return polkit.Result.YES;
    }
});

This adds your group to the polkit config. You will not be prompted for a password when interacting with virt-manager or virsh.

Conclusion

And that should be it. If you run virt-manager in your terminal, a GUI will pop up and you can setup your VM with the ISO of your choice. The rest is pretty self-explanetory, so I won't go into more detail. If you want to know the various tools that you can use with libvirt, checkout (this page)[https://libvirt.org/apps.html] where all the possible tools are listed. I'm sure you'll find something that is appropriate for your use case.

Subscribe To My Blog

Enter your email to receive the latest articles about tech, work and life.

© 2025 Nemanja Tomic. All rights reserved.