Using Azure RM Site to Site VPN with a Dynamic IP

By guest writer: Leon Zippel

 

In the interests of saving a bit of money, I decided to switch my ADSL service from an expensive business connection to a cheap residential connection. In Australia this also means switching from a static IP address to a dynamic IP address. With most web-based services now able to be proxied via Microsoft’s Web Application Proxy (and other services using unique ports), it seemed like everything would be fine with a combination of a Dynamic DNS service and port forwarding. I only run a development environment at home, so if I could save some money without any real impact, all the better!

 

After I made the switch, I realised that I’d forgotten about my site-to-site VPN between my development environment and Azure Resource Manager (AzureRM). For those familiar with AzureRM and Site to Site VPN, you’ll know that your on premise IP address is configured in a “Local Network Gateway” object. I thought perhaps that you could enter a DNS entry in the IP address field – no such luck.

 

So I had a look around online to see if anyone else had some easy solution I could poach. While I could find a solution for Azure Classic, the objects are completely different in AzureRM (and the powershell commands are different) – so while it gave me a direction, I couldn’t use the solution as-is. So I had a look at the available AzureRM powershell cmdlets – primarily ‘Get-AzureRmLocalNetworkGateway’ and ‘Set-AzureRmLocalNetworkGateway’.

 

The problem I came across was that ‘Set’ command really only accepts two parameters – a LocalNetworkGateway object, and AddressPrefix (for your local address spaces). No option to change the Gateway IP. The documentation didn’t give any additional information either.

 

Based on previous experience with powershell, I had assumed that the LocalNetworkGateway input object would need to refer to an existing object. As a last resort, I decided to try modify it before setting anyway – and it worked! So essentially we can do something like:

 

$LNG = Get-AzureRmLocalNetworkGateway -ResourceName <LocalNetworkGatewayName> -ResourceGroupName <ResourceGroupName>

$LNG.GatewayIpAddress = <DynamicIP>

Set-AzureRmLocalNetworkGateway -LocalNetworkGateway $LNG -AddressPrefix @('192.168.0.0/24','192.168.1.0/24')

 

Obviously this is a fair way from an automated solution that can be run on a schedule! In order to put it into a workable solution, the following overall steps need to be taken:

 

  1. Configure a dynamic DNS service (such as www.noip.com) – this will need to be automatically updated via your router or client software
  2. On the server that will be running the scheduled task, install the Azure Powershell Cmdlets (as per https://azure.microsoft.com/en-us/documentation/articles/powershell-install-configure/)
  3. Create an administrative account in Azure AD that has administrative access on the subscription (they must be listed in the Azure Classic portal under Settings > Administrators).
    1. It’s important to note that when using the ‘Login-AzureRM –Credentials’ command that the credentials used must be an ‘organisational account’ – you can’t use a Microsoft Live account (even if it’s a subscription administrator).
  4. Use some method of saving credentials for use in Powershell. I prefer to use a key-based encryption so it’s transportable between computers – a guide on doing this can be found here: http://www.adminarsenal.com/admin-arsenal-blog/secure-password-with-powershell-encrypting-credentials-part-2/
  5. Update the following values in the following script:
    1. DynDNS: the external DNS entry that resolves to your dynamic IP
    2. SubscriptionName: the name of your Azure subscription. This can be retrieved using Get-AzureRMSubscription
    3. User: the organisational administrative account
    4. PasswordFile: the file containing the encrypted password
    5. KeyFile: the file containing the encryption key (obviously you want to keep this safe – as it can be used to reverse engineer the password!)
    6. Address Prefixes on line 42.
  6. When running the script via Task Schedule, ensure you also specify the ‘Start In’ directory – otherwise you need to hard code paths in the script.
#Dynamic DNS Entry for your dynamic IP
$DynDNS = "mydynamicdomain.ddns.net"
#Azure subscription name
$SubscriptionName = "Visual Studio Premium with MSDN"

#UPN of a user account with administrative access to the subscription
$User = "azureadmin@mydomain.net"
#Password file
$PasswordFile = ".\AzurePassword.txt"
#Key file to decrypt the password
$KeyFile = ".\AzureAES.key"

Write-Host "Building Credentials"
#Grab the contents of the key
$key = Get-Content $KeyFile
$SecurePassword = Get-Content $PasswordFile | ConvertTo-SecureString -Key $key
#Build the credential object
$Creds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $SecurePassword

#Get the Current Dynamic IP
[string]$DynIP = ([System.Net.DNS]::GetHostAddresses($DynDNS)).IPAddressToString
Write-Host "Current Dynamic IP:" $DynIP

#Log into the Azure Tenant
Login-AzureRmAccount -Credential $Creds
#Select the subscription
Select-AzureRmSubscription -SubscriptionName $SubscriptionName
#Grab the current LocalNetworkGateway
$LNG = Get-AzureRmLocalNetworkGateway -ResourceName Local_Network_Gateway -ResourceGroupName RG_AU_SE
#Output the IP to view
Write-Host "Current LocalNetworkGateway IP:" $LNG.GatewayIPAddress
Write-Host "Current Dynamic IP:" $DynIP

#Determine if we need to change it
If($DynIP -ne $LNG.GatewayIpAddress)
    {
    Write-Host "Dynamic IP is different to LocalNetworkGateway IP - Updating..."
    #Update the IP in the LNG Object
    $LNG.GatewayIpAddress =$DynIP
    #Update the LNG Object in Azure. AddressPrefix is required.
    Set-AzureRmLocalNetworkGateway -LocalNetworkGateway $LNG -AddressPrefix @('192.168.0.0/24','192.168.1.0/24')
    }
else
    {
    Write-Host "No changes required"
    }