[//]: # (
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)