Networking & Content Delivery

Simulating Site-to-Site VPN customer gateways using strongSwan part 2: Certificate-based authentication

Do you need to either demonstrate or learn more about using certificate-based authentication with AWS Site-to-Site VPN capabilities?

In part 1 of this series, we showed how to use an AWS CloudFormation template to deploy the open source strongSwan VPN solution to implement the on-premises side of an AWS Site-to-Site VPN connection. The open source Quagga software suite complements the role of strongSwan by automatically propagating routing information across Site-to-Site VPN connections using Border Gateway Protocol (BGP).

Part 1 shows you how to use private shared key (PSK)-based authentication in support of your Site-to-Site VPN connections.

This new part 2 post shows you how to use an updated version of the CloudFormation template to configure certificate-based authentication in support of your Site-to-Site VPN connection. Use of certificate-based authentication can help you enhance the security of your Site-to-Site VPN connections. See Site-to-Site VPN tunnel authentication options for more background on the PSK- and certificate-based options.

If you’re interested in using PSK-based authentication with AWS Site-to-Site VPN, we recommend that you follow part 1. If you’re interested in learning more about how to use certificate-based authentication with AWS Site-to-Site VPN, continue reading.

About this blog post
Time to read 20 minutes
Time to complete 60 minutes – including 20 minutes beyond part 1 to generate certificates, store the certificates into an S3 bucket, and add the private certificate passphrase to AWS Secrets Manager.
Costs to complete Resources that may incur costs while you run this experiment include:

Learning level Advanced (300)

Solution overview

The CloudFormation template vpn-gateway-strongswan.yml used in part 1 has been enhanced to support the use of certificate-based authentication. You can review the supporting code in the associated GitHub repository.

The same topologies covered in part 1 still apply:

  • Integration with AWS Site-to-Site VPN features via:
    • AWS Transit Gateway
    • AWS Virtual Private Gateway
  • Do-it-yourself (DIY) site-to-site VPN connections

As with part 1, this post focuses on the first two topologies. If you intend to set up a DIY site-to-site connection, you should be able to use this post to help you figure out how to use certificate-based authentication in support of a DIY topology.

Figure 1 represents a common topology of an AWS Site-to-Site VPN connection with Transit Gateway.

Site-to-Site VPN with Transit Gateway

Figure 1: Site-to-Site VPN with Transit Gateway

Previewing work required for certificate-based authentication

Compared to using PSK-based authentication, there’s more upfront work required to prepare for using certificate-based authentication. The added benefit is increased security of your VPN connections.

The following sections are intended to introduce you to the extra work involved in preparing for certificate-based authentication. If you’d like to skip this background information, you can go straight to the step-by-step instructions.

Work required in your AWS environment

Figure 2 represents the private CAs and customer gateway private certificate that you must create in your AWS environment. It also represents the tunnel-specific private certificates that are automatically generated when you configure your VPN connection.

Private CAs and certificates in your AWS environment

Figure 2 – Private CAs and certificates in your AWS environment

Private certificates authorities (CAs)

When using certificate-based authentication, you must use the AWS Certificate Manager private CA feature to create root and subordinate private CAs. The root CA is used to sign the subordinate CA, while the subordinate CA is used to sign private certificates that are used to support your VPN connections.

See AWS Certificate Manager Pricing for details on the costs of operating private CAs. Ensure that you review the pricing details before you provision your private CAs. When you’re done with your experiment, you should consider deleting the private CAs so that you minimize any costs incurred.

Customer gateway private certificate

Once you’ve created the necessary CAs, use AWS Certificate Manager to create a private certificate to identify and authenticate your on-premises customer gateway when it initiates the VPN connection.

The customer gateway private certificate is signed by the subordinate private CA. When you configure a customer gateway in your AWS environment, choose certificate-based authentication and associate your customer gateway private certificate with the customer gateway.

Later, when your VPN connection and tunnels are established, this association ensures that only a customer gateway that has this customer gateway private certificate can connect to your AWS environment.

Exported forms of the certificates and customer gateway private key

Once you’ve created the private CAs and the customer gateway private certificate, you must save copies of the associated certificates to your desktop.

Later, you’ll transfer these certificates to you simulated on-premises environment. Using these certificates, the strongSwan VPN tool will validate the authenticity of both the customer gateway private certificate and tunnel-specific private certificates that are sent to the client when the VPN connection is established.

You must also save a copy of the customer gateway private key so that the strongSwan VPN tool can decrypt the content of the customer gateway private key. Since the customer gateway private key is sensitive data, you must use a passphrase to encrypt the private key file.

Role of the domain name of tunnel-specific private certificates

The tunnel-specific private certificates are automatically generated by AWS when you either create a transit gateway attachment to a VPN or create a site-to-site connection. These certificates contain a domain name that is used when deploying the strongSwan VPN gateway stack in your simulated on-premises environment.

When the tunnels are being established, the strongSwan tool uses the domain names to help validate the tunnel-specific private certificates exchanged when the tunnels are established.

Work required in your simulated on-premises environment

Before you can create the CloudFormation stack for your strongSwan VPN gateway in your simulated on-premises environment, you’ll need to perform the following steps.

First, you must upload the certificates and customer gateway private key to an S3 bucket that is accessible from your simulated on-premises environment.

Next, you must create a secret in AWS Secrets Manager and store the passphrase to decrypt the customer gateway private key in that secret.

Figure 3 shows the certificates and the customer gateway private key stored in an S3 bucket. The passphrase for the customer gateway private key is stored in a secret in AWS Secrets Manager.

Certificates and customer gateway private key stored in Amazon S3 in your simulated on-premises environment

Figure 3 – Certificates and customer gateway private key stored in Amazon S3 in your simulated on-premises environment

Setting up and testing your environment

The following steps establish an AWS Site-to-Site VPN connection in conjunction with AWS Transit Gateway. Minor adjustments to the set-up process are required if you’d rather deploy a Site-to-Site VPN connection with AWS Virtual Private Gateway.

If you’d like to build a DIY solution where a strongSwan VPN gateway is used on both ends of the VPN connection, you should be able to extend these instructions.

The overall steps include:

  1. Complete prerequisites
  2. Allocate an Elastic IP address in your simulated on-premises environment
  3. Create certificates in your AWS environment
  4. Configure the AWS side of the VPN connection
  5. Download the VPN tunnel configuration
  6. Publish certificates to your simulated on-premises environment
  7. Deploy strongSwan VPN gateway stack to your on-premises VPC
  8. Troubleshoot stack creation failures
  9. Monitor the VPN connection status
  10. Test the VPN connection

1. Complete prerequisites

For this configuration, ensure that you satisfy these prerequisites:

  • You have an AWS account.
  • You’ve selected an AWS Region in which to perform your demonstration.
  • You have two VPCs each with at least one subnet.
    • A VPC that simulates your on-premises environment. This post assumes that you have at least one public subnet in your on-premises VPC.
    • A VPC that represents your AWS cloud environment with at least one subnet. The subnet can be either private or public.
  • You have at least basic knowledge of AWS networking and the use of VPCs.
  • You have basic familiarity with Linux and the Linux command line so that you can test the VPN connection.

2. Allocate an Elastic IP address in your simulated on-premises environment

Allocate an Elastic IP address in your on-premises VPC so that in later steps you can:

  • Configure a Customer Gateway in your AWS cloud environment VPC.
  • Provide the static public IP address for your strongSwan VPN gateway EC2 instance in your on-premises network.

Allocate an Elastic IP address:

  1. Open the Amazon VPC console at https://console.aws.amazon.com/vpc/
  2. Choose the AWS Region of interest
  3. In the navigation pane, choose Elastic IPs
  4. Choose Allocate new address
  5. Choose Amazon pool
  6. Choose Allocate
  7. Select the newly allocated Elastic IP address and note the IP address and its Allocation ID. You’ll need the allocation ID in a later step when you deploy the strongSwan VPN gateway in your simulated on-premises environment.

3. Create certificates in your AWS environment

3.1 Create and install the root and subordinate CA certificates in your AWS environment

If you don’t already have private root and subordinate CA certificates in your AWS environment, use AWS Certificate Manager Private Certificate Authority to create the CA certificates.

See Creating and installing the Certificate for a Private CA for the detailed steps to create the following CA certificates:

  • Root CA certificate
  • Subordinate CA certificate
Export CA certificates

Once you’ve created and installed the CA certificates, you must export them so you can upload them to an S3 bucket in your simulated on-premises environment in a later step.

  1. In your AWS cloud environment, access the AWS account where you will configure your transit gateway and VPN connection.
  2. Go to AWS Certificate Manager in the AWS Management Console.
  3. Select Private CAs
  4. Select the root CA.
  5. Select CA Certificate
  6. Select Export certificate body to a file
  7. Save the certificate to a local file.

Perform the same steps for the subordinate CA certificate.

3.2 Create customer gateway private certificate in your AWS environment

Next, you must create a private certificate to represent your customer gateway. You will upload this certificate and its associated private key to an S3 bucket in your simulated on-premises environment in a later step.

See Requesting a Private Certificate for details on how to create a private certificate to use as the identity of the customer gateway.

Export customer gateway private certificate and private key

Once you’ve created private certificate, you must export both the private certificate and the private key so you can upload them to an S3 bucket in a later step.

  1. Go to AWS Certificate Manager in the AWS Management Console.
  2. Select the customer gateway private certificate.
  3. Select Actions -> Export
  4. You’ll be asked to enter a passphrase that will be used to encrypt and decrypt the exported private key file.
  5. Select Export certificate body to a file to export the private certificate.
  6. Select Export certificate private key to a file to export the private key.

4. Configure the AWS side of the VPN connection

Next, set-up an AWS Site-to-Site VPN connection in your AWS cloud VPC environment. We use AWS Transit Gateway in these instructions. Alternatively, you can choose to use AWS Virtual Private Gateway. See Getting started in the AWS Site-to-Site VPN documentation for instructions on setting up a virtual private gateway.

Create a customer gateway

First, create a customer gateway in your AWS Cloud environment:

  1. Go to VPC in the AWS Management Console
  2. Select Customer Gateways
  3. Select Create Customer Gateway
  4. Assign a name to the customer gateway
  5. Select the dynamic routing option to demonstrate the use of BGP
  6. Since we’ll be demonstrating the use of dynamic routing via BGP, provide a BGP Autonomous System Number (ASN) associated with your customer gateway. You can either use one that is assigned to your network, or, if you’re only experimenting, you can specify a private ASN in the 64512-65534 range.
  7. Provide the Elastic IP address for your customer gateway that you allocated in the previous step.
  8. Select the private certificate that you’ve created to identity your customer gateway

Create a transit gateway and Site-to-Site VPN connection in your AWS Cloud environment:

  1. See Getting started with Transit Gateway for instructions on how to create a transit gateway for your AWS Cloud VPC environment and attach your AWS Cloud VPC. To keep things simple, you can use the following default settings:
    Configure the transit gateway
  2. Update your AWS cloud VPC route table(s) to route your on-premises destined network traffic to the transit gateway. For example, if your on-premises network is 10.0.0.0/16, add a route to the transit gateway:
    Update VPC route table
  3. Create a transit gateway VPN attachment
    1. See Creating a Transit Gateway VPN attachment for the instructions to create a Site-to-Site VPN connection that is integrated with Transit Gateway.
    2. When configuring the attachment:
      1. Provide a name for the attachment
      2. Select the Virtual Private Gateway target gateway type
      3. Choose the option use an existing customer gateway
      4. Select the customer gateway that you just created
      5. Select the dynamic routing option since you’ll be using BGP
      6. Accept the default tunnel options unless you want to experiment with the advanced options
  4. Note the domain names of the tunnel-specific private certificates
    1. Once the VPN attachment has been created, access Site-to-Site VPN Connections in the AWS Management Console
    2. Select the VPN connection
    3. Select Tunnel Details
    4. Under Certificate ARN, open each of the private certificate links.
    5. Note the domain name for each private certificate. You’ll need these values when you deploy the strongSwan VPN stack in your simulated on-premises environment

5. Download the VPN tunnel configuration

Within the site-to-site VPN connection resource of your AWS cloud VPC environment, download the VPN configuration file.

  1. Go to VPC in the AWS Management Console
  2. Choose the AWS Region of interest
  3. Choose Site-to-Site VPN Connections
  4. Select the VPN connection of interest, choose Download, choose the Generic option for Vendor, and download the configuration file.

If you browse the configuration file, you will see configuration settings for two VPN tunnels. You’ll use the tunnel configuration data in a later step when you deploy a strongSwan-based VPN gateway stack in your simulated on-premises VPC.

6. Publish certificates to your simulated on-premises environment

6.1 Upload certificates and private key to an S3 bucket in your simulated on-premises environment

In your simulated on-premises environment, either reuse an existing S3 bucket or create a new one and upload the following certificate files to the bucket:

  • Root CA certificate
  • Subordinate CA certificate
  • Customer gateway private certificate

Upload the customer gateway private key file to the same S3 bucket.

Once you’ve uploaded the certificates and customer gateway private key file, you should have 4 files in your S3 bucket. The names of your files will likely differ from these examples.

6.2 Add customer gateway private key passphrase to AWS Secrets Manager

In your simulated on-premises environment, you’ll need to create a new secret in AWS Secrets Manager to hold the value of the passphrase you used earlier to encrypt the customer gateway private key.

You’ll provide the name of this secret to CloudFormation in a later step when you deploy the strongSwan VPN gateway stack.

  1. Access AWS Secrets Manager
  2. Select Store a new secret
  3. Select Other types of secrets
  4. In Secret key/value:
    1. Enter the text passphrase as the key. Since the CloudFormation template looks for a key with this value, you must use “passphrase”.
    2. Enter the passphrase value for the customer gateway private key as the value. You had supplied a passphrase when you originally created the private key.
  5. Select NextStore a new secret in AWS Secrets Manager
  6. Provide a name for the secret. How you name the secret is your choice. You’ll supply this name as a parameter when you use CloudFormation in a later to deploy the strongSwan VPN gateway stack.
  7. Select Next
    Provide a name for the secret
  8. Select Next, and Store

7. Deploy strongSwan VPN gateway stack to your on-premises VPC

In this step, you create a CloudFormation stack using the vpn-gateway-strongswan.yml template and configuration data obtained from the remote site’s Site-to-Site VPN Connection resource.

You can use either the AWS Management Console or an included helper script and the AWS Command Line Interface (CLI) to create the stack.

Given the number of parameters involved, you will probably find it easier to use the CLI so you can specify the parameter values once in a JSON file. This is easier than entering them using the AWS Management Console.

The CLI approach also makes it easier to spin up new stack instances, both in cases where failures occur and when you change settings as you experiment with features.

CloudFormation stack parameters

See the README in the GitHub repository for more details on the CloudFormation stack parameters.

CloudFormation Stack Parameter Description
System Classification and Environment You can choose to override these parameter values if you’d like to customize the naming of AWS resources created by the template.
pEnvPurpose Specify the purpose for this particular stack. This short qualifier will be used in resource names including, for example, IAM roles. For example, “dev1”, “test”, “1”, etc.
Authentication Type
pAuthType

The type of authentication. Either psk or pubkey.

In this example, use “pubkey” for certificate-based authentication.

Certificate-Based Authentication
pCertBucket Name of S3 bucket (not the ARN) containing the following certificate files in .pem format.
pCgwCert Name of customer gateway certificate file residing in S3.
pCgwPrivateKey Name of customer gateway private key file residing in S3.
pCgwPrivateKeyPassphraseSecretName

Name of secret in AWS Secrets Manager containing the passphrase for the customer gateway private certificate file residing in S3.

The AWS Secrets Manager secret must be in the form of passphrase:<value> where passphrase is the key and <value> is the passphrase value.

pRootCaCert Name of root CA certificate file residing in S3. Required when using certificate-based authentication.
pSubordinateCaCert Name of subordinate CA certificate file residing in S3. Required when using certificate-based authentication.
VPN Tunnel 1 Open the VPN configuration file that you downloaded earlier.
pTunnel1VgwCertDomainName

The domain name of the private certificate associated with tunnel 1. Required when using certificate-based authentication.

You can obtain this value from accessing your site-to-site VPN connection in your AWS environment, selecting the Tunnel Details tab, and scrolling to the right to see the Certificate ARN column, and selecting the ARN associated with tunnel 1. Once the certificate information is displayed, locate the Domain name value.

pTunnel1VgwOutsideIpAddress See the remote site’s configuration for the “IPSec Tunnel #1” section, “Outside IP Addresses” section and “Virtual Private Gateway” value.
pTunnel1CgwInsideCidr See the remote site’s configuration for the “IPSec Tunnel #1” section, “Inside IP Addresses” section and “Customer Gateway” value.
pTunnel1VgwInsideCidr See the remote site’s configuration for the “IPSec Tunnel #1” section, “Inside IP Addresses” section and “Virtual Private Gateway” value.
pTunnel1VgwBgpAsn See the remote site’s configuration for the “BGP Configuration Options” and the “Virtual Private Gateway ASN” value.
pTunnel1BgpNeighborIpAddress See the remote site’s configuration for the “BGP Configuration Options” and the “Neighbor IP Address” value.
VPN Tunnel 2
pTunnel2VgwCertDomainName

The domain name of the private certificate associated with tunnel 2. Required when using certificate-based authentication.

You can obtain this value from accessing your site-to-site VPN connection in your AWS environment, selecting the Tunnel Details tab, and scrolling to the right to see the Certificate ARN column, and selecting the ARN associated with tunnel 2. Once the certificate information is displayed, locate the Domain name value.

Rest of the tunnel 2 parameters Address the same parameters types as explained for tunnel 1, but use values taken from the tunnel 2 section of the configuration file. Note that most of the values for tunnel 2 are different from those used to configure tunnel 1.
On-premises Network Configuration Settings associated with the configuration of the VPC and other resources that are simulating your on-premises network environment.
pVpcId The VPC in which the VPN gateway is to be deployed.
pVpcCidr The CIDR block of the local VPC. Used to advertise via BGP routing information to the remote site.
pSubnetId The subnet in which the VPN gateway is to be deployed.
pEipAllocationId The allocation ID of the Elastic IP address that is to be associated with the VPN gateway.
pLocalBgpAsn The BGP Autonomous System Number (ASN) used to represent the local end of the site-to-site VPN connection.

Using the CLI

If you have the AWS CLI installed, you might find it easier to use the shell script manage-stack to create the stack. You can obtain this script from the same repository as the CloudFormation template.

  1. We recommend you clone the repository to your local system where you have the AWS CLI installed.
  2. Customize one of the template-parameters-*.json files containing example sets of parameters for your stack. For example, to specify all of the parameters required for certificate-based authentication, make a copy of the template-parameters-certificate-auth.json file.
  3. Run the manage-stack wrapper script to create the stack. For example:$ ./manage-stack -s vpn-gateway-1 --region us-east-1 template-parameters-certificate-auth.json

Here are the option arguments supported by the manage-stack script:

Option Argument Required? Description Default
-s or --stack-name Required Specifies the name to assign to the newly created stack. None
-r or --region Optional AWS Region. Since the aws CLI is used, the standard environment variables are honored. The aws CLI will use the standard AWS_DEFAULT_REGION environment variable if set.
-p or --profile Optional AWS profile. Since the aws CLI is used, the standard environment variables are honored. The aws CLI will use the standard AWS_PROFILE environment variable if set.

Monitor progress of the stack creation using the AWS Management Console. Wait for creation of the stack to complete. Since the template uses a wait condition, the stack does not complete until the strongSwan application and other components have been configured and started.

Using the AWS Management Console

When you deploy the CloudFormation stack, you must enter parameter values that are associated with the VPN connection and specifically for the two tunnels that make up the connection. You must have the VPN configuration file open as a reference so you can copy and paste values for the parameters in the CloudFormation stack.

  1. Open the AWS CloudFormation console at https://console.aws.amazon.com/cloudformation/.
  2. Choose the AWS Region of interest.
  3. Choose Create Stack and choose With new resources.
  4. Choose Upload a template file.
  5. Use your browser to download the vpn-gateway-strongswan.yml CloudFormation template file to your local computer.
  6. Select Choose file to select the CloudFormation template file that you downloaded.
  7. Choose Next to proceed to Specify stack details.
  8. Enter a name for your new CloudFormation stack. For example, “vpn-gateway
  9. Specify the required parameters. See the preceding table of parameters for details.
  10. Choose Next to proceed to Configure stack options.
  11. Choose Next to review your stack settings.
  12. Choose Create stack.

Wait for creation of the stack to complete. Since the template uses a wait condition, the stack does not complete until the strongSwan application and other components have been configured and started.

8. Troubleshoot stack creation failures

If creating the stack seems to take too long (usually more than 5 minutes), or fails and resources are rolled back, then you must troubleshoot the situation.

Since there are a large number of parameters passed to the stack creation process, it’s not unusual for parameters to contain inaccurate data. More often than not, stack creation failures are due to incorrect parameter data.

Stack creation fails quickly

Verify your parameter settings against both your local network configuration and the configuration of the site-to-site tunnels. If you’re using an Elastic IP address, ensure the allocation ID is correct.

Stack creation fails after a long period of time

You may find that the stack creation fails after multiple minutes and resources are rolled back. In this case, it’s best to delete the stack and use the CLI approach described in the preceding step in an attempt to create the stack again. However, this time, use CloudWatch Logs to inspect the progress of the first boot configuration steps during stack creation.

Similar to the previous circumstance, verify your parameter settings against both your local network configuration and the configuration of the site-to-site tunnels. If you’re using an Elastic IP address, ensure that the allocation ID is correct.

If no obvious issues are found in the template parameters, delete the failed stack and use the CLI wrapper script in an attempt to create the stack again.

This time, during stack creation, inspect the CloudWatch Logs log group to find failures that occur during the first boot configuration process. For example, if the S3 bucket name for certificate key files is incorrect, the first boot configuration process will fail.

Specifically, access the cfn-init.log log stream to review the first boot configuration for any errors. By default, the CloudWatch Logs log group for your EC2 instance will be named /infra/vpngw/ec2/<environment purpose>.

If the cfn-init.log log stream looks clean, then review the charon.log stream for errors. If you’re using certificate-based authentication and your certificates and key files are incorrect, then you’ll typically see errors in this log stream.

A common mistake is to either fail to create a secret in AWS Secrets Manager or the secret key:value pair is incorrect. See the preceding steps for details on creating the secret in AWS Secrets Manager. Pay close attention to the fact that the secret’s key must be set to “passphrase“.

9. Monitor the VPN connection status

You can monitor the use of certificate-based authentication by inspecting the content of the charon.log file using either CloudWatch Logs or by connecting directly to the strongSwan EC2 instance and inspecting /var/log/charon.log. By default, the CloudWatch Logs log group for your EC2 instance will be named /infra/vpngw/ec2/<environment purpose>.

Once creation of the stack has completed, monitor the Site-to-Site VPN Connection on the remote site to confirm that the two VPN tunnels have progressed from the DOWN state to the UP state.

It will usually take 3-5 minutes before both tunnels progress to the UP state.

When using dynamic routing and BGP with the strongSwan configuration established using the CloudFormation template, both tunnels should eventually progress to the UP state.

If the VPN gateway configuration is correct, Tunnel 1 will come up first followed several minutes later by Tunnel 2.

Site-to-site VPN tunnel status showing both tunnels as UP

If the tunnels don’t come up within 5 or so minutes after your stack has completed, it’s likely that one or more of the tunnel related CloudFormation stack parameters is incorrect. Double check the parameter values. If any are incorrect, delete and recreate the VPN gateway CloudFormation stack. You should not need to delete and recreate the remote site’s transit gateway and VPN resources.

Review CloudWatch logs of the VPN gateway

You can inspect the VPN gateway’s logs via CloudWatch Logs. In the AWS Management Console under the CloudWatch services and CloudWatch Logs, look for a log group that is named similar to:  /infra/vpngw/ec2/....

The log files in order of importance are:

  • cf-init.log – Look for successful execution of the configuration sets from the AWS::CloudFormation::Init section of the CloudFormation template.
  • charon.log – If CloudFormation initialization looks ok, review the content of this log file to monitor the establishment of the VPN tunnels.

Inspect the strongSwan VPN gateway

If any of the following log files are not present: charon.log, zebra.logbgpd.log, start a terminal session with the VPN gateway instance and execute a command to display error messages associated with services starting up on the strongSwan EC2 instance.

Since the CloudFormation stack configures the VPN gateway EC2 instance to support terminal access through AWS Systems Manager Session Manager, you can easily connect to the strongSwan EC2 instance via the EC2 portion of the AWS management console.

  1. Access the EC2 service of the AWS Management Console
  2. Choose the strongSwan EC2 instance. For example, infra-vpngw-test
  3. Choose Connect in the upper portion of the console
  4. Choose the Session Manager option
  5. Choose Connect

Use the following commands to display errors associated with starting the following services:

$ systemctl status strongswan

$ systemctl status zebra

$ systemctl status bgpd

You can review the status of the strongSwan application via sudo strongswan status command. Execution of this command should show that both tunnels are connected:

$ sudo strongswan status

Security Associations (2 up, 0 connecting):
AWS-VPC-TUNNEL-1[135]: ESTABLISHED 2 hours ago, 10.0.0.221[10.0.0.221]...18.222.98.126[18.222.98.126]
AWS-VPC-TUNNEL-1{1358}:  REKEYED, TUNNEL, reqid 1, expires in 6 minutes
AWS-VPC-TUNNEL-1{1358}:   0.0.0.0/0 === 0.0.0.0/0
AWS-VPC-TUNNEL-1{1360}:  INSTALLED, TUNNEL, reqid 1, ESP in UDP SPIs: c2217636_i c2fc4ee3_o
AWS-VPC-TUNNEL-1{1360}:   0.0.0.0/0 === 0.0.0.0/0
AWS-VPC-TUNNEL-2[134]: ESTABLISHED 6 hours ago, 10.0.0.221[10.0.0.221]...52.15.138.189[52.15.138.189]
AWS-VPC-TUNNEL-2{1357}:  REKEYED, TUNNEL, reqid 8, expires in 4 minutes
AWS-VPC-TUNNEL-2{1357}:   0.0.0.0/0 === 0.0.0.0/0
AWS-VPC-TUNNEL-2{1359}:  INSTALLED, TUNNEL, reqid 8, ESP in UDP SPIs: cff85483_i 87052d38_o
AWS-VPC-TUNNEL-2{1359}:   0.0.0.0/0 === 0.0.0.0/0

You can inspect the BGP routes that Quagga knows about by executing the sudo vtysh command followed by the show ip bgp summary subcommand. In the following example, the BGP tunnel neighors are listed:

$ sudo vtysh

Hello, this is Quagga (version 0.99.22.4).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

ip-10-0-0-221.corp.ckamps-acme.com#  show ip bgp summary

BGP router identifier 10.0.0.221, local AS number 65000
RIB entries 3, using 336 bytes of memory
Peers 2, using 9120 bytes of memory

Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
169.254.54.17   4 64512  182713  182714        0    0    0 03w0d03h        1
169.254.227.237 4 64512  182593  182632        0    0    0 14:36:47        1

Total number of neighbors 2

Next, you can inspect the routes by executing the <code<show ip route subcommand. In the following example, 10.4.0.0/19 represents the route advertised by the transit gateway via BGP.

# show ip route

Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, A - Babel,
       > - selected route, * - FIB route

K>* 0.0.0.0/0 via 10.0.0.1, eth0
C>* 10.0.0.0/24 is directly connected, eth0
B>* 10.4.0.0/19 [20/100] via 169.254.54.17, vti1, src 10.0.0.221, 03w0d03h
C>* 127.0.0.0/8 is directly connected, lo
C>* 169.254.54.16/30 is directly connected, vti1
K>* 169.254.169.254/32 is directly connected, eth0
C>* 169.254.227.236/30 is directly connected, vti2

10. Test the VPN connection

Once you’ve confirmed that the two tunnels are in the UP state, you’re ready to test the VPN connection. The simplest means to test the VPN connection is to deploy an Amazon Linux EC2 instance in a subnet in the VPC of the simulated on-premises environment, deploy an EC2 instance in your AWS cloud VPC, and test connectivity between the EC2 instances.

Add a route to your strongSwan instance in your on-premises subnet routing table

Since you’re using BGP, the strongSwan instance will advertise your on-premises routing information to the transit gateway and vice versa. However, that routing information is not propagated to the VPC route tables on either side of the connection.

In your on-premises VPC, ensure that the subnet in which you intend to deploy a test EC2 instance is associated with a VPC route table that routes all traffic destined for the remote side of the VPN connection to the elastic network interface (ENI) of your strongSwan EC2 instance.

Similarly, on the remote side, ensure that the subnet in which you intend to deploy the other test EC2 instance is associated with a VPC route table that routes all traffic destined for your on-premises network to your transit gateway.

An end-to-end testing scenario with two test EC2 instances is shown in Figure 4.

Testing your site-to-site VPN connection using two EC2 instances

Figure 4: Testing your site-to-site VPN connection using two EC2 instances

Deploy an Amazon Linux EC2 instance to a subnet in each VPC

  1. Select which method you’d like to use to access your Linux instance:
    1. Systems Manager Session Manager: No publicly accessible IP address is required. Instead, you can use either AWS Management Console or SSH command line to access your instance. See Getting Started with Session Manager for set up details.
    2. SSH: Ensure that the security group allows for SSH inbound access and that the instance has a publicly accessible IP address.
  2. Deploy an Amazon Linux EC2 instance to one each of the two VPCs.
  3. Ensure the security group includes “All ICMP – IPv4” with a source of the remote network.

Using ping to test connectivity

Use the ping command from either of the two test EC2 instances to validate routing and connectivity between the instances. In the following example, the EC2 instance configured with the address 10.4.15.88 is in the remote environment on the other side of the site-to-site VPN connection. In this example, the ping was successful.

$ ping 10.4.15.88

PING 10.4.15.88 (10.4.15.88) 56(84) bytes of data.
64 bytes from 10.4.15.88: icmp_seq=1 ttl=252 time=2.09 ms
64 bytes from 10.4.15.88: icmp_seq=2 ttl=252 time=1.71 ms
64 bytes from 10.4.15.88: icmp_seq=3 ttl=252 time=1.74 ms
^C
--- 10.4.15.88 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 1.713/1.851/2.094/0.172 ms

Use the tcpdump command on the target instance to monitor traffic. In the following example, ping or ICMP requests from 10.0.4.26 are flowing into the target instance that has an IP address of 10.4.15.88. ICMP responses are flowing out of the target instance back to the client at 10.0.4.26.

$ sudo tcpdump -eni any icmp

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
17:12:14.259360  In 02:ff:0e:f8:f1:5c ethertype IPv4 (0x0800), length 100: 10.0.4.26 > 10.4.15.88: ICMP echo request, id 23325, seq 1, length 64
17:12:14.259388 Out 02:4a:3b:b9:d7:14 ethertype IPv4 (0x0800), length 100: 10.4.15.88 > 10.0.4.26: ICMP echo reply, id 23325, seq 1, length 64
17:12:15.260400  In 02:ff:0e:f8:f1:5c ethertype IPv4 (0x0800), length 100: 10.0.4.26 > 10.4.15.88: ICMP echo request, id 23325, seq 2, length 64
17:12:15.260428 Out 02:4a:3b:b9:d7:14 ethertype IPv4 (0x0800), length 100: 10.4.15.88 > 10.0.4.26: ICMP echo reply, id 23325, seq 2, length 64
17:12:16.262395  In 02:ff:0e:f8:f1:5c ethertype IPv4 (0x0800), length 100: 10.0.4.26 > 10.4.15.88: ICMP echo request, id 23325, seq 3, length 64
17:12:16.262412 Out 02:4a:3b:b9:d7:14 ethertype IPv4 (0x0800), length 100: 10.4.15.88 > 10.0.4.26: ICMP echo reply, id 23325, seq 3, length 64
17:12:17.264502  In 02:ff:0e:f8:f1:5c ethertype IPv4 (0x0800), length 100: 10.0.4.26 > 10.4.15.88: ICMP echo request, id 23325, seq 4, length 64
17:12:17.264525 Out 02:4a:3b:b9:d7:14 ethertype IPv4 (0x0800), length 100: 10.4.15.88 > 10.0.4.26: ICMP echo reply, id 23325, seq 4, length 64
^C
8 packets captured
8 packets received by filter
0 packets dropped by kernel

See Testing the Site-to-Site VPN connection for additional tips on testing.

If your ping tests are not successful, verify the following configurations on both sides of the site-to-site VPN connection:

  • Ensure that “All ICMP – IPv4” is allowed in the EC2 security group on each of your test EC2 instances.
  • Route tables:
    • If you are using AWS Transit Gateway, ensure that your remote VPC’s route table has a routing entry to direct on-premises traffic to the transit gateway attachment.
    • In your local on-premises VPC, ensure that a route entry directs AWS cloud traffic to the strongSwan EC2 instance’s network interface.

If necessary, consider using tcpdump on the strongSwan VPN gateway EC2 instance to see if traffic is being routed through the gateway.

Exploring other capabilities

See the README for more advanced capabilities you might want to explore and demonstrate including:

  • Hosting the VPN gateway in a private subnet.
  • Updating the VPN gateway stack with configuration changes.
  • Replacing the VPN gateway stack with a new stack.
  • Route all internet destined traffic from your AWS Cloud VPC back through the Site-to-Site VPN connection and out your existing security devices.

Cleaning up

To avoid incurring future charges, delete the following resources.

In your simulated on-premises environment:

  1. Use AWS CloudFormation to delete the stack that deployed the strongSwan VPN gateway.
  2. If you created an Elastic IP Address in support of the strongSwan VPN gateway, you can use the EC2 area of the AWS Management Console to delete the Elastic IP address.
  3. If you created a VPC to emulate the on-premises side of the Site-to-Site VPN connection and no longer need it, you can consider deleting the VPC and its supporting resources.
  4. Terminate the test Linux EC2 instance.
  5. Delete the certificate files from your S3 bucket and delete the bucket.
  6. Delete the secret from AWS Secrets Manager

In your AWS Cloud environment:

  1. Delete your Site-to-Site VPN connection.
  2. Delete your Transit Gateway.
  3. Delete your customer gateway.
  4. Terminate the test Linux EC2 instance.
  5. Delete the certificates and private CAs from AWS Certificate Manager.

Conclusion

In this post, we showed how to experiment with and demonstrate certificate-based authentication to further enhance the security of your Site-to-Site VPN connections.

If you’d like to learn more about the AWS Site-to-Site VPN services referenced in this example, see the following resources:

Christopher Kampmeier

Chris is a Senior Solutions Architect helping financial services customers throughout the world adopt AWS to meet their business needs. Prior to joining AWS, Chris led agile teams to provide builder services to hundreds of delivery teams within a global payment technology solutions provider. In his spare time, he enjoys cycling, working on home automation and yard projects, and traveling with his family.

Mohammed Munem

Mohammed is a Cloud Infrastructure Architect at AWS Professional Services who works closely with customers to accelerate their AWS Cloud journey. In his spare time, he enjoys running, cycling, and spending time with his family.