How to add NAT to an existing EC2 instance in an AWS VPC

December 11, 2012 - 2 minute read -

I’m in the process of moving infrastructure from the AWS public cloud into a VPC, and since my VPC has private subnets, I need NAT to allow machines in these subnets to open connections to S3, Ubuntu repos, etc. The VPC wizard can create a NAT EC2 instance for you, but I’m a penny pincher and didn’t want to dedicate a whole instance just to NAT - e.g. I also wanted to use it as my VPN server.

But I couldn’t find specific instructions on exactly how to add NAT to an existing instance with a single NIC (most solutions require two NICs in a standard gateway configuration, one for the LAN IP and one for the WAN IP, which you can actually do with VPC, but why do it if you don’t have to?). After a bit of research and some reverse engineering of the AWS NAT solution, here’s what I came up with:

  1. In the EC2 console, disable source/dest checking by right clicking on the instance you want to use for NAT and choosing “Change Source / Dest Check”.
  2. Create a security group having an inbound rule allowing ALL from 10.0.0.0/16 and associate it with your NAT instance.
  3. On the NAT instance, create /etc/network/if-pre-up.d/nat-setup as:
    #!/bin/sh
    echo 1 > /proc/sys/net/ipv4/ip_forward
    iptables -t nat -A POSTROUTING -s 10.0.0.0/16 -j MASQUERADE
    
  4. chmod +x the script, then run it. This script will automatically be run when the machine reboots, so your NAT will survive a restart.
  5. Make sure all your private subnets have a default route to use the NAT instance as a gateway (create a route for 0.0.0.0/0 and associate it with your NAT instance in the route table(s) associated with your private subnets).
  6. test your NAT by pinging something from an EC2 instance in a private subnet

Note: the NAT instance needs to have an Elastic IP, of course.