Home / AWS Networking
AWS Networking • Hybrid Cloud

AWS Site-to-Site VPN Connection Guide

A complete engineering blueprint for configuring redundant IPSec VPN tunnels between an on-premises network and Amazon VPC using Openswan/Libreswan and automated Terraform modules.

AWS Site-to-Site VPN Architecture Diagram

1. Understanding AWS Hybrid Cloud Networking

Modern hybrid enterprise environments require reliable, encrypted connectivity between corporate on-premises data centers and cloud VPCs. While dedicated physical circuits like AWS Direct Connect deliver high throughput with consistent latency, they entail lead times and substantial monthly commitments.

An AWS Site-to-Site VPN provides a secure, cost-effective alternative utilizing standard IPSec (Internet Protocol Security) over the public internet. AWS provisions each managed VPN connection with two distinct endpoint IP addresses terminating in separate Availability Zones, creating two redundant tunnels for high availability.

2. Core Architectural Components

To design a functional IPSec tunnel, specific network abstractions must exist on both sides of the boundary:

3. Provisioning AWS VPN Infrastructure with Terraform

Automating the creation of networking primitives prevents configuration drift across environments. The following Terraform module provisions the VGW, associates it with the VPC, registers the Customer Gateway, defines the VPN connection with static routing, and enables route propagation:

# 1. Create and attach Virtual Private Gateway (VGW)
resource "aws_vpn_gateway" "main_vgw" {
  vpc_id = aws_vpc.cloud_vpc.id
  tags   = { Name = "cicdclouds-vgw" }
}

# 2. Define the on-premises Customer Gateway (CGW)
resource "aws_customer_gateway" "onprem_cgw" {
  bgp_asn    = 65000
  ip_address = "203.0.113.45" # Replace with your real on-prem public IP
  type       = "ipsec.1"
  tags       = { Name = "onprem-datacenter-cgw" }
}

# 3. Create the managed Site-to-Site VPN Connection
resource "aws_vpn_connection" "hybrid_vpn" {
  vpn_gateway_id      = aws_vpn_gateway.main_vgw.id
  customer_gateway_id = aws_customer_gateway.onprem_cgw.id
  type                = "ipsec.1"
  static_routes_only  = true
  tags                = { Name = "cicdclouds-site-to-site" }
}

# 4. Route on-premises subnets through the VPN tunnel
resource "aws_vpn_connection_route" "onprem_network" {
  destination_cidr_block = "192.168.10.0/24"
  vpn_connection_id      = aws_vpn_connection.hybrid_vpn.id
}

# 5. Automatically propagate routes into the VPC Route Table
resource "aws_vpn_gateway_route_propagation" "private_subnets" {
  vpn_gateway_id = aws_vpn_gateway.main_vgw.id
  route_table_id = aws_route_table.private_rt.id
}

4. Configuring Openswan on Linux Gateway

For development or lab scenarios, a Linux server (Ubuntu/RHEL) acting as a perimeter gateway can terminate the IPSec tunnel via Openswan or Libreswan.

Step 4.1: Enable Linux IP Forwarding

The operating system kernel must forward packets between interfaces instead of dropping routed packets:

# Enable runtime packet forwarding
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv4.conf.all.accept_redirects=0
sudo sysctl -w net.ipv4.conf.all.send_redirects=0

# Make settings persistent across reboots in /etc/sysctl.conf
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.conf.all.accept_redirects = 0" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.conf.all.send_redirects = 0" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Step 4.2: Configure IPSec Tunnel Parameters

Create the connection definition file in /etc/ipsec.d/aws-vpn.conf. Ensure your local subnet matches your on-premises network (192.168.10.0/24) and the remote subnet matches your VPC CIDR (10.0.0.0/16):

conn AWS-Tunnel-1
  authby=secret
  auto=start
  left=%defaultroute
  leftid=203.0.113.45               # On-premises Public IP
  right=198.51.100.12               # AWS Tunnel 1 Endpoint IP
  type=tunnel
  ikelifetime=8h
  keylife=1h
  phase2alg=aes128-sha1;modp1024
  ike=aes128-sha1;modp1024
  keyingtries=%forever
  keyexchange=ike
  leftsubnet=192.168.10.0/24       # On-premises CIDR
  rightsubnet=10.0.0.0/16          # AWS VPC CIDR
  dpddelay=10
  dpdtimeout=30
  dpdaction=restart_by_peer

Step 4.3: Securely Store Pre-Shared Keys

Store the authentication key in /etc/ipsec.d/aws.secrets with strict read permissions (chmod 600):

# File: /etc/ipsec.d/aws.secrets
203.0.113.45 198.51.100.12: PSK "YourGeneratedPreSharedSecretKey123"

# Enforce secure file permissions
sudo chmod 600 /etc/ipsec.d/aws.secrets

5. Firewall & Security Group Prerequisites

Tunnel initialization failures frequently stem from upstream security appliances filtering IPSec handshake packets. Ensure the following ports are open bi-directionally on the perimeter firewall:

6. Verification and Troubleshooting

After restarting the IPSec service, check the operational status of the tunnel:

# Restart the IPSec service daemon
sudo systemctl restart ipsec

# Inspect live Phase 1 and Phase 2 status
sudo ipsec status

# Check detailed tunnel statistics
sudo ipsec auto --status

In the AWS Console, navigate to VPC > Site-to-Site VPN Connections and inspect the Tunnel Details tab. The status should shift from DOWN to UP.

To test end-to-end data transfer, send an ICMP echo request from an on-premises host to a private EC2 instance inside your VPC subnet:

ping -c 4 10.0.1.25

If ping requests fail while the tunnel is UP, verify that the target EC2 instance's Security Group allows inbound ICMP traffic from your on-premises CIDR (192.168.10.0/24) and that your VPC Route Table includes a route pointing to the Virtual Private Gateway.