Wednesday, April 15, 2015

Configuring an AWS Customer Gateway Behind a NAT

I have been wanting to configure a VPN Connection from AWS to my house, but my cheap Netgear router does not support IPSec. So, I picked up an old Cisco 871 router that does. I didn’t want to sacrifice the speed (it supports 802.11ac while the 871 is an old 802.11g device) and features of my Netgear router, so I put the 871 behind the Netgear and modified the VPN configuration for NAT traversal.
The 871 (or a similar device) is a great way to get some hands on experience configuring a Virtual Private Gateway. Despite its age, the 871 is actually a capable device and it’s available on eBay for less than $100. While most production implementations will not require NAT traversal, this is also good experience. You may want to peer two VPCs (in the same or different regions) and one common solution is to use two Cisco CSR1000V (available in the AWS Marketplace). In this configuration both CSR100V devices will require an Elastic IP, which uses NAT.

My configuration looks like the diagram below. I am using a Netgear router, but any router will work. My cable provider has assigned the address to my Netgear router which also has a private address of I have assigned the Cisco 871 a static IP address of (make sure to exclude this from the DHCP pool on the router). My AWS VPC has the CIDR block I have configured a static route on the Netgear that forwards all traffic destined for to In addition, I added a port forwarding rule to the Netgear that forwards UDP port 500 to

In the AWS VPC console, I created a VPN Connection as shown below. Note that I have entered the public IP address of the Netgear router ( as the IP address of a new Customer Gateway. I also configured static routing and entered the CIDR block of my home network (

Once the VPN connection is created you can download the router configuration. I choose a Cisco Systems ISR Series Router. In order to support NAT traversal you will need to modify the configuration slightly. You need to find the six places where the public IP address appears and replace it with the private IP address of the IPSec router. Not that there will two of each of the highlighted sections below, one for Tunnel1 and one for Tunnel2.
crypto keyring keyring-vpn-d67b98bf-0  
  local-address !Replace with
pre-shared-key address key XXXXXXXXXXXXXXXXX
crypto isakmp profile isakmp-vpn-d67b98bf-0
  local-address !Replace with
  match identity address
  keyring keyring-vpn-d67b89bf-0

crypto ipsec fragmentation before-encryption
interface Tunnel1
  ip address
  ip virtual-reassembly !Protects against Fragment attacks
  tunnel source !Replace with
  tunnel destination 
  tunnel mode ipsec ipv4
  tunnel protection ipsec profile ipsec-vpn-d67b98bf-0
  ! This option causes the router to reduce the Maximum Segment Size of
  ! TCP packets to prevent packet fragmentation.
  ip tcp adjust-mss 1387 
  no shutdown
In addition, I needed to change the ip sla timeout because the 871 is too old to support the default value, but this is unique to the 871.
ip sla 100
   icmp-echo source-interface Tunnel1
   timeout 1000 !AWS uses 1000.  Min on 871 is 5000.
   frequency 5
With static routing AWS is not advertising routes over the VPN tunnel. Therefore, I had to add the route statements to the 871 manually. The first statement uses the default administrative distance of 1 and therefore tell the router to prefer Tunnel1. If SLA 100 fails, this route will be removed and Tunnel2 with administrative distance of 10 will take over.
ip route Tunnel1 track 100
ip route Tunnel2 10 track 200

Extra Credit: Securing the Home Network

In order to protect my home network from nefarious traffic from AWS, I added a “firewall” policy using inspect statements on the 871. The ACL defines what is allowed from AWS. In this case, just ping for testing. All traffic to AWS is allowed and the inspect rules open the return path for any traffic initiated from my house. SSH and FTP defines high level inspect rules specific to these protocols.
ip inspect name TrafficToAWS tcp
ip inspect name TrafficToAWS udp
ip inspect name TrafficToAWS icmp
ip inspect name TrafficToAWS ssh
ip inspect name TrafficToAWS ftp

ip access-list extended TrafficFromAWS
 permit icmp any any echo
 permit icmp any any echo-reply
 !NOTE: echo-reply needed for sla ping

interface Tunnel1
 ip access-group TrafficFromAWS in
 ip inspect TrafficToAWS out
interface Tunnel2
 ip access-group TrafficFromAWS in
 ip inspect TrafficToAWS out
This is when it gets interesting. While my configuration gives priority to Tunnel1 when sending traffic to AWS, AWS uses both tunnels for return traffic. The issue is that the inspect rules only allow return traffic on the tunnel it exited. Therefore, if a request goes out Tunnel1 but the response is received on Tunnel2, the router will block it. I simply disabled Tunnel2, sacrificing redundancy, but plan to dig into this a bit deeper when I get a chance. If you beat me to it, let me know how you fixed it.


  1. Thats what I have been looking for - guidance to simulate CGW from home.. eventually I moved to the second page on Google Search.

    Thanks Brian!!

  2. I have a single Ec2 instance on a VPC with a dedicated static ip vpn which I host a web application on. It runs on Windows sever 2012. I remote desktop to the server to manage it. I recently setup a customer gateway, a virtual private gateway and a VPN to the VPC my host runs on from our corporate network. I passed the config file it generated over to our network team but I soon realised the connection over the external/elastic IP went down. I can no longer ping, RDP or access the web application. I cannot seem to figure out how to get this back up and running again. Any help?