How to use SNAT (Source Network Address Translation) for outbound Windows Virtual Desktop connections

During the lifecycle of your Windows Virtual Desktop environment, you might encounter the following issues.

The issue

  • Users not being able to browse certain websites
  • Random WVD hosts not being able to connect to specific 3rd party hosted web apps

Normal behavior

Since there is no physical network hardware layer you can troubleshoot, one of the rather obvious cases which are often overlooked is SNAT (Source Network Address Translation). In a traditional on-premises environment you would have a reverse proxy or other networking equipment in place that would translate all of your internal workspace IP Addresses to a single public IP address.

Root cause

Windows Virtual Desktop is an Azure Native solution built on IaaS. Virtual Machines running on Azure have direct internet connectivity by using the Azure backplane. Just like Microsoft 365 a wide range of public IP addresses and ports is used to connect to online services.

This wide range of public IP addresses might just be the reason for the previously mentioned issues.

The solution: Configuring SNAT on your Windows Virtual Desktop Host Pool

What is SNAT? The following Microsoft Docs site explains more in detail all of the possible options & configurations for SNAT.
In our use case, we want to use SNAT to masquerade our back-end WVD Host IP Addresses to a single Public IP address.

What is required? We need a Standard Public Azure Loadbalancer configured on top of our WVD hosts and a SNAT rule configured to allow outbound connections.

Deploying the solution

Let’s get started with deploying the new load balancer and assigning the SNAT rules to the WVD hosts.

Powershell Script

You can run the powershell script provided below or review it on my GitHub Repo.

#region clear variables & in memory parameters
$slb = $null
$vm = $null
$NI = $null
$natrules = $null
$NIConfig = $null
$ELBPurpose =  $null
$ELBlocation = $null
$SKU =  $null
#endregion

#region input variables
$ELBPurpose = "enter the purpose of your loadbalancer (ex. wvd)"
$ELBlocation = "enter the location of your loadbalancer (ex. westeurope)"
$SKU = "enter the SKU of your loadbalancer (ex. standard)"
$ELBResourceGroup =  "enter the resource group name of your loadbalancer (ex. prd-network-rg)"
#endregion

#region naming convention
$ELBconvention = "-elb"
$PIPconvention = "-pip"
$FrontEndConvention = "-fep"
$BackEndConvention = "-bep"
$OutboundRuleConvention = "-obr"

$ELBname = $ELBPurpose + $ELBconvention
$ELBpip = $ELBname + $PIPconvention
$ELBFrontEndName = $ELBname + $FrontEndConvention
$ELDBackEndPoolName = $ELBname + $BackEndConvention
$ELBOutboundRulename = $ELBname + $OutboundRuleConvention
#endregion

#region loadbalancer deployment

# Step 1: Create a new static public IP address
$publicip = New-AzPublicIpAddress -ResourceGroupName $ELBResourceGroup -name $ELBpip -Location $ELBlocation -AllocationMethod Static -Sku $SKU

# Step 2: Create a new front end pool configuration and assign the public IP
$frontend = New-AzLoadBalancerFrontendIpConfig -Name $ELBFrontEndName -PublicIpAddress $publicip

# Step 3: Create a new back end pool configuration
$backendAddressPool = New-AzLoadBalancerBackendAddressPoolConfig -Name $ELDBackEndPoolName


# Step 4: Create the actual load balancer
$slb = New-AzLoadBalancer -Name $ELBname -ResourceGroupName $ELBResourceGroup -Location $ELBlocation -FrontendIpConfiguration $frontend -BackendAddressPool $backendAddressPool -Sku $SKU

# Step 5: Assign the back end VMs to the loadbalancer
$VMs = Get-AzVM | Out-GridView -PassThru -Title "Select your WVD hosts"

foreach ($vm in $VMs) {
    $NI = Get-AzNetworkInterface | Where-Object { $_.name -like "*$($VM.name)*" }
    $NI.IpConfigurations[0].Subnet.Id
    $bep = Get-AzLoadBalancerBackendAddressPoolConfig -Name $ELDBackEndPoolName -LoadBalancer $slb
    $NI.IpConfigurations[0].LoadBalancerBackendAddressPools = $bep
    $NI | Set-AzNetworkInterface
}

# Step 6: Assign the outbound SNAT rules
$myelb = Get-AzLoadBalancer -Name $slb.Name
$myelb | Add-AzLoadBalancerOutboundRuleConfig -Name $ELBOutboundRulename -FrontendIpConfiguration $frontend -BackendAddressPool $backendAddressPool -Protocol "All"

# Step 7: Configure the loadbalancer
$myelb | Set-AzLoadBalancer

#endregion

The end result will look similar to below screenshots.

Warning!

The scripts are provided as-is, please be very careful and test run the scripts on a “test” environment or an environment that allows you to perform some quick checks and tests. Adding a standard load balancer with no SNAT rules can cause internet connectivity loss for Windows Virtual Desktop users.

Thank you!

Thank you for reading through this blog post, I hope I have been able to assist in adding SNAT rules to WVD.

If you encounter any new insights, feel free to drop me a comment or contact me via mail or other social media channels

1 Comment on “How to use SNAT (Source Network Address Translation) for outbound Windows Virtual Desktop connections

Leave a Reply

Your email address will not be published. Required fields are marked *

Please reload

Please Wait