[Updated 03/05/2016: New-ContainerNetwork at the end of this post]
In Windows Server 2016 Technical Preview 4 and Windows 10 build #1058, Microsoft included a new Virtual Switch Type called Network Address Translation (NAT), which allows Virtual Machines to have an Internal Network and connect to the physical world and have Internet access. The NAT mode was basically built for Windows Server Containers and Hyper-V Containers, because Windows containers function similarly to virtual machines in regards to networking. Each container has a virtual network adapter which is connected to a virtual switch, over which inbound and outbound traffic is forwarded.
This feature is so convenient to give Internet access to virtual machines without bridging the Wi-Fi adapters or using RRAS / Linux server.
This feature was not exposed in the UI, you need to use PowerShell to create the “NAT” Virtual Switch type.
In Windows Server 2016 Technical Preview 5 and the latest Windows 10 build #14295, Microsoft removed “NAT” VM Switch Type… It’s gone!
However, the good news is, the NAT networks can still be created and customized using PowerShell cmdlets but in different way.
Network Address Translation Overview
Each virtual machine is connected to an internal virtual switch and will use WinNAT to connect to a private IP subnet. WinNAT gives a virtual machine access to network resources using the host computer’s IP address and a port. WinNAT will perform both network address translation (NAT) and port address translation (PAT) between the container / Hyper-V host and the containers / virtual machines themselves.
This feature is not included in the UI of course, but you can use PowerShell to create the “NAT” internal Virtual Switch.
Step 1 – Create internal virtual switch
New-VMSwitch –SwitchName “NAT_vSwitch” –SwitchType Internal –Verbose
Step 2 – Configure NAT gateway
In order to configure a NAT gateway using New-NetIPAddress, you’ll need a bit of information about your network, you would use the following syntax. Notice that additional parameters including IPAddress, PrefixLength and InterfaceIndex can be specified by using PowerShell.
New-NetIPAddress –IPAddress 172.31.1.1 -PrefixLength 24 -InterfaceIndex 16 –Verbose
- IPAddress: IPv4 or IPv6 address to use as the NAT gateway IP which will be assigned to the (vEthernet) internal switch.
- PrefixLength: Is a subnet mask, the range will be a value from 0 up to 32. You want to define a Subnet Mask to be used by the NAT internal switch.
- InterfaceIndex: Is the interface index of the internal switch that we created in Step 1. You can use Get-NetAdapter to determine the ifIndex number. In my case here, the Interface Index is 16.
Step 3 – Configure NAT Network
In order to configure a NAT network using New-NetNat, you’ll need also a bit of information about your network and the NAT gateway we configured in Step 2. you would use the following syntax. Notice that additional parameters including Name and InternalIPInterfaceAddressPrefix.
New-NetNat –Name NATNetwork –InternalIPInterfaceAddressPrefix 172.31.1.0/24 –Verbose
- Name: This is the name of the NAT network. If you want to remove the NAT network in the future, you need to use Remove-NetNAT –Name <NAT Network Name>.
- InternalIPInterfaceAddressPrefix: This is the NAT subnet network describes for both the NAT Gateway IP prefix and the NAT Subnet mask from Step 2 . In my case here, the NAT subnet network is (172.31.1.0) and the subnet mask is (24) which is 255.255.255.0.
Step 4 – Connect your virtual machine to the internal “NAT” network switch
You need to connect the internal “NAT” switch you created in Step 1 to your virtual machine using the VM Settings or using PowerShell.
Get-VM | Get-VMNetworkAdapter | Connect-VMNetworkAdapter –SwitchName “NAT_vSwitch”
In the final step, you need to set manually or through DHCP an IP Address (and default GW) to the virtual machine on the same NAT subnet, in my case here it’s (172.31.1.0/24 ) and default gateway (172.31.1.1).
Here you go… Your virtual machines are now communicating to the external world
Note: At the time of this writing, Hyper-V only allows you to create one NAT network.
The New-ContainerNetwork cmdlet could also be used to connect VMs to a NAT network if you installed the Container feature on the Hyper-V host, but it should be used with caution, because the cmdlet was designed for Windows Server Containers and instructs the host network service to allocate IPs to containers from the NAT network range. You would have to manually assign IP and default gateway to the VM and make sure the IP address isn’t already assigned to a Container. Please note, the host network service won’t know that you have assigned an IP from this range to a VM and so may try and re-assign the same IP to a container in the future, thus you will end-up by having a network conflict. The recommended way is to use the method described in this post.
Many Thanks to Jason Messer (Microsoft PM on the SDN Team) for the information.