Amazon AWS VPC Setting up OpenVPN server

Posted on Friday, December 14, 2012



This assumes you already have a VPC set up and working.

I am still new to the VPC world, but from what I have read it seems that the virtual VPN service that Amazon provides is intended for a hardware based VPN, site to site.   Aside from that it costs $0.05 per hour connection.

In this tutorial I am going to set up a OpenVPN server on Ubuntu 12.04 LTS server within my VPC.   Once I get that working I am additionally going to turn that OpenVPN server into a NAT server to replace my current NAT server and save some money.

The best information I found on the web one how to do this was a video at http://dbsgkhvbz3k7m.cloudfront.net/AmazonVPC/AmazonVPC.html [1]



My current system is set up like this with a private and public subnet and a running NAT serving as a gateway for the private network.
                                       


Create an Ubuntu instance


This instance will serve as the OpenVPN server.  I am using Ubuntu 12.04 LTS

Set up a VPC security group

Before I can create this instance I need to create a new VPC security group for it.
























From the VPN console open Security Groups and click on Create Security Group

















Name it openvpn and associate it with your VPC, then click create.

















Select the Details tab and make not of the group ID,  in this case its
sg-cd7c94a2






















Select the Inbound tab and select the SSH rule and click Add Rule.
























Select Custom UDP rule set the port range to 1194 for OpenVPN.  Click Add Rule.


























Select Custom TCP rule and enter 943 for the port range click Add Rule.



























Select Custom TCP rule and enter 946 for the port range and click Add Rule

























Select HTTPS and click Add Rule

























Click Apply Rule Changes.






Here are the Security rules







Select Subnets and copy the ID of the public subnet, in my case its subnet-4c657627



Start the instance

Now start the instance


              >   ec2-run-instances ami-9c78c0f5 -b /dev/sda1=:8:true -k pats-keypair -t t1.micro -s subnet-4c657627 -g sg-cd7c94a2 --private-ip-address 10.0.0.99 --availability-zone us-east-1a







Change Source /Dest Check















From the EC2 console select the newly made  instance and right click and select “Change Source / Dest Check”


















Click Yes, Disable

Give it an elastic IP






















From the VPC console select Elastic IPs and click Allocate New Address

















Make sure its set to VPC and click Yes, Allocate


















Click on associate Address

























Select the instance that was just created and click on Yes, Associate



SSH into the new instance


To confirm its up and running SSH into this box


              >   ssh -i .ec2/pats-keypair.pem ubuntu@107.23.79.220







Install OpenVPN

You need to download the OpenVPN software from openvpn.net.  This version of the software is free to use for two users, otherwise it costs $5 per user per year, but require a minimum of 10 users so $50 per year, which is not a bad deal.  https://openvpn.net/index.php/access-server/pricing.html [2]

From the OpenVPN machine run the following commands


              >   wget http://swupdate.openvpn.org/as/openvpn-as-1.8.4-Ubuntu10.amd_64.deb
              >   sudo dpkg –i openvpn-as-1.8.4-Ubuntu10.amd_64.deb


After the install is done you will see the admin web interface address displayed











The admin needs a password for the openvpn user run the following command to set it.



              >  sudo passwd openvpn


I just set mine to adminpass for test purposes.

Configure OpenVPN


Open up OpenVPN admin web page at
https://107.23.79.220:943/admin

Of course enter your static IP address for it.



You will see something like this,  click on proceed anyway





















The admin login page will now display.  Enter the user name openvpn and the password you assigned to that user, then click Sign in










 Click Agree for the license terms











Click on Server Network Settings









Enter the Elastic IP address in the hostname field






















Scroll to the bottom of the page and click Save Settings













Click Update Running Server
























Click on VPN settings























Scroll down to the routing section and add all your subnets to this section.  I only have 2 subnets 10.0.0.0/24 and 10.0.1.0/24























Scroll down and click Save Settings






















Click on Update Running Server



Set up Client machine

Open up https://107.23.79.220/  in a web browser (change the IP address for your own.

























Login as the openvpn user and click go































Click on “Click here to continue”  This will download software you need to your system to connect to this VPN













Install the software,  on a windows machine you can right click on the download and click Open
























Then click Run















This window should pop up,  click Yes to create the tunnel.




























The web site should now report that it is up.

To test this out I am going to attempt to ssh into my instances
I have the following instances

10.0.0.20
10.0.1.30
10.0.0.25 NAT from aws
10.0.0.99

Test Connection


From my cygwing command line


              >  ssh -i .ec2/pats-keypair.pem ubuntu@10.0.0.20




              >  ssh -i .ec2/pats-keypair.pem ubuntu@10.0.1.30




              >   ssh -i .ec2/pats-keypair.pem ec2-user@10.0.0.25




              >   ssh -i .ec2/pats-keypair.pem ubuntu@10.0.0.99









That worked perfectly



























To disconnect from the VPN simply click Disconnect on the web page.   Closing the web page will not disconnect.



Alternatively, on windows, you can use the taskbar OpenVPN tool


















Click on the Taskbar OpenVPN tool to open it





















Then select Disconnect





















You do not have to use the web site to connect you can use the taskbar.  Click on it then click on Connect to….

























This will pop up a login prompt, enter you name/password then click Connect



Setting the OpenVPN server as the NAT Server also


In my case this OpenVPN server is not going to carry a heavy load, so I would like to also use it as my NAT server for my private network.  This would replace my NAT instance currently running in my public subnet and save me a few bucks a month.

I found some information on how to set up a NAT here
http://wiki.strongswan.org/projects/strongswan/wiki/AwsVpc [3], but that information did not work for me the best information I got was from https://forums.aws.amazon.com/message.jspa?messageID=335757 [4]
in here the person launched a NAT provided by Amazon and copied /usr/local/sbin/configure-pat.sh and updated /etc/rc.local


Update /usr/local/sbin/configure-pat.sh


              >  sudo vi /usr/local/sbin/configure-pat.sh


And place the following text in it.


#!/bin/bash

# Configure the instance to run as a Port Address Translator (PAT) to provide
# Internet connectivity to private instances.
#

set -x
echo "Determining the MAC address on eth0"
ETH0_MAC=`/sbin/ifconfig  | /bin/grep eth0 | awk '{print tolower($5)}' | grep '^[0-9a-f]\{2\}\(:[0-9a-f]\{2\}\)\{5\}$'`
if [ $? -ne 0 ] ; then
   echo "Unable to determine MAC address on eth0" | logger -t "ec2"
   exit 1
fi
echo "Found MAC: ${ETH0_MAC} on eth0" | logger -t "ec2"


VPC_CIDR_URI="http://169.254.169.254/latest/meta-data/network/interfaces/macs/${ETH0_MAC}/vpc-ipv4-cidr-block"
echo "Metadata location for vpc ipv4 range: ${VPC_CIDR_URI}" | logger -t "ec2"

VPC_CIDR_RANGE=`curl --retry 3 --retry-delay 0 --silent --fail ${VPC_CIDR_URI}`
if [ $? -ne 0 ] ; then
   echo "Unable to retrive VPC CIDR range from meta-data. Using 0.0.0.0/0 instead. PAT may not function correctly" | logger -t "ec2"
   VPC_CIDR_RANGE="0.0.0.0/0"
else
   echo "Retrived the VPC CIDR range: ${VPC_CIDR_RANGE} from meta-data" |logger -t "ec2"
fi

echo 1 >  /proc/sys/net/ipv4/ip_forward && \
   echo 0 >  /proc/sys/net/ipv4/conf/eth0/send_redirects && \
   /sbin/iptables -t nat -A POSTROUTING -o eth0 -s ${VPC_CIDR_RANGE} -j MASQUERADE

if [ $? -ne 0 ] ; then
   echo "Configuration of PAT failed" | logger -t "ec2"
   exit 0
fi

echo "Configuration of PAT complete" |logger -t "ec2"
exit 0


Make it executable


              >  sudo chmod u+x /usr/local/sbin/configure-pat.sh



Edit /etc/rc.local



              >  sudo vi /etc/rc.local


Adding the following line


/usr/local/sbin/configure-pat.sh







Save it and reboot the machine 




              >  sudo reboot now





Switch NATs






















From the VPC console select find the id of the private subnet.  In my case its subnet-4f657624









Select the Route Tables and select the Route table that is not associated with a subnet.

















Click on Remove, to remove the route to the NAT.
















Click on Yes, Delete.









Enter 0.0.0.0/0 for the destination.  For the target choose the OpenVPN instance and click Add















Click Yes, Create


Test to make sure the NAT is working

With a OpenVPN tunnel open ssh into the server on the private network 10.0.1.30 in my case


              >   ssh -i .ec2/pats-keypair.pem ubuntu@10.0.1.30



Now make sure it has access to the internet, by pinging google.com


              >   ping google.com


And it did not work……..

This is because I failed to let the NAT instance and the private cloud instances see each other.
I have a vpc security group that can see itself







To do this yourself you can choose a group



















Select All Traffic.  Enter the security group and click Add Rule.  Then click Apply Rule Change.

My instance on the private subnet already has the see-each-other security group assigned to it.   I need to assign this security group to the OpenVPN server.










From the EC2 Console select the OpenVPN server, right click and select “Change Security Groups”

EC2 Servers run in the VPC can have more than one security group assigned to it.























Hold the ctrl key and select see-each-other security group and click Yes, Change.




Test Connection

 Shut down the original NAT instance


























Right click on the original NAT server and select stop.
























Click on Yes, Stop




























Open https://107.23.79.220/?src=connect   and connect to the VPN


Log onto a machine that is in the private network, in my case machine 10.0.1.30 is in the private network.


              >   ssh -i .ec2/pats-keypair.pem ubuntu@10.0.1.30



Once you are in ping www.google.com


              >   ping www.google.com


 That is working.

Then try wget


              >  wget www.google.com



That worked






References
[1]  Amazon Virtual Private Cloud
       Visited 11/2012
[2]  OpenVPN pricing Guide
       Visited 11/2012
[3]  Setting Up a VPN into Amazon's Public Cloud VPC
       Visited 11/2012
[4]  Convert EC2 regular instance into NAT
       Visited 11/2012

9 comments:

  1. Thanks for your help. I needed a little more redundancy, but the general steps were sufficient to get started. If anyone wants, I blogged about my experience with OpenVPN and VPC.

    ReplyDelete
    Replies
    1. Good article, should I ever have a need to bridge a local network with an AWS VPC network I am glad you put up that article it gives me a leg up.

      Delete
  2. Replies
    1. Thanks for the feedback. I only give back a little what I take from the giant pool of information on the internet :)

      Delete
  3. This is a great write up and helped me, the only part that can be added is the client setup on linux.

    ReplyDelete
  4. Hello,

    Thank you for your post, I would like to know if there is a way the private network hosts can access the client network. I can access these hosts from my computer but I need bidirectional communication, is there a way to configure it? Thank you for your help!

    ReplyDelete
  5. Very nice article - I'm trying to connect to a web server on the private subnet but it doesnt work. I can start the openVPN client and can ping and ssh using the internal IP address (which I cant do whilst the openvpn client is disconnected, then can only connect with the public IP) but when i try to access the url of the internal IP address, i get a timeout.

    Any ideas what i might be missing ?

    I turned off my local firewall (Mcafee) and also modified the security group to allow all traffic on both the VPN server and web server but this didnt help either and i dont see anything in the webserver logs so seems it's getting lost somewhere in the VPN server. ( PS I used a t1.micro instance of the OpenVPN Access server appliance so didnt need to download and install openVPN manually)

    One thing i noticed was that you also enabled port 946 but this wasnt listed in the OpenVPN documentation - what is that port for ?

    ReplyDelete
  6. Awesome Comments and notes

    I setup the VPN/VPC using an OpenVPN AMI from Amazon;
    Completed the loop back using an Amazon NAT server

    To use the OpenVPN machine to complete the loop back

    The two important pieces are the
    script /usr/local/sbin/configure-pat.sh

    and executing this script in /etc/rc.local

    I disabled the source/destination check for the OpenVPN machine; added that on the Private Subnet Route Table

    Viola; I struggled for almost a whole day with this before bumping into the script on this page by Patrick!!!

    Thank you for this blog

    ReplyDelete