Setting up an AWS to Digital Ocean Site-to-Site VPN with strongSwan

Updated:

I just spent many hours over the course of several days figuring out how to set up a VPN between AWS and Digital Ocean with strongSwan.

I had to piece together various blog and forum posts to get this to work.

Why might you want a Site-to-Site VPN between Digital Ocean and AWS?

First, let’s go over why a VPN connection between AWS and Digital Ocean might be useful for you.

Say you wanted to migrate from Digital Ocean to AWS, but you didn’t want to have to migrate all your services in one go. You can start by making new microservices on AWS infrastruture while leaving your existing services on Digital Ocean. The site-to-site VPN allows your new services in AWS to call existing services on Digital Ocean.

Setup

The desired topology will look like this, where “Corporate Data Center” is Digital Ocean.

You can read more about it on AWS’s blog.

Creating Digital Ocean Droplet

First, you’ll need a Digital Ocean droplet that will be your customer gateway on AWS’s side. This droplet will be running strongSwan and act as your VPN server into your Digital Ocean VPC.

Create a droplet in the desired VPC. For the purposes of this guide, I’ll be assuming you’re using Ubuntu. The resourcing of the droplet can be up to you. Make sure you have an ssh key so that you can ssh onto the droplet.

Keep a note of the VPC IP cidr, public, and private IPs of the droplet.

Creating AWS Resources

Next, we’ll create the AWS resources, starting with the customer gateway. The customer gateway refers to your Digital Ocean droplet.

Log into your AWS Console.

  1. Create a VPC if you don’t already have one.
  2. Go to customer gateways
  3. Click Create customer gateway
  4. Fill out the name as you wish. Keep the BGP ASN the default. For the IP address, put in the public ip address of the Digital Ocean droplet we created in the previous step.
  5. Click Create customer gateway

Now it’s time to create your Virtual Private Gateway. This is what will allow traffic into your VPC.

  1. Go to Virtual Private Gateways
  2. Click Create virtual private gateway.
  3. Name it as you please, leave the default Amazon default ASN in place.
  4. Click Create virtual private gateway

Next, we’ll make the VPN connection that ties the customer gateway and the virtual private gateway together.

  1. Go to Site-to-Site VPN Connections.
  2. Click Create VPN connection
  3. Name it as you please
  4. For Target gateway type, make sure Virtual private gateway is selected and in the dropdown select the Virtual private gateway that you created earlier.
  5. Do the same for Customer gateway.
  6. For routing options, it’s important that you select Static and not Dynamic. If you select Dynamic then you won’t see the strongSwan configuration for download later on.
  7. Click Create VPN Connection

In a few minutes you’ll see the VPN State go from Pending to Available.

If you inspect the VPN connection and go to the Tunnel details tab, you’ll see that AWS created two tunnels for you and both will have a status of Down.

One thing that confused me was why there were two tunnels, so here’s a quick explaination. You only need one tunnel for the site-to-site VPN to work. There’s an additional tunnel for redundancy. If you wanted to create both tunnels, they would be separate instances in your on-premises network, or in this case, Digital Ocean.

Note the tunnel’s outside IP address and inside IPv4 CIDRs. You’ll need them later when configuring the VPN server in Digital Ocean.

  1. Download the configuration for your VPN by selecting it in the AWS console and clicking Download Configuration.

Here, you’ll be prompted for the VPN Vendor and Platform. Select strongSwan and Ubuntu. Then click Download

Finally, we’ll need to turn on Route Propagation.

  1. Go to your AWS VPC.
  2. Click on your Main route table. Note: If you have differents routes on your subnets you might need to configure those.
  3. Go to Route Propagation under your route table.
  4. Click Edit and check Enable for your Virtual private gateway.

Setting up the Digital Ocean strongSwan VPN server

  1. SSH into your Digital Ocean droplet.
  2. Install strongswan

Assuming you’re using Ubuntu, you can install it with apt:

sudo apt-get update
sudo apt-get install -y strongswan
  1. Open up the strongswan configuration for Ubuntu that you downloaded earlier.
  2. Follow the instructions for Tunnel 1. We won’t be covering Tunnel 2 in this guide, but it’s essentially the same thing on a different droplet in your VPC. ONLY DO the steps in #1 Enable Packet Forwarding and Configure the Tunnel Do Automated Tunnel Healthcheck and Failover and skips steps #2 - #5.

I’m going to highlight a few things that were confusing to me in their instructions.

In the configuration for the Tunnel1, there’s a comment and line that looks like this:

## Uncomment the following line to utilize the script from the "Automated Tunnel Healhcheck and Failover" section. Ensure that the integer after "-m" matches the "mark" value above, and <VPC CIDR> is replaced with the CIDR of your VPC

Where it says <VPC CIDR> here, they mean the AWS VPC CIDR, NOT the Digital Ocean VPC CIDR.

You can find your Digital Ocean VPC CIDR in your Networking page here:

digital ocean vpc cidr

Once you’ve followed the instructions and have everything set up and restarted strongSwan with sudo ipsec restart, in a few minutes you should see the Tunnel1 go from DOWN to UP in the AWS Console.

You can also do the debugging steps at the bottom of the VPN instructions to ensure that everything is configured properly.

sudo ipsec status # Ensure that your Tunnel1 is ESTABLISHED

If you’ve done things correctly, at this point you should be able to ping from an EC2 instance on AWS to your Digital Ocean instance. You should not be able to ping from your Digital Ocean VPN server to an EC2 instance yet!

Finally, and here’s the key step that took me forever to figure out:

You need to add your private VPN’s internal CIDR as a static route on your VPN. It’s the CIDR range that starts with 169.254.X.X/30. Once that’s in place and you give it a couple minutes, you should be able to ping from Digital Ocean to AWS and receive a response.

NAT setup on DO VPN instance

Once the tunnel is set up, you need to set up a NAT to translate the source IP to be the private IP of the DO VPN server:

iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to <PRIVATE IP>

This will enable you to access other DO instances from AWS.

Note: iptables settings do not persist after reboot by default so you will need to save and persist them somehow.

For ubuntu:

sudo iptables-save > /etc/iptables/rules.v4
sudo apt install iptables-persistent
sudo systemctl enable netfilter-persistent.service

Credit to this article.

Making the tunnel start on reboot

In step #5 Persistent Configuration, skip the iptables part and do the third step that involves editing /etc/network/interfaces.

Resources


Join the 80/20 DevOps Newsletter

If you're an engineering leader or developer, you should subscribe to my 80/20 DevOps Newsletter. Give me 1 minute of your day, and I'll teach you essential DevOps skills. I cover topics like Kubernetes, AWS, Infrastructure as Code, and more.

Not sure yet? Check out the archive.

Unsubscribe at any time.