OpenVPN server on Amazon EC2

I was recently asked to set up a personal VPN for a friend here in Beijing and thought I’d share my process. I went with Amazon’s EC2 service because they have a reasonable choice of DC locations and their “micro” instances are free to trial for one year.

I’m assuming that you already have an AWS account, if not then create one and login to the EC2 console to follow along.

Provision the EC2 instance

Launch a new “micro” instance using the latest Amazon Linux AMI image. Don’t forget to save the PEM keyfile.

Create & assign a new Security Group (I called mine “openvpn” but name isn’t important) and open the following ports: 22 (TCP) and 1194 (TCP & UDP).

Login via SSH using the PEM file you downloaded and run the initial updates:

$ ssh ec2-user@[ec2-hostname] -i path/to/keyfile.pem

$ sudo yum upgrade

Install OpenVPN

Enable the EPEL repository which contains the openvpn package. EPEL is installed by default but not enabled, so edit /etc/yum.repos.d/epel.repo and change the enabled=0 line to enabled=1. It should look like this:

[epel]
name=Extra Packages for Enterprise Linux 6 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch
failovermethod=priority
enabled=1
#includepkgs=pkg1,pkg2,pkg3
includepkgs=fcgi-devel,fcgi,spawn-fcgi
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6

Then install as normal via yum:

$ sudo yum install openvpn

Configuring the OpenVPN server

Please note: at this point you can follow any of the usual openvpn guides found online. I opted for a TUN configuration using a pre-shared key for simplicity. This works fine for the purpose of tunneling all network traffic to circumvent the GFW here. Your needs may vary, so please read the openvpn manpage and the online docs.

Firstly we need to generate the pre-shared key. This isn’t user-specific so I put it in the system config directory:

$ sudo openvpn —genkey —secret /etc/openvpn/key.txt

Also in the config directory is the openvpn.conf file which should look like this:

dev tun
port 1194
proto udp
secret key.txt
ifconfig 192.168.2.1 192.168.2.2
keepalive 10 120
comp-lzo
persist-key
persist-tun
status server.log

You’ll also need to enable IP forwarding in the openvpn initialisation file in /etc/init.d/openvpn. Open the file in an editor and search for “ip_forward”. Uncomment the line, save and exit. It should look like this:

echo 1 > /proc/sys/net/ipv4/ip_forward

Finally, start the server process:

$ sudo service openvpn start

Configure the firewall for forwarding/masquerading

The openvpn server can’t do much except accept packets unless you configure iptables appropriately. Edit /etc/sysconfig/iptables with the following:

*nat
:POSTROUTING ACCEPT [0:0]
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -s 192.168.2.0/24 -d 0.0.0.0/0 -o eth0 -j MASQUERADE
COMMIT

Restart iptables to load the new config:

$ sudo service iptables restart

Lastly, set both openvpn and iptables to start on boot:

$ sudo chkconfig openvpn on && sudo chkconfig iptables on

OpenVPN client config

All clients will need a copy of the /etc/openvpn/key.txt file and the following config file:

dev tun
proto udp
remote [your ec2 hostname goes here] 1194
resolv-retry infinite
nobind
secret key.txt
ifconfig 192.168.2.2 192.168.2.1
comp-lzo
dhcp-option DNS 172.16.0.23
redirect-gateway def1

I tested this using the Windows OpenVPN client from openvpn.se, but it should work fine with any client so long as you put key.txt and ec2.ovpn in their openvpn/config directory.