NAT networking with Hyper-V on Windows 10
I was setting up a new system with Windows 10 recently and decided to have a shot at Hyper-V instead of VirtualBox. An attractive feature of Hyper-V is dynamic memory. This means the VM only uses what it needs and essentially shares the unused memory with the host system so either the host or the VM can use it as needed. In contrast, VirtualBox reserves all the memory assigned to the VM right away.
Networking in Hyper-V
Overall, using Hyper-V is pretty straight forward if you've used VirtualBox or VMWare. One bit of challenge is the network configuration: you connect your VMs to virtual switches.
The type of switch decides what the VM has access to:
- External: essentially bridges the chosen host network adapter to the virtual switch. Any VM connected will have direct access to the LAN.
- Internal: creates a network adapter on your host and connects it to the virtual switch. Allows your host to communicate with any connected VM but the VMs cannot access your LAN from this switch.
- Private: a virtual switch that only VMs can connect to.
The easiest way to give network access to a VM is to connect it to an external switch. However, you may not always want it to be fully accessible from other systems on the network. If you're looking for the equivalent to a NAT connection in VirtualBox, at first sight there's no such feature.
As it turns out, you can relatively easily leverage Windows built-in features to turn an internal switch into a NAT connection. Here is what you need to do:
- Create an internal switch
- Right-click on the Windows start button and choose "Network Connections"
- Pick the host network adapter which is connected to the network you want to share with your VMs. Right click on it and switch to the Sharing tab.
- There, you can configure Window's Internet Connection Sharing (ICS). Pick the vEthernet adapter corresponding to your internal network and click Ok.
Activating ICS has the following effect on your internal switch:
- Enables DHCP so your VMs automatically get an IP address.
- Enables routing of network traffic from the internal network to your physical network.
- Enables DNS, both for your VMs to resolve internet names but also for your host to resolve your VMs names. You'll be able to reach your VMs from the host by using
Bonus: Port forwarding
ICS has some extra configuration that's supposedly able to do port forwarding but it hasn't worked for me. However, there is a way to configure port forwarding from the command line:
netsh interface portproxy add v4tov4 listenport=8080 connectport=80 connectaddress=hostname.mshome.net
listenport argument correspond to the port your host system will listen on. The
connectport is the port on the VM.
You can also forward IPv6 ports if need be:
netsh interface portproxy add v6tov4 listenport=8080 connectport=80 connectaddress=hostname.mshome.net
On my system, it took a couple of minutes before the forwarding rule took effect. Make sure to also configure the Windows firewall to accept connections on the
listenport on your host.