I worry about data. I worry about whether it’ll be lost, compromised, or corrupted. I worry whether or not I am doing enough: did I check the backups, are they “good”, did any fail to run, do I have a “plan”, will it work? It is easier for me to get a handle on my fretting with regards to the server I tend but what about those assets that get to see the wider world and networks other than my own?
As a company, we are traveling more and it isn’t unusual for people to work from airports, coffee shops, clients, taxi cabs, or bars. Its just how business is getting done. But what about that data I worry about so much, both company and personal? Things like Firesheep intrigue me at the same time as leave me with the feeling that I need to do more for the people on the road.
The most obvious solution is to implement a VPN but which one, how, and moreover could we run it in our EC2 stack. I experimented with PPTP and loved the ease and simplicity of setting it up and it worked great with the built in OS X VPN client. However, once I left the free love environment that is my home network it was all but useless as I encountered plenty of public WiFi that disallowed TCP/1723. Next up was Openswan’s IPSec implementation, a complex beast full of options and configurations. It enjoyed wide support on the public networks I tried but, sadly, I seemingly could not get the built in OS X VPN client to consistently play nice. Last up was OpenVPN.
OpenVPN is easy to setup, configure, and roll out. We use it on our production servers as part of the CohesiveFT VPN-Cubed product that allows us to easily throw up IPSec tunnels with clients and hook it back stack so we know it is rock solid. The only drawback that I encountered with OpenVPN is that neither the iPad nor the iPhone support it so this does limit the devices that we can secure at the moment but life is about compromise.
Eric Hammond wrote an excellent article as a proof-of-concept for running OpenVPN over TCP/80 on EC2. Per usual he made it dead simple and easy to implement and with the slightest bit of finessing it can be adapted for rolling out to small teams.
For this I chose a micro instance running Ubuntu 10.04 for both the typical miserly and familiarity reasons. Prepping I ran with Hammond’s opening tasks:
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install openvpn -y
sudo modprobe iptable_nat
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
sudo iptables-save > /some/place/you/can/recall
sudo iptables -t nat -A POSTROUTING -s 10.4.0.1/2 -o eth0 -j MASQUERADE
Once that inital prep work was out of the way I hoped over to the official Ubuntu OpenVPN documentation where we can set up OpenVPN to use asymmetrical keys instead.
But first we need to make a couple of tweaks to the server config (/etc/openvpn/server.conf). Look for the following and adjust them:
server 10.4.0.0 255.255.255.0
The port and protocol is so that our tunnel will run over TCP/80 and this, in theory, let you toss up your tunnel on nearly any network that has access to the Internet. That said, I’ve tested this on my free love network, a tighter administered open WiFi where my daughter goes to school (this is the one that disallows TCP/1723), and my T-Mobile data plan and while it worked on all three your mileage may vary.
The next step is to create a CA for OpenVPN and generate keys for clients and the server. Rather than do that work in /etc/openvpn/ as suggested in the documentation I opted to perform all that work in another directory so we can easily manage it with tools like git or puppet.
sudo mkdir /mnt/easy-rsa/
sudo cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /mnt/easy-rsa/
sudo chown -R $USER /mnt/easy-rsa/
Adjust the variables in /mnt/easy-rsa/vars to best fit how you want things to look:
export KEY_ORG="Awesome Pancake, LLP"
Then, because the devs and maintainers are awesome, just run some handy scripts and you’ll be all set:
./pkitool --server server
openvpn --genkey --secret ta.key
sudo cp server.crt server.key ca.crt dh1024.pem ta.key /etc/openvpn/
Now we just need to generate some client certs:
Replace “jimmy” with whatever you want to name your client, I recommend easy to remember nicknames that will cause you to snicker when you use them.
Now for the clients, it all depends on the what you’ll be using to connect to the server with. For testing I tried Tunnelblick and while it’s FLOSS I found it to be a little harder to configure than Viscosity, which is an affordable commercial client. The additional benefit to Viscosity is that it will allow you create easy to distribute connection bundles that include the CA cert, client key, and client cert that you can distribute to your clients for importing.
Setting up Viscosity is about as easy as it gets, you’ll need the CA.crt, and the host key and cert that you created above. Since pictures are a more valuable currency:
Once that is all set, connect to your tunnel and marvel at your secure connection. To check how things look on the client you can check ifconfig to ensure that the tunnel was added:
Also, do a quick nslookup to ensure that DNS is going to EC2 rather than to the local network:
Viscosity as a nifty detail page for visualizing the traffic over the tunnel:
On the server you can use tcpdump to watch the traffic and make sure that it is flowing like you want:
sudo tcpdump -i tun0 | grep "ip-10-4-0-6.ec2.internal"
Where 10-4-0-6 is the same as the ip address given by the tunnel.
That’s pretty much it, very easy thanks to Eric Hammond and the Ubuntu documentation team. From here you could set up connections in Viscosity for each of your users, export a zipped connection and distribute it (securely, of course!).
The next big test will be setting up all our road warriors and asking them to try it while they are traveling and report back with concerns, problems, or suggestions because in the end I want it to be easy as possible as they’ll be more inclined to use it.