Recently I have been working on the growing need of a private cloud to utilize ec2 instances in a secure environment. Right now I have a network behind a Cisco ASA which acts as the front end, and does what I need it to do. I started looking into Amazon VPC since I could create an IPSec tunnel directly from my network behind the ASA into the Amazon Cloud. Then I realized the big issue after reading into how cool it was, the ASA alone wasn’t compatible with VPC. This of course was a major downer, since I didn’t want to purchase new hardware and redesign my network just to get a private cloud working. I immediately started searching for alternative options, yet it seems like there were a few that could fit but didn’t exactly do what I wanted. One of those options was VPNCubed, which is awesome software they did a great job I must say. The only issue I ran into it besides pricing was the fact I couldn’t just spin up an instance and have it dynamically be assigned a private address. I had to assign a static private ip to each instance with some cert stuff that I didn’t bother looking into. I was told later by support I could utilize their API in order to do this, but one of my core components in needing the private cloud was that another server would be spinning up instances on demand, and I couldn’t script in their API to tie into this process (I’m not going to get into this, just believe me). Anyways, I started reading about the possibility of using OpenVPN somehow, but it appears that it doesn’t support IPSec tunnels (please correct me if im incorrect!), and I didn’t want another OpenVPN server running on my local network in order to communicate with that. I found some articles on OpenSwan and EC2 but nothing regarding VPC, which really surprised me. I saw numerous posts about it not working and such, but no guides on how to create the private network in the cloud and have a basic IPSec site-to-site path between the VPC and an ASA. It blew my mind to say the least… So I set out to get it working on my own, and I’m pleasantly suprised to say it was pretty damn easy.
- Allow communication between my local network and ec2 instances within the vpc and vice-versa
- Allow communication between ec2 instances within the vpc
- Communication between all paths must be somewhat secure
- The ability to have instances assigned a dynamic private address from a dhcp pool or a statically assigned private address
- The ability to have a few instances be able to route to the outside world, and have a publically accessable IP
The Network Layout:
The Network Diagram:
Getting Started (Amazon VPC):
First off we want to create our VPC via the Amazon AWS Management Console.
I pretty much followed the guide here: http://docs.amazonwebservices.com/AmazonVPC/latest/GettingStartedGuide/
- Go to the VPC tab
- Find the Your Virtual Private Cloud area, and click Get started creating a VPC.
- I chose VPC w/ a Single Public Subnet Only, along with the information I provided above in the layout.
- Follow the steps to create the VPC.
Adding the OpenSwan Server into your VPC:
- First we will need to Allocate a New Elastic IP within the VPC tab under Virtual Private Cloud -> Elastic IPs.This will be used for the openswan server.
- Once that is done, I went back to the EC2 tab, and launched an instance. I used the Basic 32bit Amazon Linux AMI
- I chose m1.small as my instance type
- Make sure to choose ‘Launch Instances Into Your Virtual Private Cloud’
- For instance details, I chose to assign it a private IP address of 220.127.116.11
- Chose my keypair, assigned it a name tag of ‘openswan server’
- For configure firewall, I chose allow all traffic (0.0.0.0/0) to start off, since I would be locking it down further after it’s setup.
- I then associated the elastic IP to the running instance after it started up.
- I ssh’d into the instance using my key (ssh -i my-key.pem email@example.com), and I was brought to a shell, yay!
Configure the instance w/ OpenSwan:
I found a great article here: (http://www.fragmentationneeded.net/2010/10/amazon-ec2-ipsec-tunnel-to-cisco-ios.html) which described the steps in connecting an ec2 instance to an IOS router. It worked great, so I thought I’d mention where I got the information from.
Here are the exact commands I ran after ssh’ing into the server, note the HOMEPUBLIC and HOMEPRIVATE should be changed according to your internal network:
sudo yum update -y
sudo yum -y install openswan openswan-doc ipsec-tools
EC2PRIVATE=`/sbin/ifconfig eth0|grep Bcast|cut -d: -f 2|cut -d\ -f 1`
EC2PUBLIC=`curl -s http://169.254.169.254/latest/meta-data/public-ipv4`
PSK=`< /dev/urandom tr -dc a-zA-Z0-9_ | head -c30`
echo “conn home” > /tmp/home.conf
echo ” left=%defaultroute” >> /tmp/home.conf
echo ” leftsubnet=$EC2PRIVATE/32″ >> /tmp/home.conf
echo ” leftid=$EC2PUBLIC” >> /tmp/home.conf
echo ” right=$HOMEPUBLIC” >> /tmp/home.conf
echo ” rightid=$HOMEPUBLIC” >> /tmp/home.conf
echo ” rightsubnet=$HOMEPRIVATE” >> /tmp/home.conf
echo ” authby=secret” >> /tmp/home.conf
echo ” pfs=yes” >> /tmp/home.conf
echo ” forceencaps=yes” >> /tmp/home.conf
echo ” auto=start” >> /tmp/home.conf
echo “$EC2PUBLIC $HOMEPUBLIC: PSK \”$PSK\”" > /tmp/home.secrets
sudo sed ‘s!^#\(include /etc/ipsec.d/\*.conf\)!\1!’ /etc/ipsec.conf > /tmp/ipsec.conf
sudo chmod 600 /tmp/home.* /tmp/ipsec.conf
sudo chown root:root /tmp/home.* /tmp/ipsec.conf
sudo mv /tmp/home.* /etc/ipsec.d
sudo mv /tmp/ipsec.conf /etc
sudo chkconfig ipsec on
sudo /etc/init.d/ipsec start
We need to do a couple more things as well:
net.ipv4.ip_forward = 1
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
At the end of this, I had OpenSwan up and running! I had /etc/ipsec.d/home.conf as my openswan configuration and /etc/ipsec.d/home.secrets as my preshared key! Awesome!
Configuring the ASA:
I’m trying my best to grep out the commands that I did here from config change logs, so please take this with a grain of salt. Anyone who has setup a site-to-site on an ASA should be familiar with this process already. All we are doing is creating a new site-to-site entry, using esp-3des-md5 and allowing access to and from this tunnel. (I know esp-3des-md5 is horrible, but this is how I got it working, I need to change it to sha-aes soon.)
ASA Configs: Make sure to BACKUP before making these changes!
tunnel-group 18.104.22.168 type ipsec-l2l tunnel-group 22.214.171.124 ipsec-attributes ! pre-shared-key (the key in /etc/ipsec.d/home.secrets on your openswan server)
I’m using crypto map priority 6, this doesn’t need to be 6.
crypto map outside_map 6 match address outside_cryptomap_6 crypto map outside_map 6 set pfs crypto map outside_map 6 set peer 126.96.36.199 crypto map outside_map 6 set transform-set ESP-3DES-MD5 crypto ipsec transform-set ESP-3DES-MD5 access-list outside_cryptomap_6 extended permit ip 10.10.0.0 255.255.255.0 188.8.131.52 255.255.255.0
Internal Network Group:
object-group myinternalnetwork description My Internal Network that Will connect to EC2 VPC network-object 10.10.0.0 255.255.255.0
NAT Entries allowing Access from my internal network to VPC:
access-list inside_nat0_outbound extended permit ip object-group myinternalnetwork 184.108.40.206 255.255.255.0
Boom! We should be all set on the ASA side. Save your changes!
Restarting IPSec on OpenSwan Instance:
- Log back into your openswan instance via ssh, and issue the commands sudo /etc/init.d/ipsec stop; sudo /etc/init.d/ipsec start
- You can check if the tunnel is up by issuing an /etc/init.d/ipsec status which should state if the tunnel is up or not, you can also check your ASA.
Fixing the routes in EC2:
In order for traffic to route properly on new instances and allow communication between your network and VPC instances we need to add a route in the AWS management console.
- Login to the AWS management Console
- Click on the VPC tab
- Click on Route Tables
- Click on the Route table ID that ISNT set as MAIN (It should say Main: No under the column)
- For destination put your local network subnet (from the above example, mine is 10.10.0.0/24) and for Target, choose the instance ID of the OpenSwan instance.
- Click Add
Fixing Your Security Groups:
You can now update your security group for the openswan server. For example, mine I have all traffic allowed from the external IP of my asa (220.127.116.11/32), and nothing else.
For new instances, you will want to have a new security group, and remember to allow the internal network to access these security groups, so for example in all security groups I allow all traffic from 10.10.0.0/24. This way I have communication both ways to the private vpc and from the private vpc to my network.
- I’m writing this at midnight after a long day, I’m sure there are errors. Please let me know what they are!!!!
- I haven’t been able to get communication to just work to the outside world from instances without an elastic IP associated to them. IE: instance4293 in the private VPC cloud can communicate between other instances in the private VPC and to my internal network, but not out to google.com… Not sure if this is a routing issue or a firewall rule, I haven’t had the time to check it out further, but please let me know if you know why!
- Enjoy and please comment! I hope to clean this up in the following weeks to be more of a step-by-step guide (especially the ASA part), but you should get the jist of it all!