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.
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:
- Virtual Private Gateway (VGW): The managed VPN concentrator on the AWS side attached directly to your target VPC.
- Customer Gateway (CGW): A configuration object in AWS representing your external on-premises appliance's static public IP address and BGP Autonomous System Number (ASN).
- VPN Connection: The construct linking the VGW and CGW. It defines pre-shared keys (PSK), encryption algorithms, and routing rules (Static or Dynamic BGP).
- On-Premises IPSec Software: An appliance (such as Cisco ASA, FortiGate, or an open-source Linux gateway running
OpenswanorLibreswan) that handles encryption handshakes and routing.
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:
- UDP Port 500 (IKE): Internet Key Exchange protocol used for Phase 1 security association negotiation.
- UDP Port 4500 (NAT-T): Required if your on-premises gateway resides behind a Network Address Translation router.
- IP Protocol 50 (ESP): Encapsulating Security Payload protocol handling encrypted traffic payload.
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.