Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save eeriemyxi/1da4b533dcb5b496f9b6542a2080f847 to your computer and use it in GitHub Desktop.

Select an option

Save eeriemyxi/1da4b533dcb5b496f9b6542a2080f847 to your computer and use it in GitHub Desktop.
Windows 11 VM on Arch Linux and SSH'ing into it from Host Linux System

Windows 11 VM on Arch Linux and SSH'ing into it from Host Linux System

Important

This is mostly for personal notes. I skip anything that isn't personally difficult for me, which mainly includes some of the grunt steps.

This gist will document how I got a Windows 11 VM working on Arch Linux and later SSH'd into it from my host system.

The first step is to grab your Windows ISO of course. I chose Tiny11 by NT-DEV for this.

The second step is to grab virtio-win from a CDN like this one, but there are also mirrors in case that one is too slow for you. Anyway, I personally went with the stable release.

I'll be using virt-manager for the frontend. Before virt-manager I tried my luck with Gnome Boxes, but it really sucked. I don't recommend it.

sudo pacman -S virt-manager libvirt qemu-base
sudo systemctl enable --now libvirtd

Now move over the ISOs to /var/lib/libvirt/images:

sudo mv /home/<user>/Downloads/{windows,virtio-win}.iso /var/lib/libvirt/images/

And set the file permissions:

sudo chmod 644 /var/lib/libvirt/images/{windows,virtio-win}.iso
sudo chown root:root /var/lib/libvirt/images/{windows,virtio-win}.iso

Now open virt-manager and go to "File" then "New connection." Select "QEMU/KVM", enable "Auto-connect" and hit connect. I'll assume it just worked.

Important

"QEMU/KVM", not "QEMU/KVM user session"

After it connected, create a new virtual machine with that connection and select the Windows ISO from that location earlier as the install media. Set it up to your liking. I assume everything went well and it booted the ISO. Finish the installation.

You'll see a blue (i) button that says "Show virtual hardware details" when you hover it. Click it.

Click "Add Hardware" and add a storage CDROM device, then select the virtio-win ISO and add it, then hit "Finish."

Shutdown the VM and start it again, now go to File Explorer and open that new CDROM device/drive, you'll see virtio-win-guest-tools executable there. Install it. Restart the VM. Go to that drive again. Then under guest-agent folder install the version for your architecture.

Now, under hardware details, go to "Display Spice" and enable Open-GL and set "Listen type" to "None". Go to "Video QXL" (or similar) and select Virtio. Enable "3D acceleration". Now restart again.

In your terminal, run sudo virsh net-start default and sudo virsh net-autostart default. Now close virt-manager and do sudo systemctl restart libvirtd.

Now open back virt-manager and go to the hardware menu of your VM again. Go to NIC :cd:fe:9c (or similar) and select Virtual network 'default': NAT. Hit "Add Hardware" and select "Channel". In the new window, select org.qemu.guest_agent.0 and add the hardware with "Auto socket" turned on.

Restart the VM again. Eventually when the startup is complete, run these commands in PowerShell with administration permission:

Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd
Set-Service -Name sshd -StartupType 'Automatic'

Tip

By now the clipboards of your host system and the guest are probably synchronized by virtio-win. You can simply copy-paste the commands.

Then fix the firewall:

if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue)) {
    New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
}

Once the steps are complete, run:

sudo virsh domifaddr win11 --source agent

Where win11 is the name of the virtual machine. You can get it from sudo virsh list.

Running it should give you an IP address like 192.168.122.214. You can use that to SSH into your Windows VM:

ssh <user>@192.168.122.214

Important

You must have set a password when you created the Windows user account to avoid issues with authentication like getting asked for a passphrase even though you never set one. You could run net user <user> "password" from an elevated shell to set a password for your user. Or use SSH keys for authentication instead.

If the SSH command still times out, it may have something to do with the firewall:

Set-NetConnectionProfile -NetworkCategory Private
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
Restart-Service sshd

If your internet access doesn't work, try rebooting your PC. I had that issue but a reboot fixed it. If that doesn't work, try:

sudo mkdir /etc/libvirt/hooks

Then,

sudo nano /etc/libvirt/hooks/network

Then pasting in:

#!/bin/bash
# Libvirt Hook for the 'default' NAT network
# Fixes Docker/KVM conflict by forcing ACCEPT rules at the top of the chain

network="$1"
operation="$2"

if [ "$network" = "default" ] && [ "$operation" = "started" ]; then
    # 1. Allow traffic FROM the VM
    iptables -I FORWARD -i virbr0 -j ACCEPT
    
    # 2. Allow traffic TO the VM (if established)
    iptables -I FORWARD -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    
    # 3. Force NAT (Masquerade)
    iptables -t nat -I POSTROUTING -s 192.168.122.0/24 -j MASQUERADE
fi

Then making that script executable via sudo chmod +x /etc/libvirt/hooks/network and doing sudo systemctl restart libvirtd to restart the daemon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment