A universal need with Infrastructure as a Service (IaaS) is to securely connect isolated networks, whether they be public or private cloud, on-premise, etc. Some of this need can now be met using methods such as Amazon VPC peering, etc. however, even this has technical constraints preventing a blanket use (e.g. when using in conjunction with Direct Connect, etc.). Therefore, an inexpensive generic network interconnect design pattern was sought to address this typical use-case.
strongSwan, launch in 2005, is an OpenSource IPsec implementation that was originally based on the discontinued FreeS/WAN project. strongSwan can be quickly provisioned onto a virtual machine (VM) which then connects to connect an Amazon VPC network to via a standard Amazon VGW to another network, whether that be any public or private cloud, on-premise data centre, etc.
The following diagram illustrates a simple implementation connecting networks A and B; where Network B is an AWS network (VPC), and Network A can be a network of any type at any location with Internet access and an instance/VM available to run a VPN gateway. From here on in, this diagram will be referenced to simplify key concepts.
It is essential to avoid overlapping addresses for the networks you are joining as this will lead to routing complications.
StrongSwan can be installed on Linux 2.6, 3.x and 4.x kernels, Android, FreeBSD, OS X and Windows. However, we have found the optimal platform to be a Linux Ubuntu 14 VM. This VM, which can run on a modest 1CPU + 1GB configuration (additional resource will be needed depending on load), will need and internal and external interface.
Some firewall should be deployed to protect Network A, at the very least this must have IP filtering capabilities.
The following instructions should be used to provision the Amazon VGW:
- Create a new Customer Gateway in the VPC (Network B) with IP address set to the external IP address of the StrongSwan VM (e.g. 18.104.22.168)
- Create a Virtual Private Gateway in the VPC (Network B)
- Create a new VPN Connection in the VPC (Network B) using the above Customer Gateway and Virtual Private Gateway. Set routing to static, and add a static route to Network A (172.16.0.0/16)
- Once provisioned, download the configuration file for the VPN Connection using the generic/generic/vendor agnostic pattern
- Open the downloaded file in Excel for clarity
- In the file you will see two sections; one called IPSec Tunnel #1 and the other called IPSec Tunnel #2. Both sections contain the following information that is needed for later configuration:
- Pre-Shared Key (a random string of characters used for authentication)
- Virtual Private Gateway (the external IP address of the Amazon VGW tunnel – 22.214.171.124 and 126.96.36.199 in the above example).
A route table will need creating, with a route to Network A (172.16.0.0/16) targetted to the VGW. This route table should then be associated with all subnets needing to communicate with Network A.
A security group will need to be provisioning to permit inbound traffic into Network B. This security group should be associated with any resources in Network B that need to be accessed by resources on Network A.
To install just run the following command:
- apt-get install strongswan
Firstly the Network A firewall should be opened to permit incoming traffic from the VGW tunnels on 188.8.131.52 and 184.108.40.206 on only UDP 500, UDP 4500 and protocol 50. Additionally, AWS security groups should be carefully managed to protect incoming traffic to Network B.
Finally, the VGW Pre-Shared Keys needs to be bound to the StrongSwan service so tunnel(s) can be established, these are maintained in /etc/ipsec.secrets.
# This file holds shared secrets or RSA private keys for authentication.
# RSA private key for this host, authenticating it to any other host
# which knows the public part. Suitable public keys, for ipsec.conf, DNS,
# or configuration of other implementations, can be extracted conveniently
# with “ipsec showhostkey”.
220.127.116.11 : PSK “????????????????????”
NOTE: it is vital to retain the quotes either side of the pre-shared key.
Once installed, the service maintains its configuration at /etc/ipsec.conf. Simply, paste the following, AWS-optimised configuration into the file making changes highlighted in BOLD to fit with your particular environment. Each connection (conn) is given a name, in our example aws_tunnel_1, aws_tunnel_2, these can be changed to reflect your specific requirement.
Once the configuration files are ready, you can start the service run running service strongswan start.
The service should already be enabled for startup on boot through an upstart job for strongSwan located at /etc/init/strongswan.conf.
Should you need to connect multiple AWS networks using a single strongSwan VM, this can be easily achieved by the following:
- Adding connections (four lines per conn) to the end of the /etc/ipsec.conf file – ensuring the connection name is unique
- Adding a new PSK lines to the end of the /etc/ipsec.secrets file
- Opening up the Network A firewall to permit IPsec traffic to the new network
- Restarting the stringswan service.
18.104.22.168 : PSK “????????????????????”
NOTE: it is not possible to the use the strongSwan VM as the Network A test resource as this is outside the encryption domain so will not be included.
Check whether the tunnel is up by either:
- From the AWS console look in the tunnel details on the VPN connections, this will list the tunnels as either up or down
- From the strongSwan VM, run the ipsec status command, this will list the tunnels as either established (up) or installed (down).
If the tunnel is not up:
- Ensure the StrongSwan service is started by running the service strongswan status command
- Ensure the configuration is correct, and that the Pre-Shared Keys in the /etc/ipsec.secrets file are surrounded by the correct quotes
- Ensure the Network A firewall is open to the VGW tunnel addresses.
Check hosts on Network A can route to Network B and visa-versa:
- From VM A run traceroute (Linux) or tracert -d (Windows) to the internal IP address of VM B, then repeat in the other direction.
The first hop should be the internal IP address of the strong Swan VM. If it isn’t then:
- Check the IP addresses used in the test
- Check the StrongSwan configuration file is correct
- Check the Network B route table
- Check the Network B VPN Connection static route.
Check hosts on Network A can ping to Network B and visa-versa:
- From VM A run ping to the internal IP address of VM B, then repeat in the other direction.
A ping reply should be returned. If it is not then:
- Check the IP addresses used in the test
- Check all test computers are running
- Check the security group (Network B).
The following commands have been listed to assist with any troubleshooting.
- ipsec status. Queries the tunnels
- ipsec <connection name> up. Brings up a specific tunnel (called <connection name>)
- ipsec <connection name> down. Tears down a specific tunnel (called <connection name>)
- service strongswan status. Queries the strongSwan service
- service strongswan stop. Stops the strongSwan service
- service strongswan start. Starts the strongSwan service.
I would like to take the opportunity to thank Ra’ed Hussein, Cloud Support Engineer at Amazon Web Services who helped me iron out some of the wrinkles with the implementation of this solution!