OFFSET偏移
← All articlesOFFSET / FIELD NOTESNO. 136

KVM host installation, permissions, and network preparation

Check host capabilities, distribution components, management authorization, and the actual default-network state one by one.

English translation · Code and commands follow the Chinese original.

IN THESE READING PATHSKVM host and management foundations ↗
About 13 min readStart reading

The commands and XML are generic examples and must be adjusted for the host version and actual resources. Network addresses use documentation ranges; choose a nonconflicting private network for real deployments. See the relevant sections for the conditions that apply to image modification and device passthrough.


1. Verifying hardware virtualization#

The installation commands in this article apply to different distributions and should not be run consecutively. On NixOS, maintain software and services through modules and Home Manager rather than directly editing /etc or dotfiles. AMD IOMMU is normally initialized by firmware and the kernel; iommu.strict=1 controls only the invalidation policy and is not an enable switch.

Before installing any software, confirm that the CPU supports hardware virtualization, the corresponding firmware extensions are enabled, and the kernel modules can load correctly.

1.1 Check CPU virtualization extensions

Intel platforms require VT-x (vmx); AMD platforms require AMD-V/SVM (svm).

# 统计 CPU 虚拟化标志位(> 0 表示支持)
egrep -c '(vmx|svm)' /proc/cpuinfo

If this returns 0, the CPU either does not support hardware virtualization or it is disabled in BIOS/UEFI.

Inspect the specific flags in more detail:

# 查看完整 flags 行
grep -E '(vmx|svm)' /proc/cpuinfo

# 使用 lscpu 查看虚拟化信息
lscpu | grep -i virtualization

Example expected output (Intel):

Virtualization:                  VT-x

Example expected output (AMD):

Virtualization:                  AMD-V

1.2 Additional checks with kvm-ok

kvm-ok comes from the cpu-checker package and checks both the CPU and the /dev/kvm device in one run.

# Ubuntu/Debian
sudo apt install cpu-checker
sudo kvm-ok

# Fedora
virt-host-validate qemu  # Fedora 可用 libvirt 的验证工具;cpu-checker 包名不能跨发行版假定
sudo kvm-ok

Expected output:

INFO: /dev/kvm exists
KVM acceleration can be used

Possible failure output:

INFO: Your CPU does not support KVM extensions
KVM acceleration can NOT be used

1.3 Check the KVM kernel modules

# 查看 KVM 模块是否已加载
lsmod | grep kvm

# 如果未加载,手动加载
sudo modprobe kvm           # 通用 KVM 核心
sudo modprobe kvm_amd       # AMD 平台
sudo modprobe kvm_intel     # Intel 平台

Expected output (Intel platform):

kvm_intel           385024  0
kvm                 1134592  1 kvm_intel

A common issue: AMD-V disabled in BIOS Some motherboards, particularly ASUS and MSI AMD boards, ship with AMD-V disabled by default. Press Del/F2 during boot to enter firmware settings, find SVM Mode under Advanced CPU Configuration, and set it to Enabled. On Linux, the following command provides a quick check:

dmesg | grep -i "svm.*disabled by bios"

If you see svm: SVM disabled (by BIOS), that confirms it is disabled at the firmware level.

1.4 Check IOMMU support (a prerequisite for PCI passthrough)

If you plan to use VGA/PCI passthrough, such as GPU passthrough, also confirm IOMMU support.

# 检查 IOMMU 是否在内核日志中出现
dmesg | grep -i iommu

# 查看 IOMMU 分组
ls /sys/kernel/iommu_groups/ 2>/dev/null

On Intel platforms, also check whether VT-d is enabled:

dmesg | grep -i "DMAR" | grep -i "IOMMU"

If IOMMU is not enabled, add the following to the GRUB kernel command line:

  • Intel: intel_iommu=on
  • AMD: after enabling AMD-Vi in firmware, check kernel initialization and IOMMU groups; iommu.strict=1 is an optional DMA invalidation policy, not an enable switch

2. Installation guides by distribution#

The KVM virtualization stack includes the following core components:

Component Function Key package name
KVM kernel module CPU hardware virtualization acceleration kvm.ko (included with the kernel)
QEMU Device emulation and virtual-machine execution engine qemu-kvm / qemu-full
libvirt Virtual-machine management abstraction layer with a unified API libvirt-daemon
virsh libvirt command-line management tool libvirt-clients
virt-manager Graphical management interface (GUI) virt-manager
bridge-utils Bridge networking tools bridge-utils

2.1 Ubuntu 24.04+ / Debian

sudo apt update
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients \
  bridge-utils virt-manager virt-viewer qemu-utils
Package name Description
qemu-kvm QEMU userspace components with KVM acceleration; a virtual package that automatically pulls in the QEMU binary appropriate for the current architecture
libvirt-daemon-system The libvirt system daemon and systemd service unit files; replaces the older libvirt-bin
libvirt-clients Command-line clients: virsh, virt-admin, and virt-host-validate
bridge-utils Provides the brctl command for manually creating Linux bridges (bridge networking)
virt-manager GTK graphical management tool that manages virtual machines through the libvirt API
virt-viewer SPICE/VNC console viewer (the virt-viewer command), a lightweight alternative
qemu-utils Provides utilities such as qemu-img for creating/converting disk images and qemu-io for I/O testing

Optional but recommended additional packages:

sudo apt install libguestfs-tools virt-top ovmf
  • libguestfs-tools: guest disk tools such as virt-builder and virt-resize
  • virt-top: real-time virtual-machine resource monitoring, similar to top
  • ovmf: UEFI firmware for creating virtual machines that boot with UEFI

2.2 Fedora

# 方式一:安装 @virtualization 组(推荐,一键安装全部相关包)
sudo dnf install @virtualization

# 方式二:手动按需安装
sudo dnf install qemu-kvm libvirt-daemon libvirt-client \
  virt-manager virt-viewer bridge-utils

About the Fedora package group The @virtualization group includes qemu-kvm, libvirt-daemon, virt-manager, virt-viewer, edk2-ovmf, guestfs-tools, and other packages. It is Fedora's officially recommended installation method. Compared with installing packages manually, the group ensures correct dependencies and matching versions.

On Fedora, libvirt uses the modular daemon architecture by default; see 02_Installation_and_Setup.

2.3 Arch Linux

sudo pacman -S qemu-full virt-manager virt-viewer libvirt \
  dnsmasq edk2-ovmf swtpm iptables-nft
Package name Description
qemu-full The complete QEMU package, including all system emulators, such as qemu-system-x86_64 and qemu-system-aarch64. If you only need x86_64 virtualization, you can use qemu-base instead, but this is not recommended because it is too limited.
virt-manager Graphical management interface
virt-viewer SPICE/VNC console
libvirt Main package, including the libvirtd daemon
dnsmasq DHCP/DNS service required by libvirt NAT virtual networks, such as the default network
edk2-ovmf UEFI firmware (OVMF), required for creating UEFI virtual machines
swtpm TPM 2.0 emulator. Required for Windows 11 installation: Win11 requires TPM 2.0, and without swtpm it cannot pass the installation checks.
iptables-nft Tools used by the iptables-compatible backend; newer libvirt versions also support native nftables. Check the actual version, network firewall_backend, and distribution defaults.

Optional packages:

sudo pacman -S dmidecode guestfs-tools virt-top

qemu-full vs qemu-base vs qemu-desktop

  • qemu-base: includes only qemu-system-x86_64, suitable for minimal setups
  • qemu-desktop: includes x86_64 and common UI backends (SPICE, OpenGL), suitable for desktop users
  • qemu-full: includes QEMU emulators for all architectures; recommended for development/experimental environments to avoid repeated compilation later because an emulator is missing

2.4 openSUSE

# 安装 KVM 服务器模式(含 libvirt、QEMU、virt-manager)
sudo zypper install -t pattern kvm_server

# 补充图形管理界面(若 pattern 未包含)
sudo zypper install virt-manager

openSUSE's kvm_server pattern installs the complete KVM virtualization stack; the kvm_tools pattern provides additional guest-management tools and can be installed as needed.

2.5 Basic post-installation checks

Regardless of distribution, run the following commands after installation to confirm that the components are in place:

# 检查 QEMU 版本和可用架构
qemu-system-x86_64 --version

# 检查 libvirt 版本
virsh --version

# 检查 virt-manager 是否可启动
virt-manager --version

# 运行 libvirt 宿主机验证
virt-host-validate qemu

virt-host-validate checks IOMMU, CPU extensions, device permissions, and other items individually, marking each PASS/FAIL/WARN.


3. User and permission configuration#

libvirt controls access through UNIX sockets and PolicyKit. To let a non-root user manage virtual machines, add that user to the corresponding UNIX groups.

3.1 Add the user to the virtualization groups

# 将当前用户加入 libvirt 和 kvm 组
sudo usermod -aG libvirt,kvm $USER
Group name Permission scope
libvirt Allows management of virtual machines, networks, and storage pools through the libvirt socket (/var/run/libvirt/libvirt-sock)
kvm Allows access to the /dev/kvm device node to run QEMU processes with KVM acceleration

3.2 Make group changes take effect

usermod -aG changes the group membership loaded when a user logs in; existing shell sessions do not automatically inherit the new groups.

# 方式一:在当前 shell 临时生效(仅影响此 shell 及其子进程)
newgrp libvirt

# 方式二:登出后重新登录(永久生效,推荐)
# 注销当前桌面会话并重新登录

# 方式三:重启系统(最彻底)
sudo reboot

Group changes must take effect If you run virsh list --all before the group changes take effect, you will receive Failed to connect to the hypervisor or Permission denied. Make sure the current session has membership in the libvirt group.

3.3 Verify permissions

# 确认当前用户已加入目标组
id -nG | grep -E 'libvirt|kvm'

# 期望输出中包含 libvirt 和 kvm
# 示例: user adm cdrom sudo dip plugdev libvirt kvm docker

# 测试 libvirt 连接(不应需要 sudo)
virsh list --all

# 期望输出
#  Id   Name   State
# --------------------

If virsh list --all runs without sudo and returns an empty list, the permissions are configured correctly.


4. Managing the libvirtd service#

4.1 Start and enable

# 启动并设为开机自启(一次性操作)
sudo systemctl enable --now libvirtd

# 检查运行状态
sudo systemctl status libvirtd

Key expected output line:

Active: active (running) since ...

Socket activation On most distributions, libvirtd is configured to be socket-activated by default. This means that systemctl status libvirtd may show either active (running) or inactive (dead), and both can be normal:

  • When no clients are connected, libvirtd may be idle
  • When virsh or virt-manager initiates a connection, systemd automatically starts libvirtd through the socket

Check the socket state to confirm that the service is ready:

systemctl status libvirtd.socket libvirtd-ro.socket libvirtd-admin.socket

4.2 The modular daemon architecture

In modern distributions (Fedora 35+, Ubuntu 24.04+, Arch Linux), libvirt has been split from a monolithic libvirtd into multiple specialized daemons:

Traditional daemon Modern modular replacement Responsibility
libvirtd (monolithic) virtqemud QEMU/KVM virtual-machine management
virtnetworkd Virtual network management (NAT, bridge, DHCP)
virtstoraged Storage pool management (dir, LVM, iSCSI, and others)
virtnodedevd Host device management (PCI, USB, and others)
virtsecretd Key/password management (Ceph, iSCSI CHAP, and others)
virtinterfaced Host network interface management
virtproxyd Unified proxy entry point that routes requests to the appropriate module

Check which architecture is in use:

# 查看模块化 daemon 是否在运行
systemctl status virtqemud virtnetworkd virtstoraged 2>/dev/null

# 查看 libvirt 连接 URI(会显示使用哪个 daemon)
virsh uri
  • With the modular architecture, virsh uri outputs qemu:///system, which is actually handled by virtqemud
  • The monolithic architecture also outputs qemu:///system, but it is handled by libvirtd

From the user's perspective, virsh and virt-manager make exactly the same API calls with either architecture; the difference is transparent.

4.3 Troubleshooting service failures

# 查看 libvirtd 日志
sudo journalctl -u libvirtd -f

# 查看模块化 daemon 日志
sudo journalctl -u virtqemud -f

# 检查配置文件语法
sudo virt-host-validate qemu

# 查看 systemd 托管服务的日志;避免重复 daemon
journalctl -u libvirtd -b  # 检查已托管 daemon 的日志,不另起第二个实例

5. Default network configuration#

After installation, libvirt automatically creates a NAT virtual network named default, using the virbr0 bridge.

5.1 Network parameters

Parameter Value
Network name default
Bridge interface virbr0
Network address 192.0.2.0/24
DHCP address pool 192.0.2.2 - 192.0.2.254
Host IP (on this network) 192.0.2.1
DNS/DHCP service dnsmasq (automatically managed by libvirt)

5.2 Manage the default network

# 启动 default 网络
sudo virsh net-start default

# 设为自动启动(宿主机开机后自动创建)
sudo virsh net-autostart default

# 查看所有虚拟网络
virsh net-list --all

# 期望输出:
#  名称       状态     自动启动   持久
# -------------------------------------------
#  default    活跃     是         是

# 查看 virbr0 网桥接口
ip addr show virbr0

# 查看 DHCP 租约
virsh net-dhcp-leases default

5.3 Restore a missing network

If the default network was accidentally deleted or was never created:

# 从 libvirt 默认网络 XML 模板重新定义
sudo virsh net-define /usr/share/libvirt/networks/default.xml

# 启动并设为自启
sudo virsh net-start default
sudo virsh net-autostart default

The location of default.xml may vary slightly by distribution:

  • Debian/Ubuntu: /usr/share/libvirt/networks/default.xml
  • Fedora: /usr/share/libvirt/networks/default.xml
  • Arch: /etc/libvirt/qemu/networks/default.xml

5.4 Understanding NAT network communication

graph LR
    VM[虚拟机 / 192.0.2.x] -->|eth0| Bridge[virbr0 / 192.0.2.1]
    Bridge -->|NAT/Masquerade| Host[宿主机物理网卡 / enpXsY]
    Host -->|路由| LAN[外部网络/互联网]
  • Outbound from a virtual machine: traffic is translated by NAT and leaves through the host's physical NIC; the host must have IP forwarding enabled
  • Host to virtual machine: the host can directly ping 192.0.2.x
  • External access to a virtual machine: configure port forwarding on the host or use bridged networking; see Advanced Network Configuration

Verify that IP forwarding is enabled KVM NAT networking depends on the host's IP forwarding. Check its status:

sysctl net.ipv4.ip_forward
# 期望: net.ipv4.ip_forward = 1

If the value is 0, libvirt normally enables it automatically when starting the default network. However, disabling it manually may prevent virtual machines from reaching external networks.


6. Verifying the installation#

This section uses CirrOS 0.6.2, a historical smoke-test image; the x86_64 disk file listed in the official directory is approximately 20 MiB. MD5SUMS can check only for accidental transfer corruption, not provide strong source authentication. Check the signatures and strong-checksum chain available for the actual release. Do not use this kind of test image or its publicly known default password for externally exposed services. Paths read by system QEMU must also satisfy security policies and directory permissions; --graphics none does not automatically make an arbitrary guest provide a serial login.

Use a CirrOS test image for end-to-end verification. CirrOS is a minimal Linux distribution of only about 12MB, designed specifically for OpenStack/KVM testing.

6.1 Download the test image

# 下载 CirrOS(x86_64 压缩磁盘镜像)
wget https://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img

# 校验文件完整性(可选)
wget https://download.cirros-cloud.net/0.6.2/MD5SUMS
grep cirros-0.6.2-x86_64-disk.img MD5SUMS | md5sum -c -

6.2 Create and start the test virtual machine

virt-install --connect qemu:///system \
  --name test \
  --ram 512 \
  --vcpus 1 \
  --disk path=cirros-0.6.2-x86_64-disk.img \
  --import \
  --os-variant cirros0.6 \
  --graphics none \
  --network network=default
Parameter Meaning
--name test The virtual machine's name in libvirt
--ram 512 Allocate 512MB of memory
--vcpus 1 Allocate 1 virtual CPU core
--disk path=... Specify the disk image file path
--import Skip operating-system installation and use the existing disk image directly; importantly, without this option virt-install will try to launch an OS installer
--os-variant cirros0.6 Tell libvirt the guest OS type to optimize default settings, such as virtio drivers
--graphics none Do not start a graphical console; connect output directly to the current terminal, suitable for testing or environments without a desktop
--network network=default Connect to the default NAT virtual network

After the virtual machine starts, the terminal directly displays the CirrOS boot process and login prompt:

=== cirros: cirros 0.6.2 ===
login:

Default CirrOS login credentials:

  • Username: cirros
  • Password: <CIRROS_TEST_PASSWORD_FROM_RELEASE>

Press Ctrl+] to leave the console connection; the virtual machine continues running in the background.

6.3 Check the virtual machine state

# 列出所有虚拟机
virsh list --all

# 期望输出:
#  Id   Name    State
# -----------------------
#  1    test    running

# 查看虚拟机详细信息
virsh dominfo test

# 期望输出关键字段:
#  Id:             1
#  Name:           test
#  UUID:           xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
#  OS Type:        hvm
#  State:          running
#  CPU(s):         1
#  Max memory:     524288 KiB
#  Used memory:    524288 KiB

6.4 Clean up the test virtual machine

# 强制关闭虚拟机(相当于拔电源)
virsh destroy test

# 若虚拟机已正常关机(shutdown),用 undefine 直接删除定义即可
# 从 libvirt 中注销虚拟机定义(不删除磁盘文件)
virsh undefine test

# 可选:删除下载的测试镜像
rm cirros-0.6.2-x86_64-disk.img

destroy vs shutdown vs undefine

  • virsh destroy <name>: forcibly stop the virtual machine, similar to cutting power; data not yet written to disk may be lost. It does not delete the virtual-machine definition or disks.
  • virsh shutdown <name>: send an ACPI shutdown signal to the guest for a graceful shutdown; the guest needs an ACPI service installed
  • virsh undefine <name>: remove the virtual-machine configuration from the libvirt database; it does not delete disk files. Add --remove-all-storage to also delete the associated storage volumes.

7. Recommended post-installation configuration#

7.1 Set the default libvirt URI

When using virsh, avoid having to specify -c qemu:///system every time:

# 写入 shell 配置文件
echo 'export LIBVIRT_DEFAULT_URI="qemu:///system"' >> ~/.bashrc
source ~/.bashrc

# 或者一次性设置(已有 shell 会话)
export LIBVIRT_DEFAULT_URI="qemu:///system"

7.2 Configure the VM storage directory

pool-define-as creates a persistent definition, which is then activated by pool-start. pool-create-as creates only a transient pool, so do not assume it can autostart. System QEMU needs actual directory-traversal and file read/write permissions; home directories are often restricted by permissions or security policies. Choose an authorized storage directory rather than using chmod to open up the entire home directory.

Create a dedicated directory for virtual-machine disks and ISO images:

# 创建存储目录
mkdir -p ~/vm/images    # 虚拟机磁盘文件
mkdir -p ~/vm/isos      # 操作系统 ISO 镜像
mkdir -p ~/vm/cloud-init  # cloud-init 配置文件(可选)

# 注册为 libvirt 存储池(方便 virt-manager 可视化操作)
virsh pool-define-as --name vm-images --type dir --target ~/vm/images
virsh pool-define-as --name vm-isos --type dir --target ~/vm/isos
virsh pool-start vm-images
virsh pool-autostart vm-images
virsh pool-start vm-isos
virsh pool-autostart vm-isos

7.3 Configure remote management (optional)

Prefer an SSH tunnel: the remote account needs both SSH authentication and group or polkit authorization for the remote system libvirt socket. Permission to log in over SSH alone does not grant libvirt management access.

virsh -c qemu+ssh://user@server.example.com/system list --all

TLS management requires a CA, server and client certificates, correct hostname verification, private-key permissions, access control, and the appropriate socket configuration. Historical monolithic-daemon configuration keys include listen_tls, tls_port, key_file, cert_file, and ca_file. For socket activation or virtproxyd deployments, follow the official documentation for the architecture in use; editing the old libvirtd.conf alone is insufficient.

The historical combination of plaintext TCP listen_tcp and unauthenticated auth_tcp grants full management capability to anyone who can reach the port; it should not be the default even on a "trusted internal network." TLS commonly uses port 16514, while plaintext TCP commonly uses 16509. The port number does not prove that a connection is authenticated or encrypted.


Summary#

Whether the default NAT network is defined, started, or configured to autostart depends on the distribution's installation and existing state. NAT provides outbound forwarding, not complete security isolation; guests can usually still access the host's virtual bridge and other guests on the same network. The example subnet uses a documentation range to illustrate the topology. Replace it with a nonconflicting RFC1918 private network when creating a real network.

After configuration, verify each of the following conditions. The commands in this article have not been run:

  • KVM hardware acceleration is ready
  • The QEMU + libvirt software stack is installed
  • User permissions are configured correctly, allowing virtual-machine management without sudo
  • libvirtd, or the equivalent modular daemons, starts automatically at boot
  • The default NAT network is available

Next: Creating and Managing Virtual Machines covers the creation process, configuration parameters, and lifecycle management in depth.



References & further reading

  1. libvirt daemons and sockets ↗
  2. libvirt remote management ↗
  3. libvirt network XML ↗
  4. Linux kernel parameters ↗

Adapted from technical notes. Examples use generic names.

Continue along a reading path

KVM host and management foundations

  1. 01The responsibilities of KVM, QEMU, and libvirt
  2. 02KVM host installation, permissions, and network preparation
  3. 03Managing domains, storage, networks, and recovery with virsh
  4. 04virt-manager: VM creation, hardware panels, and remote control
CONTINUE READING / NEXT ARTICLEManaging domains, storage, networks, and recovery with virsh

Retain command categories and XML parameters while distinguishing persistent definitions, running instances, snapshots, and offline backups.