[//]: # ( pandoc -f markdown -t html5 -s -c /path/to/style/sheet/file.css \ --self-contained -o /path/to/output/file.html /path/to/this/file.md ) ## Set up qemu-kvm for CentOS 7 ### Synopsis On a kvm-capable x86\_64 host running CentOS Linux 7.9 with a single wired network adapter and a static ipv4 address: - Disable NetworkManager and set up a network bridge. - Add a tun/tap device to the bridge for pass-thru networking with qemu guests. - Install and configure qemu-kvm and related packages with support for guests requiring both UEFI and legacy BIOS boot. - Test boot an iso image with UEFI boot. ### Set up network bridge [1] [2] [3] [4] Install bridge utilities (and dependencies) on the host: ``` > sudo dnf install bridge-utils ``` Identify the host's active network adapter (e.g. enp1s0) and settings: ``` > nmcli device show ... GENERAL.DEVICE: enp1s0 GENERAL.TYPE: ethernet GENERAL.HWADDR: 1A:2B:3C:4D:5E:6F ... IP4.ADDRESS[1]: 192.168.1.99/24 IP4.GATEWAY: 192.168.1.1 ... IP4.DNS[1]: 192.168.1.1 IP4.DNS[2]: 8.8.8.8 IP4.DNS[3]: 9.9.9.9 ... ``` Create a network config script for the bridge: ``` > sudo /bin/cat <<'_EOF_' > /etc/sysconfig/network-scripts/ifcfg-br0 > DEVICE="br0" > BOOTPROTO="static" > GATEWAY="192.168.1.1" > IPADDR="192.168.1.99" > PREFIX="24" > ONBOOT="yes" > TYPE="Bridge" > NM_CONTROLLED="no" > _EOF_ ``` Verify packet filtering is disabled for bridges on the host: ``` > cat /usr/lib/sysctl.d/00-system.conf ... net.bridge.bridge-nf-call-ip6tables = 0 net.bridge.bridge-nf-call-iptables = 0 net.bridge.bridge-nf-call-arptables = 0 ... ``` Disable and save the active network adapter's existing config script: ``` > sudo /bin/mv /etc/sysconfig/network-scripts/ifcfg-enp1s0 \ > /etc/sysconfg/network-scripts/ifcfg-enp1so.disabled ``` Create a new config script (e.g. as eth0) for the active adapter: ``` > sudo /bin/cat <<'_EOF_' > /etc/sysconfig/network-scripts/ifcfg-eth0 > DEVICE="eth0" > BOOTPROTO="none" > BRIDGE="br0" > HWADDR="1A:2B:3C:4D:5E:6F" > ONBOOT="yes" > TYPE="Ethernet" > NM_CONTROLLED="no" > _EOF_ ``` Add the following lines if not already present in /etc/sysconfig/network-scripts/ifcfg-lo: ``` ONBOOT="yes" NM_CONTROLLED="no" ``` Ensure /etc/resolv.conf exists and contains valid nameserver entries: ``` > cat /etc/resolv.conf ... nameserver 192.168.1.1 nameserver 8.8.8.8 nameserver 9.9.9.9 ... ``` Edit /etc/default/grub and add the params net.ifnames=0 and biosdevname=0 to the existing params of the GRUB\_CMDLINE\_LINUX entry: ``` > sudoedit /etc/default/grub ... GRUB_CMDLINE_LINUX="crashkernel=auto net.ifnames=0 biosdevname=0 ... " ... ``` Regenerate the grub config file: ``` > sudo grub2-mkconfig -o /boot/grub2/grub.cfg ``` Stop and disable NetworkManager ``` > sudo systemctl stop NetworkManager.service > sudo systemctl disable NetworkManager.service ``` Enable the network service: ``` > sudo systemctl enable network.service ``` Reboot the host. Verify the bridge is enabled: ``` > brctl show bridge name bridge id STP enabled interfaces br0 8000.1c1b0d36ca12 no eth0 ``` Enable spanning tree protocol (STP) on the bridge if it will not be the only bridge on the host: ``` > sudo brctl br0 stp on > brctl show bridge name bridge id STP enabled interfaces br0 8000.1c1b0d36ca12 yes eth0 ``` If network comes up OK on reboot it's safe to delete /etc/sysconfg/network-scripts/ifcfg-enp1so.disabled ### Install qemu-kvm-ev [5] [6] [7] [8] [9] Verify host is x86\_64 arch with AMD (smx) or Intel (vmx) cpu flags: ``` > grep -Eq '(svm|vmx)' /proc/cpuinfo || echo 'No kvm on this host' ``` Install base package (and dependencies) on the host: ``` > sudo dnf install qemu-kvm ``` Upgrade to qemu-kvm-ev (latest available version is 2.12) and dependencies: ``` sudo dnf install centos-release-qemu-ev sudo dnf install centos-release-ceph-nautilus sudo dnf install qemu-kvm-ev ``` We need Open Virtual Machine Firmware for UEFI boot: ``` > sudo dnf install OVMF.noarch ``` View and verify the package contents: ``` > rpm -ql OVMF.noarch /usr/share/OVMF /usr/share/OVMF/OVMF_CODE.secboot.fd /usr/share/OVMF/OVMF_VARS.fd /usr/share/OVMF/OVMF_VARS.secboot.fd /usr/share/OVMF/UefiShell.iso /usr/share/doc/OVMF/Licenses /usr/share/doc/OVMF/Licenses/OpensslLib-License.txt /usr/share/doc/OVMF/Licenses/OvmfPkg-License.txt /usr/share/doc/OVMF/Licenses/edk2-License.txt /usr/share/doc/OVMF/README /usr/share/doc/OVMF/ovmf-whitepaper-c770f8c.txt /usr/share/qemu /usr/share/qemu/firmware /usr/share/qemu/firmware/50-ovmf-sb.json /usr/share/qemu/firmware/60-ovmf.json ``` ### Qemu guest network setup Must specify guest network setup with the `-nic` and `-netdev` params. Get available NIC adapter types with `/usr/libexec/qemu-kvm -nic model=?` Guest must have driver support for the selected type. For best throughput enable virtio support with `-net nic,model=virtio` Get available network setup types with `/usr/libexec/qemu-kvm -netdev type=?` ###### User (default) Guest is in a qemu-managed private LAN. \ `-netdev user,id=id[,option][,option][,...]` ###### Tap host bridge --> tap device --> guest NIC \ `-netdev tap,id=id[,fd=h][,ifname=name][,script=file][,downscript=dfile] [,helper=helper]` ###### Bridge `-netdev bridge,id=id[,br=bridge][,helper=helper]` ###### Socket `-netdev socket,id=id[,fd=h][,listen=[host]:port][,connect=host:port]` ###### VDE `-netdev vde,id=id[,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]` ###### Hubport `-netdev hubport,id=id,hubid=hubid` ### Test the installation [10] [11] [12] [13] [14] Ensure kvm kernel module is loaded: ``` > sudo lsmod | grep kvm ``` Add your USER account to the kvm and qemu groups: ``` > sudo usermod -aG kvm,qemu $USER ``` You will have to log out and back in for the group adds to take effect, or use the newgrp command. The firmware will run with secure boot enabled (SECURE\_VARS) or disabled (EFI\_VARS): ``` OVMF='/usr/share/OVMF' EFI_CODE='OVMF_CODE.secboot.fd' EFI_VARS='OVMF_VARS.fd' SECURE_VARS='OVMF_VARS.secboot.fd' ``` Qemu handles PC system flash storage (persistent flash storage) as a parallel flash image (i.e. as a block device with a pflash interface) so we must create block devices for the EFI\_CODE and EFI\_VARS files; changes to firmware settings will not be saved as the EFI\_VARS file is writable only by root; in production we would make a user-writable copy of EFI\_VARS; here we test with secure boot disabled; EFI\_CODE must be declared before EFI\_VARS; boot target is the UEFI shell iso image: ``` > /usr/libexec/qemu-kvm \ > -blockdev node-name=CODE,driver=file,filename=${OVMF}/${EFI_CODE},read-only=on \ > -blockdev node-name=VARS,driver=file,filename=${OVMF}/${EFI_VARS},read-only=on \ > -machine type=q35,pflash0=CODE,pflash1=VARS \ > -drive media=cdrom,file=${OVMF}/UefiShell.iso \ > -net none -serial stdio -display none -m 256M -cpu host ``` The OVMF command line interface should appear in your terminal (stdio). Type exit to enter the UEFI shell interface. Press Ctrl-C to shut down the VM. ### Additional VM management tools Install these packages to import and manage guest images with qemu-kvm: ``` > sudo dnf install libguestfs libguestfs-tools libguestfs-winsupport virt-dib \ > virt-v2v virt-p2v-maker ``` ###### References 1. [How to Create A Network Bridge on CentOS 7](https://www.itzgeek.com/how-tos/mini-howtos/create-a-network-bridge-on-centos-7-rhel-7.html) 2. [CentOS/RHEL 7: How to modify Network Interface names](https://www.thegeekdiary.com/centos-rhel-7-how-to-modify-network-interface-names/) 3. [Understanding the Network interface configuration file](https://www.thegeekdiary.com/understanding-the-network-interface-configuration-file-etc-sysconfig-network-scripts-ifcfg-eth/) 4. [Disable Network Manager on CentOS 7](https://radwebhosting.com/client_area/knowledgebase/164/Disable-Network-Manager-on-CentOS-7.html) 5. [UEFI boot for VM](https://www.server-world.info/en/note?os=CentOS_7&p=kvm&f=11) 6. [qemu-kvm-ev](https://github.com/akiko97/qemu-kvm-ev) 7. [Windows 10 VM](https://github.com/infokiller/win10-vm) 8. [libvirt networking](https://wiki.libvirt.org/page/Networking) 9. [Use virt-manager as a non-root user on Linux](https://computingforgeeks.com/use-virt-manager-as-non-root-user/) 10. [edk2 quickstart for virtualization](https://www.kraxel.org/blog/2022/05/edk2-virt-quickstart/) 11. [Open Virtual Machine Firmware (OVMF) Status Report](http://www.linux-kvm.org/downloads/lersek/ovmf-whitepaper-c770f8c.txt) 12. [How to boot Windows partition virtually under KVM with UEFI firmware](https://k3a.me/boot-windows-partition-virtually-kvm-uefi/) \ 13. [UEFI, PC boot process and UEFI with QEMU](https://joonas.fi/2021/02/uefi-pc-boot-process-and-uefi-with-qemu/) 14. [Setting up QEMU with OVMF (UEFI) and swtpm (software TPM emulation)](https://github.com/tompreston/qemu-ovmf-swtpm)