Building an Azure lab – Implementing S2S (Site-to-Site) VPN – Part 2: Multi Virtual Networks


In Part 1 of this series I created a Site-to-Site VPN setup for my Azure MSDN subscription to my local network. This will be a base for this post.

This part will cover the basics to add another Virtual Network into the mix, based on a different location and different Subscription.

The result will look like this:
site-to-site

By completing Part 1 we have this:
site-to-site-subA

I showed how to do this using the Azure Portal and I showed how to do this using PowerShell.

I will use that same PowerShell script to create the resources needed to connect the second subscription’s Virtual Network to my on-premises network. If you want to do that using the Azure Portal follow the steps in Part 1 again, substituting names and settings as you go.
Here’s the PowerShell script I used to setup my second subscription:

Login-AzureRmAccount

# If you have multiple subscriptions on your account run the following command:
# Get-AzureRmSubscription
# It will output all your subscriptions. Find the name of the subscription you
# want to use and run the following command:
# Select-AzureRmSubscription -SubscriptionName "Replace_with_your_subscription_name"

# Setting variables
$location               = "East US"
$resourceGroupName      = "it-worxx.azure.site.2"

$virtualNetworkName     = "it-worxx.azure.site.2.network"
$virtualNetworkRange    = "10.20.0.0/16"
$virtualNetworkDNS      = @("192.168.2.4")

$subnetName             = "it-worxx.azure.site.2.production"
$subnetAddressRange     = "10.20.0"
$gatewayAddressRange    = "10.20.255"

$localGatewayName       = "it-worxx.local.gateway"
$localGatewayIPaddress  = "77.x.x.14"
$localNetworkRange      = @("192.168.2.0/24")

$gatewayIpName          = "it-worxx.azure.site.2.gateway.ip"
$gatewayName            = "it-worxx.azure.site.2.gateway"

$connectionName         = "it-worxx.azure.site.2.S2S.it-worxx.local"
$sharedKey              = "SuperSecretSharedKey123!"

# Create the Resource Group
New-AzureRmResourceGroup -Name $resourceGroupName -Location $location

# Define the subnets and create the Virtual network
$subnet1 = New-AzureRmVirtualNetworkSubnetConfig -Name $subnetName -AddressPrefix "$($subnetAddressRange).0/24"
$subnet2 = New-AzureRmVirtualNetworkSubnetConfig -Name 'GatewaySubnet' -AddressPrefix "$($gatewayAddressRange).0/24"
$virtualNetwork = New-AzureRmVirtualNetwork -Name $virtualNetworkName -ResourceGroupName $resourceGroupName -Location $location -AddressPrefix $virtualNetworkRange -Subnet $subnet1, $subnet2
if($virtualNetworkDNS){ $virtualNetwork.DhcpOptions.DnsServers = $virtualNetworkDNS
	Set-AzureRmVirtualNetwork -VirtualNetwork $virtualNetwork
}

# Create the Local Network Gateway
$gatewayLocal = New-AzureRmLocalNetworkGateway -Name $localGatewayName -ResourceGroupName $resourceGroupName -Location $location -GatewayIpAddress $localGatewayIPaddress -AddressPrefix $localNetworkRange

# Create the Public IP Address
$azureGatewayIpAddress = New-AzureRmPublicIpAddress -Name $gatewayIpName -ResourceGroupName $resourceGroupName -Location $location -AllocationMethod Dynamic

# Define properties for and create the Virtual Network Gateway
$gatewaySubnet = Get-AzureRmVirtualNetworkSubnetConfig -Name 'GatewaySubnet' -VirtualNetwork $virtualNetwork
$gatewayIpConfig = New-AzureRmVirtualNetworkGatewayIpConfig -Name gwipconfig -SubnetId $gatewaySubnet.Id -PublicIpAddressId $azureGatewayIpAddress.Id
$gatewayAzure = New-AzureRmVirtualNetworkGateway -Name $gatewayName -ResourceGroupName $resourceGroupName -Location $location -IpConfigurations $gatewayIpConfig -GatewayType Vpn -VpnType RouteBased -GatewaySku Basic
$azureGatewayIpAddress = Get-AzureRmPublicIpAddress -Name $gatewayIpName -ResourceGroupName $resourceGroupName

# Create the Connection
New-AzureRmVirtualNetworkGatewayConnection -Name $connectionName -ResourceGroupName $resourceGroupName -Location $location -VirtualNetworkGateway1 $gatewayAzure -LocalNetworkGateway2 $gatewayLocal -ConnectionType IPsec -RoutingWeight 10 -SharedKey $sharedKey

# Output values needed for on-premises Gateway configuration
Write-Host "Azure Gateway IP Address  :            $($azureGatewayIpAddress.IpAddress)"
Write-Host "Azure Gateway SharedSecret:            $sharedKey"
Write-Host "Azure Virtual Network address space:   $virtualNetworkRange"

As with the first Site-to-Site VPN, this scripts takes about 30 to 45 minutes to complete.
After that on the RRAS server:

# Setting variables
$rrasInterfaceName      = "it-worxx.local.S2S.it-worxx.azure.site.2"
$azureGatewayIpAddress  = "52.x.x.20"
$virtualNetworkRange    = "10.20.0.0/16"
$sharedKey              = "SuperSecretSharedKey123!"

Function Invoke-WindowsApi(
    [string] $dllName,
    [Type] $returnType,
    [string] $methodName,
    [Type[]] $parameterTypes,
    [Object[]] $parameters
    )
{
  ## Begin to build the dynamic assembly
  $domain = [AppDomain]::CurrentDomain
  $name = New-Object Reflection.AssemblyName 'PInvokeAssembly'
  $assembly = $domain.DefineDynamicAssembly($name, 'Run')
  $module = $assembly.DefineDynamicModule('PInvokeModule')
  $type = $module.DefineType('PInvokeType', "Public,BeforeFieldInit") 

  $inputParameters = @() 

  for($counter = 1; $counter -le $parameterTypes.Length; $counter++)
  {
     $inputParameters += $parameters[$counter - 1]
  } 

  $method = $type.DefineMethod($methodName, 'Public,HideBySig,Static,PinvokeImpl',$returnType, $parameterTypes) 

  ## Apply the P/Invoke constructor
  $ctor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([string])
  $attr = New-Object Reflection.Emit.CustomAttributeBuilder $ctor, $dllName
  $method.SetCustomAttribute($attr) 

  ## Create the temporary type, and invoke the method.
  $realType = $type.CreateType() 

  $ret = $realType.InvokeMember($methodName, 'Public,Static,InvokeMethod', $null, $null, $inputParameters) 

  return $ret
}

Function Set-PrivateProfileString(
    $file,
    $category,
    $key,
    $value)
{
  ## Prepare the parameter types and parameter values for the Invoke-WindowsApi script
  $parameterTypes = [string], [string], [string], [string]
  $parameters = [string] $category, [string] $key, [string] $value, [string] $file 

  ## Invoke the API
  [void] (Invoke-WindowsApi "kernel32.dll" ([UInt32]) "WritePrivateProfileString" $parameterTypes $parameters)
}

# Add and configure S2S VPN interface for VNet1
Add-VpnS2SInterface -Protocol IKEv2 -AuthenticationMethod PSKOnly -ResponderAuthenticationMethod PSKOnly `
 -Name $rrasInterfaceName -Destination $azureGatewayIpAddress -IPv4Subnet @("$($virtualNetworkRange):256")`
 -NumberOfTries 3 -SharedSecret $sharedKey

Set-VpnServerIPsecConfiguration -EncryptionType MaximumEncryption
# default value for Windows 2012 is 100MB, which is way too small. Increase it to 32GB.
Set-VpnServerIPsecConfiguration -SADataSizeForRenegotiationKilobytes 33553408

New-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\RemoteAccess\Parameters\IKEV2 -Name SkipConfigPayload -PropertyType DWord -Value 1 -Force

# Set S2S VPN connections to be persistent by editing the router.pbk file (required admin priveleges)note that the IdelDisconnectSeconds and RedialOnLinkFailure are set for reach adaptors.
Set-PrivateProfileString $env:windir\System32\ras\router.pbk "$($rrasInterfaceName)" "IdleDisconnectSeconds" "0"
Set-PrivateProfileString $env:windir\System32\ras\router.pbk "$($rrasInterfaceName)" "RedialOnLinkFailure" "1"

# Restart the RRAS service
Restart-Service RemoteAccess

Et voila, Site-to-Site VPN from on-premises network to Virtual Networks in two subscriptions:
site-to-site-basic

To test the connections I’ve setup two VMs.
Subscription A now has a VM in the subnet “it-worxx.azure.site.1.production” with IP address 10.10.0.4 called ITWS110.
Subscription B now has a VM in the subnet “it-worxx.azure.site.2.production” with IP address 10.20.0.4 called ITWS220.

Pinging the servers from the RRAS server on-premises:
2gw-01

Success!

But what about connectivity from Subscription A to Subscription B?
From 10.10.0.4 pinging an on-premises VM and pinging a VM in Subscription B:
2gw-02

I can reach a server on my on-premises network, but I can’t reach a server in Subscription B. This is by design. The Gateway in Subscription A knows the routes to the on-premises network, but not to the next hop

For fun repeatedly ping ITWS220:2gw-02a

I want to have a connection between the Virtual Network in Subscription A, and the Virtual Network in Subscription B.
I want the end result to look like this:

site-to-site

I’ll start with Subscription A. I’ll assume all resources will be created in the previously created Resource Group and its location.

Navigate to the Resource Group and click Add. Search for Local Network Gateway, and click Local Network Gateway. Click Create.

2gw-03
Name it after the site you are connecting to, enter the Public IP Address for the VPN Gateway in the Virtual Network for Subscription B, and add that network’s address space. Click Create.
NB: It seems kind of odd to need to add the Virtual Network in Subscription B as a Local Network Gateway, but basically to the Azure VPN Gateway the Virtual Network in Subscription B is no different from the on-premises network.

Navigate to the Resource Group and click Add. Search for Local Network Gateway, and click Local Network Gateway. Click Create.

2gw-04
Select Site-to-Site (IPsec), click OK.

2gw-05
Select Subscription A’s Virtual network gateway, the Local network gateway to Subscription B that was just created, name the connection, and define a Shared key. Click OK.

Review the Summary and click OK.

If you want to create the new resources using PowerShell, use the following script:

Login-AzureRmAccount

# If you have multiple subscriptions on your account run the following command:
# Get-AzureRmSubscription
# It will output all your subscriptions. Find the name of the subscription you
# want to use and run the following command:
# Select-AzureRmSubscription -SubscriptionName "Replace_with_your_subscription_name"

# Setting variables
$resourceGroupName      = "it-worxx.azure.site.1"

$localGatewayName       = "it-worxx.azure.site.2.gateway"
$localGatewayIPaddress  = "52.x.x.20"
$localNetworkRange      = @("10.20.0.0/16")

$gatewayName            = "it-worxx.azure.site.1.gateway"

$connectionName         = "it-worxx.azure.site.1.S2S.it-worxx.azure.site.2"
$sharedKey              = "SuperSecretSharedKey123!"

# Create the Local Network Gateway
$gatewayLocal = New-AzureRmLocalNetworkGateway -Name $localGatewayName -ResourceGroupName $resourceGroupName -Location (Get-AzureRmResourceGroup -Name $resourceGroupName).Location -GatewayIpAddress $localGatewayIPaddress -AddressPrefix $localNetworkRange

# Create the Connection
New-AzureRmVirtualNetworkGatewayConnection -Name $connectionName -ResourceGroupName $resourceGroupName -Location (Get-AzureRmResourceGroup -Name $resourceGroupName).Location -VirtualNetworkGateway1 (Get-AzureRmVirtualNetworkGateway -Name $gatewayName -ResourceGroupName $resourceGroupName) -LocalNetworkGateway2 $gatewayLocal -ConnectionType IPsec -RoutingWeight 10 -SharedKey $sharedKey

Repeat the creation of the Local Network Gateway and the connection for Subscription B.

As soon as the Connection is created in Subscription B you’ll see the connection is up by checking ITWS110 again:
2gw-06

And there you have it.

Site-to-Site connections set up between two Virtual Networks in different regions, in different Azure Subscriptions, and each Virtual Network connected using Site-to-Site VPN to an on-premises network using Microsoft Windows Server RAS.

Until next time,

 

Arjan Mensch

Advertisements

25+ years experience in Microsoft powered environments. Enjoy automating stuff using powershell. In my free time (hah! as if there is any) I used to hunt achievements and gamerscore on anything Xbox Live enabled (Windows Mobile, Windows 8, Windows 10, Xbox 360 and Xbox One). Recently I picked up my Lego addiction again.

Tagged with: , , , ,
Posted in Azure, RRAS, Step-by-Step guide

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog Authors
https://paypal.me/ArjanMensch
BTC:1AiAL6QDbfNPiduYYEoy3iNS2m6UKJW2He
LTC:Lf52uAJiCRQtiegJyKqVvoh4FuvwMkHPae
ETH:0x096a12424e991696ad21cfc0e0f3749ab4f8ce1b
DSH:XnRGpf2v36F5iDT5uFaq7DsHPFF435EPmT
XMR:49UCmvAYNxB3voEVbfL8KDENwcg9SE9PeY5jU8YCaHMuLXHapRmfhgHWbwaVe4vUMveKAzAiA4j8xgUi29TpKXpm3xumqCq

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 401 other followers

Blog Stats
  • 2,819,970 hits
%d bloggers like this: