My goal in this post is to show how to set up an OpenVPN server within an AWS VPC so that clients can connect to EC2 instances via a VPN connection. It's fairly well documented how to configure a site-to-site VPN with an AWS VPC gateway, but articles talking about client-based VPN connections into a VPC are harder to find.== OpenVPN server setup ==
Let's start with setting up the OpenVPN server. I launched a new Ubuntu 14.04 instance in our VPC and I downloaded the latest openvpn source code via:
In order for the 'configure' step to succeed, I also had to install the following Ubuntu packages:
apt-get install build-essential openssl libssl-dev lzop liblzo2-dev libpam-dev
I then ran the usual commands inside the openvpn-2.3.6 directory:
./configure; make; sudo make install
At this point I proceeded to set up my own Certificate Authority (CA), per the OpenVPN HOWTO
guide. As it turned out, I needed the easy-rsa helper scripts on the server running openvpn. I got them from github:
git clone https://github.com/OpenVPN/easy-rsa.git
To generate the master CA certificate & key
, I did the following:
cp vars.example vars
- edited vars file and set these variables with the proper values for my organization:
(this will create the correct directory structure)
(this will use the info specified in the vars file above)
To generate the OpenVPN server certificate and key
, I ran:
./easyrsa build-server-full server
(I was prompted for a password for the server key)
To generate an OpenVPN client certificate and key
for user myuser, I ran:
./easyrsa build-client-full myuser
(I was prompted for a password for the client key)
The next step was to generate the Diffie Hellman (DH) parameters for the server
I was ready at this point to configure the OpenVPN server
I created a directory called /etc/openvpn and copied the pki directory under ~/easy-rsa/easyrsa3 to /etc/openvpn. I also copied the sample server configuration file ~/openvpn-2.3.6/sample/sample-config-files/server.conf to /etc/openvpn.
I edited /etc/openvpn/server.conf and specified the following:ca /etc/openvpn/pki/ca.crtcert /etc/openvpn/pki/issued/server.crtkey /etc/openvpn/pki/private/server.key # This file should be kept secretdh /etc/openvpn/pki/dh.pem
server 10.9.0.0 255.255.255.0ifconfig-pool-persist /etc/openvpn/ipp.txt
push "route 172.30.0.0 255.255.0.0"
The first block specifies the location of the CA certificate, the server key and certificate, and the DH certificate.
The 'server' parameter specifies a new subnet from which both the OpenVPN server and the OpenVPN clients connecting to the server will get their IP addresses. I set it to 10.9.0.0/24. The client IP allocations will be saved in the ipp.txt file, as specified in the ifconfig-pool-persist parameter.
One of the most important options, which I missed when I initially configured the server, is the 'push route' one. This makes the specified subnet (i.e. the instances in the VPC that you want to get to via the OpenVPN server) available to the clients connecting to the OpenVPN server without the need to create static routes on the clients. In my case, all the EC2 instances in the VPC are on the 172.30.0.0/16 subnet, so that's what I specified above.
Two more very important steps are needed on the OpenVPN server. It took me quite a while to find them so I hope you will be spared the pain.
The first step was to turn on IP forwarding
on the server:
- uncomment the following line in /etc/sysctl.conf:
The final step in the configuration of the OpenVPN server was to make it do NAT via itpables masquerading
(thanks to rbgeek's blog post
for these last two critical steps):
iptables -t nat -A POSTROUTING -s 10.9.0.0/24 -o eth0 -j MASQUERADE
- also add the above line to /etc/rc.local so it gets run on reboot
Now all that's needed on the server is to actually run openvpn. You can run it in the foreground for troubleshooting purposes via:
Once everything works, run it in daemon mode via:
openvpn --daemon --config /etc/openvpn/server.conf
You will be prompted for the server key password when you start up openvpn. Haven't looked yet on how to run the server in a fully automated way.
Almost forgot to specify that you need to allow incoming traffic to UDP port 1194
in the AWS security group where your OpenVPN server belongs. Also allow traffic from that security group to the security groups of the EC2 instances that you actually want to reach over the OpenVPN tunnel.== OpenVPN client setup ==
This is on a Mac OSX Mavericks client, but I'm sure it's similar for other clients.Install tuntap
- download tuntap_20150118.tar.gz from http://tuntaposx.sourceforge.net
- untar and install tuntap_20150118.pkgInstall lzo
tar xvfz lzo-2.06.tar.gz
./configure; make; sudo make installInstall openvpn
- download openvpn-2.3.6.tar.gz from http://openvpn.net/index.php/open-source/downloads.html
tar xvf openvpn-2.3.6.tar
./configure; make; sudo make install
At this point â€˜openvpn --helpâ€™ should work.
The next step for the client setup is to copy the CA certificate ca.crt, and the client key and certificate (myuser.key and myuser.crt) from the OpenVPN server to the local client. I created an openvpn directory under my home directory on my Mac and dropped ca.crt in ~/openvpn/pki, myuser.key in ~/openvpn/pki/private and myuser.crt in ~/openvpn/pki/issued. I also copied the sample file ~/openvpn-2.3.6/sample/sample-config-files/client.conf to ~/openvpn and specified the following parameters in that file:
remote EXTERNAL_IP_ADDRESS_OF_OPENVPN_SERVER 1194
ca /Users/myuseropenvpn/pki/ca.crtcert /Users/myuser/openvpn/pki/issued/myuser.crtkey /Users/myuser/openvpn/pki/private/myuser.key
Then I started up the OpenVPN client via:
sudo openvpn ~/openvpn/client.conf(at this point I was prompted for the password for myuser.key)
To verify that the OpenVPN tunnel is up and running, I ping-ed the internal IP address of the OpenVPN server (in my case it was 10.9.0.1 on the internal subnet I specified in server.conf), as well as the internal IPs of various EC2 instances behind the OpenVPN server. Finally, I ssh-ed into those internal IP addresses and declared victory.
That's about it. Hope this helps!UPDATE
: I discovered in the mean time a very good Mac OSX GUI tool for managing client OpenVPN connections: Tunnelblick
. All it took was importing the client.conf file mentioned above.