Windows in a Libvirt KVM VM
Preface
These are notes on creating a Windows and Linux hybrid environment, specifically when running Windows in a Libvirt/KVM VM. I also have Notes on Windows and Linux hybrid environment in a physical machine.
It should be noted that while this guide takes a more complicated approach to setting up the virtual machine, it should result in better performance when using it because we configure the network and hard drive as ‘VirtIO’ (paravirtualized) devices instead of emulated devices.
See the common notes first
I recommend reading Common setup for Windows and Linux systems first (there will be points at which you are referred back to this page) and use this page for the parts specific to Windows in a Libvirt/KVM VM.
Installation notes
Use at least Windows 10 Pro Version 2004, with Version 20H2 preferred. Windows 10 Home might work for some of this, but not all features are available.
Setting up the virtual machine on a Linux host
NOTE This guide doesn’t use bleeding edge setting. Instead we stick (Linux side) to stable and tested technologies that, except bug fixes, performance improvements, and generally getting better over time, have been available in Linux for at least five years.
That means, for example, we don’t use a UEFI VM (for that item there is no real point, quite yet, as the SecureBoot/certificate chain for WHQL-certified VirtIO drivers for Windows isn’t (yet) available outside of a paid RedHat subscription — it appears Ubuntu has a Windows Server edition version of the VirtIO drivers that use that technology, but I am not aware of the same for Windows 10).
Install Virtual Machine Manager and virt-viewer on your Linux host
For example, on Debian/Ubuntu/Linux Mint issue the command:
sudo apt-get install libvirt-daemon virt-clients virt-manager virt-viewer
Add an ‘isolated’ network to use for communication between the Linux host and guests (the default install already adds a ‘NAT’ network named
default
for communicating to other hosts).- Launch
Virtual Machine Manager
- Double-click on the line labelled
QEMU/KVM
:… - Click on the
Virtual Networks
Tab - Click on the
+
icon (akaAdd Network
) - Give the network a name.
- Chose Mode:
Isolated.
- Configure the networking information.
- Click
Finish
.
- Launch
If you want to be able to allow network traffic from other hosts on the network or internet to the virtual machine you will need to do some searching and reading about Linux networking — that is out of scope for this article.
Download and install Windows and drivers
We’re doing this a slightly harder way (using virtio drivers during install) that give better cpu, disk, and network performance.
Download the necessary CD images
Make sure you have a Windows 10 Product Key to verify your right to use Windows 10.
Download the most recent Windows 10 Pro release, which is 20H2 (October 2020 Release) as of this writing. For this guide you definitely want the English 64-bit version.
This will download a file named
Win10_20H2_English_x64.iso
I recommend you also click on ‘Verify your download` on the Microsoft download page, and find the ‘hash’ the ‘English 64-bit’ version.
Once the ISO is downloaded, open a terminal.
cd ~/Downloads
sha256sum Win10_20H2_English_x64.iso
- The output should match the hash from the site above (case doesn’t matter).
- If the output does not match the given hash, the download failed; try again.
Download the Latest stable KVM VirtIO drivers ISO from the Fedora Project
Copy both
.iso
files to/var/lib/libvirt/images
. You will need to do the copy as root (e.g. usingsudo
).Alternatively, or if Libvirt is running on a different Linux machine than the one with the
.iso
files:ls -al '*.iso'
and make note of the file sizes of the ISO you want to use with libvirt.Execute
virsh -c <URI-to-libvirt-host> vol-create-as --pool default --allocation <size-of-file-from-ls> --capacity <size-of-file-from-ls> --format raw --name <name-of-ISO>
Execute
virsh -c <URI-to-libvirt-host> vol-upload --pool default --vol <name-of-ISO> --file <path-to-and-ISO-name>
- Example URIs for libvirt hosts include:
- For a local qemu/kvm libvirt:
qemu:///system
- For accessing qemu/kvm libvirt via SSH:
qemu+ssh://user@host/system
- For a local qemu/kvm libvirt:
Initial steps for creating the Windows virtual machine
Using Virtual Machine Manager create a virtual machine for Windows
- In VMM (Virtual Machine Manager) select the icon in the top left (‘Create a new virtual machine’)
- Choose Local Install media (ISO image or CDROM)
- Verify ‘Architecture options|Architecture’ is x86_64
- Select ‘Forward’
- Browse for the Windows ISO
- For ‘Choose the operating system you are installing’ enter/select ‘Microsoft Windows 10’
- Select ‘Forward’
- If you have enough memory, give the virtual machine 8192 MB (8 GB) of memory, otherwise use the defaults (minimum 4096 MB)
- Recommending giving at least two cpus, but four would be better.
- Select ‘Forward’
- Set the size of Hard Disk to give the Windows Virtual Machine. I recommend at least 80 GB, although according to Microsoft the VMM default of 40 GB ought to be ’enough’.
- Select ‘Forward’
- Give the virtual machine a name for VMM purposes (this is different than the Windows hostname).
- Make sure
Customize configuration before install
is checked. - Select ‘Finish’.
Finalize the configuration of the Windows virtual machine
In Overview, make sure the virtual machine has the name you want.
Also in overview, use a Q35 BIOS virtual machine
Select
SATA Disk 1
- Under
Advanced Options
changeDisk bus
toVirtIO
and clickApply
SATA Disk 1
will becomeVirtIO Disk 1
- Under
Select
NIC:xx:xx:xx
- Change
Device model
tovirtio
- Change
Select
Add Hardware
- Choose
Select or create custom storage
- Select
Manage...
and select the VirtIO driver ISO - Change
Device type
toCDROM device
- Select
Finish
- Choose
Select ‘Add Hardware`
- Choose
Network
- Change
Network source
to the isolated network you created - Change
Device model
tovirtio
- Select
Finish
- Choose
Select
Add Hardware
- Choose
Channel
- For
Name
selectorg.qemu.guest_agent.0
- Select
Finish
- Choose
Select
Add Hardware
- Choose
Channel
- For
Name
selectorg.spice-space.webdav.0
- Select
Finish
- Choose
Select
Add Hardware
- Choose
RNG
- Select
Finish
- Choose
Select
Begin Installation
The parts that come with your Windows license and/or base VM requirements
The Windows install bootstrap (early install)
A VMM graphical console showing the Windows boot process and then installer screen will open.
Select your language and other preferences and then click ‘Next’.
Click ‘Install Now’
Enter your Windows Product Key and Click ‘Next’
As if you had a real choice (not using Windows is unrealistic for most in today’s world); check ‘I accept the license terms’
Select ‘Install Windows’
Install the VirtIO drivers we need
- Select ‘Load Driver’
- Click
Browse
- Select the virtio driver ISO (probably drive E:)
- Double-click on
NetKVM
, thenw10
, thenamd64
, then clickOK
- The VirtIO Ethernet Driver should be selected, so Click ‘Next’
- Select ‘Load Driver’
- Click
Browse
- Select the virtio driver ISO (probably drive E:)
- Double-click on
viostor
, thenw10
, thenamd64
, then clickOK
- The VirtIO SCSI Driver should be selected, so Click ‘Next’
Drive 0 Unallocated Space
should be selected, so click ‘Next’Wait while Windows installs the base system.
Reboot (will occur automatically after a bit).
Finishing the base Windows install
After the initial installation phase the Windows install will reboot at which point you will do the usual Windows 10 Pro first boot procedure. This article won’t cover those steps as there are many thorough guides available.
When prompted about whether to make this computer publicly visible to other computers and devices on the network, it is safe to say ‘yes’ because the network is actually a local (to the Linux host) network that is has a NAT between the Windows VM and anything outside the Linux host. (It is still recommended to add a firewall to your Linux host, but that is outside the scope of this article). If you don’t plan on using Windows File Sharing from the virtual machine to other hosts you can safely (and and it’s safer) to say ’no’ here.
If you want to be able to access Windows file sharing resources on your local network outside the Linux host from the Windows Virtual Machine you will have to make this network a ‘Private’ (trusted) network so that File and Print sharing will work on that network for the Windows VM. For the prompt mentioned above, that means choosing ‘Yes’.
If you will be wanting other devices to access network resources on the Windows VM you will need to do some additional reading / research to learn how to set up the network to allow this. Such a configuration is beyond the scope of this article.
Install the QEMU Guest Agent and Spice guest tools
- In File Explorer open the KVM VirtIO drivers CD.
- Double-click
virtio-win-guest-tools
and follow the prompts.
Update with Windows Update
- Make sure your machine is activated and fully up to date with Windows Update.
- If you wish, configure ‘Advanced Options’ and ‘Delivery Optimization’ of ‘Windows Update’.
Make the isolated (host-only) second network a ‘private’ network
We want the isolated second network we created to be used as a ’trusted’ communications network between the VM and the host, which means we need to convince Windows to label it a ‘Private’ network.
- In an ‘Administrator’ Powershell, issue the command
ipconfig
and make note of which ‘Ethernet’ adaptor is associated with which network (that is host-only vs. default/NAT network). - In the same powershell, issue
route print
and note which interface number is the ‘host-only’ network - Also note the IP address associated with the host-only network
- In the same powershell, issue
route -P add 0.0.0.0 mask 0.0.0.0 <IP-address-of-host-only-network> metric 1500 if <interface-number-from-above>
You should be prompted to allow other computers to see this host on this network which will likely be called ‘Network 2’. Say yes — that makes this a private (trusted) network.
You can now exit the administrator powershell.
- If you want to verify which networks on the virtual machine are considered ‘Private’, click on the network icon in the taskbar, and then select “Network & Internet Settings”.
- On the left, select ‘Ethernet’, and click on each network listed there, in turn.
- When you select the network you should see the option to configure it as ‘Public’ or ‘Private’. ‘Public’ means the network is not trusted and uses a more restrictive firewall.
Tweak according to common Windows and Linux setup
- Configure language and regional settings as appropriate
- Tweak the base install (before adding any software or apps) and settings to your preferred base configuration
- I also recommend creating a copy of your freshly installed virtual hard
drive. (the virtual disk image on a typical Debian/Ubuntu system would be
located in
/var/lib/libvirt/images
) as well as the Libvirt configuration in/etc/libvirt
. It is presumed you know enough Linux, or can learn it elsewhere, to do this.
Configure ‘Network and Sharing’, if applicable
If you want to allow this virtual machine to access Windows file shares on hosts on networks you have marked as ‘Private’ (trusted) networks you need to configure ‘File and Printer Sharing’.
- Open
Settings
- Select
Network & Internet
- Select
Network and Sharing Center
- Click on
Change advanced sharing settings
- Under the ‘Private’ section, ‘File and printer sharing’ subsection, select
Turn on file and printer sharing
- Under the ‘Public’ section, ‘File and printer sharing’ subsection, select
Turn off file and printer sharing
- The ‘Network discovery` subsections are irrelevant because of the type of networking used in the configuration in this article. This VM can’t discover hosts outside the Linux host, and hosts outside the Linux hosts can find this VM, even if the options are enabled.
- Under
All networks
,Password protected sharing
subsection, make sureTurn on password protect sharing
is enabled.
Configure language and regional features as appropriate
See language and region configuration in common docs
Configure ‘For developers’ in ‘Upgrades & Security’
- You should go through these settings as many of them are useful to power users and developers – be careful though as there are often security implications to the options. I certainly don’t enable all the options.
- If you have enabled networking into the virtual machine, and you do allow ‘Remote Desktop’ I recommend altering the default firewall rule to be for ‘Private’ networks only, perhaps even only for your particular subnet.
Add Windows (system) features
Head back to common setup for windows and linux systems, you shouldn’t need to come back to this page.
The rest, as suits your needs and preferences
The rest is about learning what makes for a comfortable environment for you. I personally tend to get annoyed with ‘opinionated’ or ‘perfect’ setup guides, and am trying to create more flexible set of suggestions that can easily be adapted to suit you.