Setting up a VPN-server on Amazon EC2

Amazon has recently announced the new Micro Instances in their Elastic Cloud service. A so called Micro Instance is a virtual machine with 620 MB main memory and CPU power in the area of an 1 GHz Opteron processor. The advantage of the Micro Instance is its low cost of only $0.02 per hour of operation (be advised, there are some additional costs for traffic and storage).

The EC2 Micro Instance is an ideal way to operate your own VPN-server, when you need it only a couple of hours per month. Let’s assume, that you want to use it for about 50 hours per month with around 10 GB of traffic, this means $1.00 for computation time + $1.50 for 15 GB of storage + $1.50 for 10 GB outgoing traffic. So for $4 this is quite a good offer. Granted, you can find commercial VPN providers for $5 per month, but it is more fun to do it yourself. In this article I will describe, how to setup an EC2 instance as a VPN-server.

I choose to setup a PPTP server. PPTP is not the most secure type of VPN, but it has the big advantage, that it is the most compatible. Nearly every OS is able to open a PPTP connection without additional software and this includes mobile devices like iPhones/iPads.

First, you need to choose a base image to boot in the Micro Instance. I have selected an 32-bit Ubuntu 10.04 server image. The AMI-ID of this image is ami-6c06f305. Start this image in a Micro Instance and log in with your SSH-key. For more details on these steps, refer to the AWS documentation.

Once you are logged in, you can install the pptp-daemon:

sudo aptitude install pptpd

Configuring the pptp-daemon is a breeze. First you to define an IP address range which will be used for connected clients. This can be any IP range, but keep in mind, if you want to avoid routing problems, choose a private IP range. Uncomment and modify 2 lines at the end of /etc/pptpd.conf:

localip 192.168.240.1
remoteip 192.168.240.2-9

With the above settings, the pptpd server will get the address 192.168.240.1 and there are 8 possible client addresses 192.168.240.2 to 192.168.240.9.

It is also a good idea to specify the address of at least one DNS server. You can use the DNS server of amazon (172.16.0.23) or the Google Public DNS. I choose the latter. Open the file /etc/ppp/pptpd-options and make sure it contains the following settings:

ms-dns 8.8.8.8
ms-dns 8.8.4.4

The last step for configuring the pptpd-daemon is to add a user account for the service:

echo "USERNAME pptpd PASSWORD *" | sudo tee -a /etc/ppp/chap-secrets

Replace USERNAME and PASSWORD with whatever credentials you like. It is possible to add as many users as you like.

Now restart the pptp-daemon:

sudo /etc/init.d/pptpd restart

It is already possible to open a PPTP-connection to the server, although no traffic will be forwarded to the Internet. We still need to enable packet forwarding and network address translation on the server.

To enable packet forwarding, uncomment the following line in /etc/sysctl.conf:

net.ipv4.ip_forward=1

Now reload this config:

sudo sysctl -p

The last step is to enable network address translation:

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

This setting is reset on every reboot, so make sure that you add the following line above exit 0 in the file /etc/rc.local:

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Now the VPN server is fully functional. The only small problem is, that the server will get a new IP address every time you reboot it. I would recommend using a dynamic dns-provider to assign this machine a unique domain name. I am using DynDNS.

The ddclient is a great little tool to update the current IP address on a number of different dynamic DNS services. Installation is done as usual:

sudo aptitude install ddclient

Once installed, the configuration is done in the file /etc/ddclient.conf. It will already contain some usefull settings, because the installer will require you to enter some information about the DNS service you are using. In the end the configuration should look something like this:

protocol=dyndns2
use=web, web=checkip.dyndns.com/, web-skip='IP Address'
server=members.dyndns.org
login=LOGINNAME
password='PASSWORD'
DOMAINNAME.dyndns.org

Replace LOGINNAME, PASSWORD and DOMAINNAME.dyndns.org with your own settings. The most important line is the one starting with use=. This defines that the registered IP-address is detected by DynDNS itself. This is neccessary, because the virtual machine is running with a private IP address.

That’s it! Now you have your own VPN-server up and running. Just start the instance in the AWS Management Console whenever you need it.

Update:

Here is a screenshot of the security groups setup I am using:

Update 2:

Please take a look at my follow up posting on how to connect to the VPN from an iOS or Android device.

  • http://www.dikant.de/ Peter Dikant

    Both ip addresses need to be in another subnet than your home network. Just keep the values from the blog posting. That should work in most cases.

  • Arunmainthan Kamalanathan

    How to connect to the VPN configured in the amazon ece2 side from my person ubuntu desktop, I have a domain name configured in the amazon EC2 as well.

  • http://www.dikant.de/ Peter Dikant

    Didn’t try it myself, but it should be easy. Click on “VPN Connections -> Configure VPN”, then press the “Add” button and select PPTP as the connection type. Now enter the ip address or the full hostname of your EC2 instance in the field “Gateway” and also enter username and password. Should work out of the box.

  • Arunmainthan Kamalanathan

    It worked , I had the problem with the password format. For the below format it worked (2 * signs ) .

    username * Pa55w0rd *

    You are very helpful. Thank you very much.

  • Hairihan Tong

    HI, Thanks for your post. I followed your steps before “DynDNS.” ,it should be works wellI.However,I have trouble with some problem. Could you help me? The followings are the Security group of My instance and log files and the EC2.

    (At EC2)$tail -f /var/log/auth.log /var/log/syslog

    Is there any problem? Thank you very much

  • http://www.dikant.de/ Peter Dikant

    This seems to be a handshake problem. Your security groups basically open up everything. If you open the port range 0-65535 on both tcp and udp, you don’t need to open specific ports additionally. But this should not be the problem.
    Take a look at your client log. Maybe there are more specific information there why the connection fails.

  • Karl Girthofer

    Hey thanks for the artical! This worked great for me; I’m just having one problem, I’ve gotten everything connected, but nothing on the VPN can communicate… EC2 cloud LAN is 10.0.0.X, my local LAN is 192.168.10.X and my VPN LAN is 192.168.0.X; things on the VPN can ping to the cloud lan (192.168.0.X –> 10.0.0.X) but the other way around doesn’t work; also nothing on the VPN LAN can communicate (192.168.0.X –> 192.168.0.X) {This is all exempt from the actual server it’s self… everything can talk to it, and it can talk to everything…
    What am I missing?

    any help would be greatly appreciated!

  • ucs75

    To clarify….

    They should both be in the SAME subnet, which must be different than your existing local subnet.

    localip is the VPN Server’s PRIVATE-VPN ip address
    remoteip is the range of addresses that a client will be assigned.

    They need to be on the same subnet to reach each other.
    This subnet (aka “network”) IS the Virtual Private Network