A visual walkthrough of building and networking a Windows 11 VM on Ubuntu using Libvirt, QEMU/KVM, and a bridged interface.
Standard update and upgrade before starting a project to make sure all packages are ready to go. NightlyJellyfin doesn't exist anymore, so I'll take care of that later.
Apparently Proxmox can't be hosted on Ubuntu—it's meant for Debian. So instead of using Proxmox, we'll use Libvirt, QEMU/KVM with a bridged interface.
Cockpit, libvirt, KVM, and QEMU dependencies have been installed successfully.
Virtualization wasn't enabled in the BIOS for my 5800X3D, so I rebooted and turned it on. After enabling SVM Mode, I reran the setup and it worked.
kvm.conf and kvm_amd.conf both exist, confirming KVM is ready to go. Reloading the AMD virtualization kernel module applies the new settings. An output of 1 confirms we're ready to go.
More dependencies are required, so we install them now. qemu-kvm is the hypervisor, libvirt-daemon-system/clients will manage the VMs, virtinst allows VM creation from CLI, ovmf provides us with the UEFI firmware, and bridge-utils is networking support for the VMs. We make sure that the default NAT is used for VMs on every boot, and then we verified our kernel modules exist again.
Now we create a new folder for ISO storage and download the ISO into that folder for use later.
We create our new virtual disk file in QCOW2 format and allocate it 80GB of space.
Using RealVNC from our Windows PC, we can now view the boot manager for our new VM! We'll select our newly created disk.
We've successfully booted into the Windows setup remotely. The VM has been created and is running on our Ubuntu machine, and we've connected to it from our main Windows machine.
Windows 11 wanted TPM 2.0 and Secure Boot enabled or it wouldn't let us pass. So we used a workaround with Shift + F10 to open the CLI and ran the following registry commands to bypass the checks:
reg add "HKLM\SYSTEM\Setup\LabConfig" /v BypassTPMCheck /t REG_DWORD /d 1 /f
reg add "HKLM\SYSTEM\Setup\LabConfig" /v BypassSecureBootCheck /t REG_DWORD /d 1 /f
reg add "HKLM\SYSTEM\Setup\LabConfig" /v BypassRAMCheck /t REG_DWORD /d 1 /f
reg add "HKLM\SYSTEM\Setup\LabConfig" /v BypassCPUCheck /t REG_DWORD /d 1 /f
We're now fully inside the Windows setup (win11_25h2) hosted purely on our Ubuntu machine and connected through RealVNC. If needed, we can also connect through Cockpit.
After setting the VM up, I wanted to try and make some use of it a few days later. I decided to run a mobile game bot on the VM so I could stop using it on my main machine, which took up valuable system resources. However, the LDPlayer version I needed (LDPlayer 4.0) required OpenGL to boot. OpenGL wasn't supported through this method, so I tried other things to fix it—like dedicating the GTX 960 GPU to the VM—but that broke the server.
After lots of messing around and breaking everything from the networking to the server's display (dedicating the GPU to the VM meant the server would get stuck at the login screen), I eventually fixed it by SSHing in and removing the GPU dedication. The screenshot above is me failing to connect to the server even though it was turned on, and since it's headless, I had to plug in an HDMI cable and monitor to fix it. I also changed the localhost IP from 10.0.6.19 to 10.0.6.31 during the mess. Oops.
I still want to get LDPlayer and the script working on a VM, but that will come at a later date.
Setting up the VM was a lot of fun (other than breaking the networking). Learning just how far you can go to create virtual environments and access them in different ways will definitely be useful down the road. As someone who uses lots of sandboxed containers for programs on their main PC, this would provide a great way for me to move the load to a dedicated system and scale it up.
This project provided good insight into how virtualization works in real-world applications, especially in a world adapting to cloud tech so fast.
I apologize for the lack of documentation on this writeup. It was the first time documenting something like this so it is done pretty poorly. Next time there will be more photos and maybe even exacty commands used etc to be closed to something like a Netlab.