Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnathanmay/161a8b8ebd36e3f19aefab77418e345e to your computer and use it in GitHub Desktop.
Save johnathanmay/161a8b8ebd36e3f19aefab77418e345e to your computer and use it in GitHub Desktop.

How To Create Stable Private Network On Hyper-V

If you find yourself stuck in a situation where you have to use Hyper-V and you hate how it doesn't come with the ability to keep the same static IP range for your private VLAN after a reboot, this gist might be for you. It shows the powershell commands to create a new private VLAN, configure it to NAT all outbound traffic, and assign the interface a static IP that doesn't change when your computer reboots. It also shows how to create and configure a very simple VM running dnsmasq that will always start at boot and handle all your DHCP needs on the private interface.

The example below uses the 172.26.48.0/22 subnet. Please be sure to update the code as needed to reflect whatever subnet you want to use.

Create Private Network

New-VMSwitch -SwitchName "internal-172.26.48.0-22" -SwitchType Internal -Verbose
$new_adapter = Get-NetAdapter -Name "vEthernet (internal-172.26.48.0-22)"
$if_index = $new_adapter.ifIndex
New-NetIPAddress -IPAddress 172.26.51.254 -PrefixLength 22 -InterfaceIndex $if_index -Verbose
New-NetNat -Name net-internal-172.26.48.0-22 -InternalIPInterfaceAddressPrefix 172.26.48.0/22 -Verbose

If you want to remove this private network, just run this:

Remove-NetNat -Name net-internal-172.26.48.0-22

Create dnsmasq VM

This gist assumes you know how to download the Ubuntu 20.04 Server LTS ISO and that you have your hyper-v disks located in c:\hyper-v. The SwitchName parameter needs to match the name of the new private network you just created. There are simpler configs but this one sets the latest features and allows all the security bells and whistles which is why I set it up this way.

New-VM -Name dnsmasq -NewVHDPath c:\hyper-v\disks\dnsmasq.vhdx -NewVHDSizeBytes 32GB -MemoryStartupBytes 1GB -SwitchName "internal-172.26.48.0-22" -Generation 2
Add-VMDvdDrive -VMName dnsmasq -Path c:\hyper-v\disks\ubuntu-20.04.3-live-server-amd64.iso
Set-VMProcessor -VMName dnsmasq -Count 2
Set-VMFirmware -VMName dnsmasq -EnableSecureBoot On -SecureBootTemplate "MicrosoftUEFICertificateAuthority"
Set-VMKeyProtector -VMName dnsmasq -NewLocalKeyProtector
Enable-VMTPM -VMName dnsmasq
Set-VMSecurity -VMName dnsmasq -EncryptStateAndVmMigrationTraffic $true
Set-VM dnsmasq -AutomaticStartAction Start -AutomaticStartDelay 30

You'll need to either change the boot order manually, or look at the current boot order and update it to boot from the network last, modifying the following code as needed:

$vm_firmware = Get-VMFirmware dnsmasq
$dvd = $vm_firmware.BootOrder[2]
$hd = $vm_firmware.BootOrder[1]
$net = $vm_firmware.BootOrder[0]
Set-VMFirmware -VMName dnsmasq -BootOrder $hd, $dvd, $net

Then go through the server installation, following all the prompts, and don't install anything extra except for the openssh-server option if prompted. Assign it a static IP when it comes to the network configuration portion. To match the dnsmasq configuration below, set it to 172.26.51.253/22.

Configure dnsmasq

After installing Ubuntu, get logged in and remove the default systemd-resolved daemon so that dnsmasq can cleanly take its place.

sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
sudo rm /etc/resolv.conf
echo nameserver 8.8.8.8 | sudo tee /etc/resolv.conf

The example below assigns specific MAC addresses to specific IPs. Be sure to update the IPs and MAC addresses and any other DHCP options below with ones that work for your environment.

sudo -s
apt install dnsmasq -y
sed -i s/^#no-resolv/no-resolv/ /etc/dnsmasq.conf
sed -i '/^#server=\/localnet/a server=8.8.8.8' /etc/dnsmasq.conf
sed -i '/^#dhcp-range=192.168.0.50/a dhcp-range=172.26.49.1,172.26.49.254,255.255.252.0,12h' /etc/dnsmasq.conf
sed -i '/^#dhcp-option=3,1.2.3.4/a dhcp-option=3,172.26.51.254' /etc/dnsmasq.conf
sed -i '/^dhcp-option=3,172.26.51.254/a dhcp-option=6,172.26.51.253' /etc/dnsmasq.conf
sed -i '/^dhcp-option=6,172.26.51.253/a dhcp-option=15,corp.example.com' /etc/dnsmasq.conf
sed -i '/^#dhcp-option=option:domain-search,eng/a dhcp-option=option:domain-search,corp.example.com' /etc/dnsmasq.conf
echo "dhcp-host=00:15:5d:7b:2c:0a,172.26.48.6
dhcp-host=00:15:5d:7b:2c:0d,172.26.48.5" | sudo tee -a /etc/dnsmasq.conf
sudo systemctl restart dnsmasq
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment