How to connect your Amazon Web Services (AWS) and Microsoft Azure Virtual Private Networks (VPN)
By: Spiros Dimopoulos
Tags: Machine Learning, AWS, Azure, VPN, Ipsec

Introduction

Let’s say that you have spent the last 2 years developing your enterprise services in either of the two cloud providers and now you decide to start using the other one. A possible scenario that would bring about such a requirement would be a migration from one cloud service provided to the other. Or maybe you’ve heard about that brand new AWS or Azure service that is not available in the competing provider and you want to integrate it into your workflow no matter what. Another scenario could be if you would like to combine services between the providers, but still keep everything behind your well protected and highly secure private network gateway. For all of the above cases, you should consider establishing a secure link between your two private networks. There is a variety of options available to achieve that, but probably the most straightforward is to connect your AWS VPC with the Azure Virtual Network using a VPN Gateway and site-to-site connectivity.

Underlying infrastructure

This guide assumes that you have already setup correctly the following resources in the cloud providers:

AWS VPC with a public and private subnet (default configuration) Azure Virtual Network Azure Virtual Network Gateway

If you haven’t yet created any of the previous resources, you may use the service provider’s documentation guides to do that.

For AWS VPC use this: https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html#Create-VPC

For Azure Virtual Network and VPN Gateway use this: https://docs.microsoft.com/en-us/azure/vpn-gateway/create-routebased-vpn-gateway-portal

Note down the IP address range for each one of your cloud networks, you will need it later when setting up the routing table.

You can find AWS VPC network range if you open the VPC service under the Networking & Content Delivery category. Then from “Your VPCs” you can check the IPv4 CIDR column in screen 1. In our depicted example you can see that the IP range is 10.101.0.0/16

Screen 1: AWS VPC IPv4 CIDR

For Azure Virtual Network, you can find the address range if you open Azure Services | Virtual Networks and then you select the Virtual Network that you want to connect to AWS. Then you can review the address range as shown in screen 2. We’ve set the range 10.0.0.0/16

Screen 2: Azure Virtual Network IPv4 address space

It is important not to have overlapping addresses between the two cloud networks or else the routing won’t work properly. So now it is high time to change any of the network ranges if needed. You need to ensure that there aren’t any overlapping ranges. In our example the AWS network uses the address 10.101.0.0–10.101.255.255 and the Azure network uses 10.0.0.0–10.0.255.255, so we are good to go.

AWS Configuration

If your AWS VPC was created using best-practices, it ought to have at least 2 different subnets, the private and the public. Any EC2 instance that resides in the private subnet is cut off from the Internet and is only accessible from inside the Virtual Network (note that you can attach a NAT gateway to your private subnet in order to allow outgoing traffic, but is not something to discuss now). In contrast, any EC2 instance inside the public subnet has Internet access through an Internet gateway. Public IPs can be assigned to instances in the public subnet, so these instances can communicate with the outside world. In our example in screen 3, you can see that our VPC has one public subnet and two private subnets that lie in different availability zones. You can also see the routing table of the public subnet. The default route sends all traffic that does not belong to the private network to the Internet gateway. (Notice that there is also a route that bridges two AWS VPCs together, but this is not relevant to our task).

Screen 3: AWS VPC subnets and routing table

You need to create one Linux-based instance with a public IP assignment in your public subnet. It will be used as a Gateway in our VPN Site to Site connection between AWS and Azure. You can give it a public IP either at creation time or associate it with an elastic IP. The former method has a drawback; if you ever need to restart the instance it will get a new public IP assignment, so you’ll have to reconfigure everything. So, it is strongly advised to use the latter method: associate a fixed elastic IP with the instance. If you don’t know how to do it, the following guide can be of help https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html

The instance will be accessible from the Internet, as it will have a public IP, and also will have access to your VPC, so make sure that you have secured it accordingly. Don’t forget to deny access to SSH, VNC or any other possible vulnerable service for connections that have source IP addresses that do not belong to your private network. You can do this by utilising a suitable security group for this purpose (more info about security groups is available here: https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html).

Having created the EC2 in a public subnet, go ahead and modify the routing table of the private subnet. Add a route towards the Azure Virtual Network via the recently created Public IP instance that will run the VPN connection on the AWS side. In our example, all destinations in the IP range 10.0.0.0/16 are routed through the instance network interface as shown in screen 4.

Screen 4: AWS to Azure routing

AWS EC2 Instances have enabled source/destination checks by default in the networking settings. So, it’s not possible to relay any network traffic that does not have either the source or the destination set to the instance address. This means that you won’t be able to use the EC2 instance to establish a tunnel between the AWS and Azure Virtual Network unless you disable the checks. You can do this by selecting the EC2 instance in the AWS Web Console EC2 Tab and then from Actions | Networking | Change Source/Destination Checks and disable it as shown in screen 5.

Now open a remote terminal in you EC2 instance with SSH.

Screen 5: Disable Source/Destination Check in AWS

Azure Configuration

It is assumed you have already created a Virtual Network and a VPN gateway in Azure cloud. If you haven’t done it already, check the following guide https://docs.microsoft.com/en-us/azure/vpn-gateway/create-routebased-vpn-gateway-portal.

Next from Azure portal we proceed with the configuration of the site-to-site VPN connection. In the Virtual Network Gateways service, first select the Virtual Network that you plan to connect, then go to Settings | Connections and Add a new connection as shown in screen 6.

Screen 6: Add new site to site VPN connection from Azure Virtual Network to AWS VPC

In the pop-up window you can set various parameters of the network tunnel. The connection type must be set to Site-to-Site (IPSec). The Virtual Network Gateway is usually pre-selected for you, but you can verify it is associated with the network that you want to connect to. A Shared key (PSK) must be set that will be shared with the other end on the AWS. Make sure you note down the key and have it handy for the final part of this guide where we set up the VPN on AWS. Also make sure the protocol is set to IKEv2. All configuration settings described above can be seen in screen 7.

Screen 7: Azure to AWS Site to Site connection configuration

Next, you need to set the local network gateway for the connection. It is essentially the corresponding configuration that will point to the AWS network. When you click the Local network gateway (Choose a local network gateway), an additional window opens as in screen 8. You can add a name for the connection in there, fill in the IP address of the AWS gateway and finally the address space of the AWS VPC that you want to connect to. The name can be anything that is accepted by Azure. The IP address has to be the public IP address of the AWS instance created in the previous section. Do you remember that you also had to note down the AWS VPC address range? Now it’s time to enter it here to let Azure know the range of addresses used on the remote Virtual Network.

Screen 8: Set remote AWS gateway and subnet in Azure

Lastly, you are almost ready to save everything and close, but before doing that note down the public IP given to the Azure VPN gateway. You are all set on the Azure side. Now you will need to log in to the AWS instance to set up the VPN connection on the AWS side.

IPSec Configuration on AWS Gateway

There are various implementations of the IPSec VPN protocol out there, but in this guide we will use Libreswan (https://libreswan.org) “a free software implementation of the most widely supported and standardized VPN protocol using IPsec and the Internet Key Exchange (IKE)”. There are binary packages of Libreswan for all major Linux distributions, meaning that you won’t need much effort to install it in the AWS EC2 instance we created in the “AWS Configuration” part of this guide.

Before that, you need to go back for a moment to your AWS web console and add an exception to the network security group that is associated with the instance. Make sure that you open UDP ports 500 and 4500 to connections originating from the public IP of the Azure VPN Gateway as shown in screen 9.

Screen 9: Allow incoming VPN from Azure to AWS

Now open a remote terminal on the EC2 instance using SSH and install Libreswan using the package manager.

Let’s start editing some configuration files in the instance itself. One important step is to change the default IPv4 linux kernel behaviour of IP packet forwarding. Usually linux will not allow packet forwarding, but we want the EC2 instance to act as a gateway for the whole AWS Virtual Network, so edit the file /etc/sysctl.conf and uncomment the line net.ipv4.ip_forward=1. To enable this change without restarting the machine, enter the following command run sysctl -p.

Next step is to configure the IPSec files that will establish the VPN connection to Azure Gateway and activate the site to site network. The following snippet is the default configuration file /etc/ipsec.conf usually distributed with the Libreswan package of ubuntu.

Default ipsec.conf file

In the last line it includes any configuration file that’s found under /etc/ipsec.d/ directory and has the extension .conf. Let’s add a new file in path /etc/ipsec.d/azure.conf with the following content

Azure configuration for ipsec

Let me talk you through some important configuration parameters of this file:

authby: This parameter sets the authentication method between the two gateways. We will use pre-shared key authentication due to limitations of the Azure setup.

ike: The IKE algorithm to use for the connection. In our case we use AES-256 combined with SHA-1 hashing and modp1024.

ikev2: Use this flag to choose between IKEv1 and IKEv2

keyingtries: How many retries to attempt before the connection fails.

leftid: How the left participant of the connection is identified. Use the AWS instance public IP address.

left: The IP address or DNS hostname of the left participant. Use the AWS private IP address of the gateway instance.

leftsubnet: The virtual private subnet that you want to connect. Use the AWS VPC subnet here.

right: The right side participant IP address or DNS hostname. Use the Azure VPN gateway public IP address

rightsubnet: The respective right side participant subnet. Use Azure Virtual Network subnet here.

For a detailed overview of all the available options you can refer to the libreswan manual page https://libreswan.org/man/ipsec.conf.5.html.

Set the pre-shared key as the secret for the connection, the same one that you used when you created the Azure VPN Connection in the previous section. The default configuration file for the secrets, includes any files under /etc/ipsec.d with the .secrets extension as you can see in the following snippet.

Default ipsec.secrets file

Add a new file /etc/ipsec.d/azure.secrets with the following content

Azure secrets configuration file

Replace the following placeholder labels with actual values:

AWS_EC2_PUBLIC_IP

AZURE_VPN_GW_PUBLIC_IP

PRESHARED KEY

Having completed the confuguration part, restart the ipsec service using the command sudo ipsec restart. This will trigger a re-read of the configuration and ultimately start the VPN connection . Check the VPN connection status in the AWS instance using the command sudo ipsec status and expect to see something like the following in the tail:

000 #1: “AwsAzureNet”:4500 STATE_PARENT_I3 (PARENT SA established); EVENT_SA_REPLACE in 9925s; newest ISAKMP; idle; import:admin initiate 000 #2: “AwsAzureNet”:4500 STATE_V2_IPSEC_I (IPsec SA established); EVENT_SA_REPLACE in 2515s; newest IPSEC; eroute owner; isakm p#1; idle; import:admin initiate 000 #2: “AwsAzureNet” esp.adc7a220@Azure_IP_here esp.455ebe39@10.101.32.205 ref=0 refhim=0 Traffic: ESPin=0B ESPout=0B! ESPmax=0 B 000

You can also verify that the connection is active with the Azure portal, if you open the VPN Gateway and check the connection status as shown in screen 10.

Screen 10: Verify VPN connection status

Now you can share resources between you Virtual networks in AWS and Azure clouds as if they were in the same Virtual Network. For example try to connect via SSH from one VM of Azure to an EC2 instance in AWS and vice versa. Or if you have an internal http or file server in one cloud provider, you can try to access it from the virtual network of the other provider.

Traffic monitoring and cost

One thing you might keep in mind though is to monitor the amount of traffic that is interchanged between the gateways. Both cloud providers will charge you per GB of traffic transferred out of their clouds, but incoming traffic is free of charge. For example prices in the US West cloud region, as of June 2020, are for Azure: 0–5GB free, 5GB-10TB $0.087/GB and for AWS: 0–1GB free, 1GB-10TB $0.09/GB. Assuming that your overall monthly traffic to the Internet in both services is below 10TB each, we can ignore the free GB tier for the sake of simplicity and calculate the total cost of data transfer between the Virtual Networks. We need to know the transferred data size to do that and one easy way to find out is to use the Azure portal as shown in screen 11. By opening the AWSAzureLink connection created previously, in the overview pane it shows that size of data in and out. The in data is the data that was sent from the AWS gateway, so you multiply this with the cost of the AWS data out. The out data is the data sent from the Azure gateway, so you multiply with the respective cost per unit of data. The general formula for traffic < 10TB is

Total cost = DataIn(GB) * AWSCost + DataOut(GB) * AzureCost

In our example the cost so far is:

Total cost = 0. 372 * $0.09 + 0.045 * $0.087 = $0.037

Screen 11: In/Out data traffic counter

Conclusion — Main points

We have established a private secure tunnel between AWS and Azure Virtual networks

We have used free IPSec VPN software tools in combination to Azure’s Site to Site VPN gateway connectivity.

We have learned how to monitor the data traffic size passing through the tunnel and calculated the imposed costs.