Guest fbinotto Posted September 7, 2022 Posted September 7, 2022 Introduction Hi folks! My name is Felipe Binotto, Cloud Solution Architect, based in Australia. I decided to make this post for a couple reasons. The first reason is to demonstrate how you can quickly build a hub between your own lab and your internet devices using Azure and how easy it is. No more port forwarding in your router, public IP addresses in your VMs, everything will route through the Azure gateway, and you will get an any-to-any type of connectivity. The second reason is to demonstrate some important concepts such as: Site-to-Site VPN Point-to-Site VPN BGP Azure AD authentication for VPN Note that everything I will demonstrate here can also be done using Azure vWAN. However, this is cheaper and fit for lab and demonstration purposes. The following is the architecture overview of what we are trying to achieve. Pre-requisites The following are the prerequisites which I will not cover in this post, and you should already have them in place before you start: Azure subscription On-premises Windows Server 2016 or higher VM with 2 network cards and internet access (the 2 network cards are only required if you want to route traffic to different subnets otherwise 1 network card should do) Enable Azure AD authentication on the VPN gateway. Instructions are documented HERE. This will create a new Enterprise Application in your Azure tenant High-Level Steps The following are the high-level steps on what we will do and the order we will do it: Install required modules Connect to Azure Create a Resource Group Create VNet and subnets Create a Local Network Gateway Create a Virtual Network Gateway Create a Connection Set up the on-premises VM as a router Create a Site-to-Site interface Set up BGP Router Configure BGP Peering Start the VPN connection Download the P2S VPN configuration from Azure Create a VM for testing Demonstrate any-to-any connectivity Now we will start to look at how you can fully automate that deployment. The full script can be downloaded from HERE but I will break it down in this post, so you understand what is happening. You must run this script from your on-premises VM if you don't want to make any modifications. However, once you understand it, you should be able to split the commands and play around. Note: in the scripts I defined the Subscription Name and Tenant Id as parameters. Here I will use them as variables. Note: disable Internet Enhanced Security Configuration (IEESC) for the administrator or you will have issues when authenticating to Azure. You can do that from Server Manager or using the following function. Restart your PowerShell session after running it. function Disable-IEESC { $AdminKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\ ` Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}" Set-ItemProperty -Path $AdminKey -Name "IsInstalled" -Value 0 Stop-Process -Name Explorer } Getting Started OK, let's get started. Let's start with the basics. The following lines of code will: Install the required modules Set some variables which I will explain when we are looking at the commands which use them. You are welcome to change their values as long as you do what you’re doing. You must provide values for $subName and $tenantId Prompt you for credentials to connect to your Azure subscription # Install required modules Install-PackageProvider -Name NuGet -Force Install-Module Az.Resources,Az.Compute,Az.Network -Force -Confirm:$false # Set variables $subName = '' $tenantId = '' $rgName = 'Connectivity' $location = 'AustraliaEast' $vnetName = 'Global-Connect' $subnetName = 'IaaS' $subnetPrefix = '172.16.0.0/24' $gatewaySubnetPrefix = '172.16.255.0/27' $myPIP = (Invoke-WebRequest myexternalip.com/raw).content $vnetAddressRange = '172.16.0.0/16' $vpnAddressPool = '172.17.0.0/24' $sharedKey = 'mySuperS3cr3t123' $vmPassword = 'myC0mplexP@ssword' $localASN = 64512 $remoteASN = 65515 # Connect to Azure subscription Connect-AzAccount -Subscription $subName Next, we will start creating the foundation resources in this order: Create Resource Group Define Azure subnets Create VNet # Create Resource Group $rg = @{ Name = $rgName Location = $location } New-AzResourceGroup @rg # Define subnets $subnet1 = New-AzVirtualNetworkSubnetConfig -Name 'GatewaySubnet' ` -AddressPrefix $gatewaySubnetPrefix $subnet2 = New-AzVirtualNetworkSubnetConfig -Name $subnetName ` -AddressPrefix $subnetPrefix # Create Virtual Network $vnet = New-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName ` -Location $location -AddressPrefix $vnetAddressRange -Subnet $subnet1, $subnet2 So far so good, nothing special. Now we are going to create the Local Network Gateway. This resource represents your on-premises router configuration. Note how we are not specifying our on-premises subnets. This is because they will be known to Azure via BGP peer route exchange. # Create Local Network Gateway $localIP = (Get-NetIPAddress | Where-Object {$_.InterfaceAlias -eq 'Ethernet' ` -and $_.AddressFamily -eq 'ipv4'}).IpAddress $localGW = New-AzLocalNetworkGateway -Name HomeLab -ResourceGroupName $rgName ` -Location $location -GatewayIpAddress $myPIP -Asn $localASN ` -BgpPeeringAddress $localIP Let's break down the important parameters being used in this command: GatewayIpAddress: this is your on-premises public IP address. Notice that when we define the variables in the beginning, we are dynamically retrieving it using a HTTP request Asn: ASN stands for Autonomous System Number. This is key for BGP routing. ASNs are assigned to organisations but if you don't have one like I don't, you can use one from the private range 64512 - 65534 BgpPeeringAddress: this is your local IP address used for BGP. BGP peers exchange routing information between them via BGP sessions. We will use the IP address of your first Ethernet device. You can also use APIPA addresses. By the way, BGP stands for Border Gateway Protocol Next, we create the Virtual Network Gateway. This is the Router representation in the Azure side. # Create Virtual Network Gateway $gwpip = New-AzPublicIpAddress -Name "$vnetName-GWIP" -ResourceGroupName $rgName ` -Location $location -AllocationMethod Dynamic $vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName $subnet = Get-AzVirtualNetworkSubnetConfig -Name 'GatewaySubnet' -VirtualNetwork $vnet $gwipconfig = New-AzVirtualNetworkGatewayIpConfig -Name gwipconfig1 -SubnetId $subnet.Id ` -PublicIpAddressId $gwpip.Id $vnetGW = New-AzVirtualNetworkGateway -Name "$vnetName-GW" -ResourceGroupName $rgName ` -Location $location -IpConfigurations $gwipconfig -GatewayType Vpn -EnableBGP $true ` -VpnType RouteBased -GatewaySku VpnGw1 -Asn $remoteASN ` -VpnClientProtocol OpenVPN -VpnClientAddressPool $vpnAddressPool ` -AadTenantUri "https://login.microsoftonline.com/$tenantId" ` -AadIssuerUri "https://sts.windows.net/$tenantId/" ` -AadAudienceId '41b23e61-6c1e-4545-b367-cd054e0ed4b4' Let's focus on the creation of the Virtual Network Gateway because there is where the important bits are. The following is the breakdown of the important parameters being used in this command: GatewayType: here we are specifying this will be a Site-to-Site VPN gateway as opposed to an Express Route gateway EnableBGP: here we specify we will be using BGP VpnType: RouteBased as PolicyBased doesn't support P2S or BGP GatewaySku: you cannot use the Basic SKU as it doesn't support the OpenVPN or IKEv2 protocols for Azure AD authentication as well as BGP Asn: this is the ASN in the Azure side VpnClientProtocol: we are going to use OpenVPN as it uses TLS and can penetrate firewalls, and it is the protocol that supports most Operating Systems such as Windows, Linux, MacOS, iOS and Android VpnClientAddressPool: this is the pool of addresses that will be used by the VPN clients AadTenantUri: this is the URI which contains your tenant details Next, let's create a connection between our on-prem router and the Azure VPN gateway. Note that at this point the connection won't be established as we haven't yet configured the on-prem router. # Create Virtual Network Gateway Connection New-AzVirtualNetworkGatewayConnection -Name "$($vnetGW.Name)-$($localGW.Name)" -ResourceGroupName $rgName -Location $location -VirtualNetworkGateway1 $vnetGW -LocalNetworkGateway2 $localGW -ConnectionType IPsec -RoutingWeight 10 ` -SharedKey $sharedKey -EnableBgp $true Everything above is self-explanatory, just worth mentioning that we are enabling BGP in the connection. Now it is time to configure the local server. We first install the required Windows Features and then install site-site VPN and BGP Routing. The script sleeps for 3 seconds to allow the service to start before we run the next command. # Install the required Windows Features and Install Remote Access Install-WindowsFeature -Name RemoteAccess, Routing, RSAT, RSAT-Role-Tools, ` RSAT-RemoteAccess, RSAT-RemoteAccess-PowerShell Install-RemoteAccess -VpnType VpnS2S Start-Sleep 3 Once we have those prerequisites in place, we can create the S2S connection from the on-premises side. Remember we have already created one in Azure, and it is waiting for a connection from the other side. # Create S2S Connection $gwpip = Get-AzPublicIpAddress -Name "$vnetName-GWIP" -ResourceGroupName $rgName Add-VpnS2SInterface -Name 'Azure' $gwpip.IpAddress -Protocol IKEv2 ` -AuthenticationMethod PSKOnly -SharedSecret $sharedKey ` -IPv4Subnet @("$($vnetAddressRange):100" ,"$($vpnAddressPool):100") Let's look at the important parameters from the command above: $gwpip.IpAddress: this is the public IP address of the Azure VPN Gateway IPv4Subnet: these are the Azure subnets which will be routed through that interface Now it is time for the on-prem BGP configuration. We first created a BPG Router followed by a BGP Peer. # Create BGP Router and Peer Add-BgpRouter -BgpIdentifier $localIP -LocalASN $localASN Add-BgpPeer -Name AzureS2S -LocalIPAddress $localIP ` -PeerIPAddress $($vnetGW.BgpSettings.BgpPeeringAddress) ` -LocalASN $localASN -PeerASN $remoteASN -PeeringMode Automatic Let's look at the important parameters from the command above: BgpIdentifier: this is the local on-prem IP, the same we have configured as the BGP Peer in the Azure Local Network Gateway LocalASN: this is the on-prem ASN, the same we have configured as the BGP Peer in the Azure Local Network Gateway LocalIPAddress: this is the local on-prem IP, the same we have configured as the BGP Peer in the Azure Local Network Gateway PeerIPAddress: this is the Azure BGP Peering address which we retrieved from the Virtual Network Gateway RemoteASN: this is the Azure ASN that we set when creating the Virtual Network Gateway And finally, we can establish the connection. Connect-VpnS2SInterface -Name 'Azure' You can run the following commands to check everything is working: Get-VpnS2SInterface The output will be like the following: Get-BgpPeer The output will be like the following: Now let's deploy an Azure VM so we can test connectivity between your router and the Azure VM. # Deploy Azure VM $vmAdminUser = "LocalAdminUser" $vmSecurePassword = ConvertTo-SecureString $vmPassword -AsPlainText -Force $nic = New-AzNetworkInterface -Name 'VM01-nic' -ResourceGroupName $rgName ` -Location $location -SubnetId $vnet.Subnets[1].Id $credential = New-Object System.Management.Automation.PSCredential ` ($vmAdminUser, $vmSecurePassword) $vm = New-AzVMConfig -VMName 'VM01' -VMSize 'Standard_DS1_v2' $vm = Set-AzVMOperatingSystem -VM $vm -Windows -ComputerName 'VM01' ` -Credential $credential -ProvisionVMAgent -EnableAutoUpdate $vm = Add-AzVMNetworkInterface -VM $vm -Id $nic.Id $vm = Set-AzVMSourceImage -VM $vm -PublisherName 'MicrosoftWindowsServer' ` -Offer 'WindowsServer' -Skus '2016-Datacenter' -Version latest From the router VM you should be able to RDP to the Azure VM and vice-versa. From the router VM: From the Azure VM (make sure RDP is enabled in your router VM): Cool, S2S is working. Now we need to download and configure the Azure VPN client to test P2S using Azure Authentication. First let's download the configuration file using our current authenticated session on the server. # Downloads VPN Client Config $vpnClient = New-AzVpnClientConfiguration -ResourceGroupName Connectivity ` -ResourceName $vnetGW.Name Invoke-WebRequest -Uri $vpnClient.VpnProfileSASUrl -OutFile .\vpnclientconfig.zip Note that a ZIP file has been downloaded to the current directory. Next you need to download the Azure VPN client from HERE. Install it on a desktop, laptop or any device which is not connected to the router you have just configured. Copy and extract the ZIP file to this device. We can now configure the VPN Client as follows: And finally, you should be able to connect using your Azure AD credentials (Conditional Access and MFA will apply if applicable). You can also see you got an IP from the pool we have configured before and you got the default routes. Now from your internet VPN client device you should be able to RDP to both the Router and the Azure VM. But what if you want to route to other devices on-premises which are in different subnets? No problem. We just need to advertise the new routes and the BGP Router will let Azure know about them. In this example, I have a second network card (Ethernet 2) which routes traffic to the 10.0.2.0/24 subnet. So, we can advertise the route with the following command. # Add custom route Add-BgpCustomRoute -Interface "Ethernet 2" -Network 10.0.2.0/24 Once you reconnect the VPN, you will notice you have new routes as per below. You have the 10.0.2.0/24 route, and you also get the gateway (10.0.2.45/32) and broadcast (10.0.2.255/32) addresses. From this point you can RDP from any-to-any if you have RDP enabled. Conclusion How cool is that? I just love to be able to connect to any of my lab resources as well as my Azure resources from a single place and completely secure! Not only that, but as a bonus you get connectivity from your lab to Azure too. And it is a fully automated setup. I hope this was informative to you and thanks for reading! Disclaimer The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages. Continue reading... Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.