How to Route a Hyper-V VM Through a Host’s WireGuard VPN

How to connect your Hyper-V virtual machine (VM) to the internet via a WireGuard VPN (or any for that matter) running on the host while maintaining normal internet functionality when the VPN is off.

If you need to connect your Hyper-V virtual machine (VM) to the internet via a WireGuard VPN (or any for that matter) running on the host while maintaining functionality when the VPN is off, follow these steps to ensure proper routing, NAT, and DNS resolution.


Step 1: Set Up a Dedicated Internal Virtual Switch

  1. Open Hyper-V Manager.
  2. Go to Virtual Switch Manager (right-hand menu).
  3. Create a new Internal Switch:
    • Name it something identifiable, like WireGuardSwitch.
    • Apply the changes.
  4. Assign an IP address to the host’s virtual adapter:
    • Open PowerShell as Administrator.
    • Run:
      CopyEditNew-NetIPAddress -IPAddress 192.168.137.1 -PrefixLength 24 -InterfaceAlias "vEthernet (WireGuardSwitch)"

This sets the host’s internal switch interface to 192.168.137.1.


Step 2: Connect the VM to the Internal Switch

  1. Open Hyper-V Manager and select the VM.
  2. Go to Settings → Network Adapter.
  3. Change the connected virtual switch to the newly created WireGuardSwitch.

Step 3: Configure the VM’s Network Settings

Inside the VM:

  1. Set a static IP address for the VM’s network adapter:
    • IP Address: 192.168.137.192 (or whatever you want so long as it’s not .1)
    • Subnet Mask: 255.255.255.0
    • Default Gateway: 192.168.137.1
  2. Set DNS servers:
    • Preferred DNS: The WireGuard DNS (e.g., 192.168.7.1). Check your config file if unsure or run ipconfig when running the VPN to see what your DNS server is)
    • Alternate DNS: A public DNS like 8.8.8.8. or 1.1.1.1

Example Command:

netsh interface ipv4 set address name="Ethernet" static 192.168.137.192 255.255.255.0 192.168.137.1
netsh interface ipv4 set dns name="Ethernet" static 192.168.7.1
netsh interface ipv4 add dns name="Ethernet" 8.8.8.8 index=2

Step 4: Set Up NAT on the Host

The host must NAT traffic from the VM to the WireGuard VPN.

  1. Open PowerShell as Administrator.
  2. Create a NAT rule for the VM’s subnet:
    New-NetNat -Name "HyperV-NAT" -InternalIPInterfaceAddressPrefix 192.168.137.0/24

Step 5: Configure WireGuard to Avoid Subnet Conflicts

Ensure that WireGuard doesn’t incorrectly route traffic destined for the VM’s subnet (192.168.137.0/24).

  1. This shouldn’t be required but just in case you were wildly following ChatGPT instructions and changed this file
  2. Open your WireGuard configuration file (e.g., wg0.conf).
  3. Check the [Peer] and make sure AllowedIPs does not include the range above 192.168.137.0/24 – if it does then nothing will work – if for some reason it’s in there remove it.

Step 6: Test Connectivity

  1. On the host, test if it can ping the VM:
    ping 192.168.137.192
  2. On the VM, test connectivity to the host:c
    ping 192.168.137.1
  3. Verify DNS resolution from the VM:
    nslookup google.com
  4. Open a browser on the VM and test internet access.

Step 7: Enable Firewalls with Necessary Rules

Should not be required but if you find connectivity isn’t working you can update the firewalls on both the host and VM, ensuring the following rules are present:

On the Host:

Allow inbound and outbound traffic for the 192.168.137.0/24 subnet:

netsh advfirewall firewall add rule name="Allow VM Traffic Inbound" dir=in action=allow protocol=any remoteip=192.168.137.0/24
netsh advfirewall firewall add rule name="Allow VM Traffic Outbound" dir=out action=allow protocol=any remoteip=192.168.137.0/24

On the VM:

Allow the same inbound and outbound traffic:

cmdCopyEditnetsh advfirewall firewall add rule name="Allow Host Traffic Inbound" dir=in action=allow protocol=any remoteip=192.168.137.1
netsh advfirewall firewall add rule name="Allow Host Traffic Outbound" dir=out action=allow protocol=any remoteip=192.168.137.1

Troubleshooting Tips

  • If DNS resolution fails, double-check the WireGuard DNS configuration.
  • If no traffic is reaching the VPN, ensure the NAT rule (HyperV-NAT) is active via PowerShell:
    Get-NetNat

Conclusion

Following these steps ensures your Hyper-V VM routes all traffic through the host’s WireGuard VPN, with DNS and internet access functioning correctly. When the VPN is off, the VM seamlessly falls back to the host’s normal internet connection.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.