AWS Site-to-Site VPN: Connecting On-Premise to Cloud
A step-by-step guide to establishing a secure IPSec tunnel between a corporate VPC and a remote network using both Manual Configuration (Openswan) and Terraform.
The Scenario
In this guide, we simulate a real-world hybrid cloud environment. We will connect a "Company HQ" (VPC A) to a "Remote CEO Office" (VPC B/On-Prem). While we use two VPCs for demonstration, the "CEO Office" acts exactly like a physical on-premise data center firewall.
1. Manual Configuration (The Hard Way)
Understanding the manual setup is crucial for debugging. We will configure the AWS side first, then the Linux-based router (Openswan) on the remote side.
Virtual Private Gateway (VGW)
Attached to the AWS VPC. Think of this as the "AWS side anchor" of the VPN cable.
Customer Gateway (CGW)
A logical representation of your remote device. It defines the IP address of the "Remote side anchor."
Step-by-Step AWS Setup
- VPC Creation: Create two VPCs with non-overlapping CIDRs (e.g.,
10.0.0.0/16and192.168.0.0/16). - Create VGW: In the VPC Dashboard, create a Virtual Private Gateway and Attach it to the "Company VPC".
- Create CGW: Create a Customer Gateway. Crucial: Use the Static Public IP of the "CEO/Remote" EC2 instance.
- Route Propagation: Go to Route Tables → Route Propagation → Enable. This automatically adds VPN routes.
- Create Connection: Create the Site-to-Site VPN Connection. Select the VGW and CGW created above.
Configuring Openswan (The Remote Router)
Once the VPN status is Pending in AWS, download the Generic Vendor Configuration file. SSH into your "Remote" EC2 instance (acting as the on-prem router).
1. System Configuration:
# Install Openswan
yum install openswan -y
# Enable IP Forwarding (Crucial for routing traffic)
vim /etc/sysctl.conf
# Add:
net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
# Apply changes
sysctl -p
2. Define the Secret Keys:
Edit /etc/ipsec.d/aws.secrets. Replace the IPs with the Tunnel 1 Outside IP from your AWS config file.
# Format: [Customer_Public_IP] [AWS_Tunnel_IP]: PSK "Your_Pre_Shared_Key"
54.12.34.56 203.0.113.10: PSK "mx_8473..."
3. Configure the Tunnel:
Edit /etc/ipsec.d/aws.conf.
conn Tunnel1
authby=secret
auto=start
left=%defaultroute
leftid=54.12.34.56 # Your EC2 Public IP
right=203.0.113.10 # AWS Tunnel IP
type=tunnel
ikelifetime=8h
keylife=1h
phase2alg=aes128-sha1;modp1024
ike=aes128-sha1;modp1024
4. Start Service: service ipsec start
2. Terraform Automation (The Easy Way)
For production environments, Infrastructure as Code (IaC) is preferred to ensure consistency. Below is a concise Terraform module to deploy the AWS side of the architecture.
resource "aws_vpn_gateway" "main" {
vpc_id = aws_vpc.company_vpc.id
tags = { Name = "Main-VGW" }
}
resource "aws_customer_gateway" "remote" {
bgp_asn = 65000
ip_address = var.remote_public_ip
type = "ipsec.1"
tags = { Name = "Remote-Office-CGW" }
}
resource "aws_vpn_connection" "site2site" {
vpn_gateway_id = aws_vpn_gateway.main.id
customer_gateway_id = aws_customer_gateway.remote.id
type = "ipsec.1"
static_routes_only = true
}
resource "aws_vpn_connection_route" "office" {
destination_cidr_block = var.remote_cidr
vpn_connection_id = aws_vpn_connection.site2site.id
}
variable "remote_public_ip" {
description = "The Public IP of the On-Prem Firewall"
}
variable "remote_cidr" {
description = "The internal network of the remote office"
default = "192.168.1.0/24"
}
3. Verification & Troubleshooting 🔧
The configuration is only half the battle. Here is how to verify the tunnel is actually passing traffic.
Status: UP for at least one tunnel. If it says DOWN, check your Security Groups to ensure UDP port 500 and 4500 are open.
ping 192.168.1.50. Note: Pinging the Public IP will go over the internet, not the VPN. Always ping private IPs to test the tunnel.