The Tinfoil Team was at the RSA Conference earlier this year and we noticed two things: there was no secure WiFi, and someone had set up a Pineapple, a device that spoofs wireless networks and sits in the middle of your connection to harvest all unencrypted information going through. Pineapples are not unexpected in any security conference, but are something that people should be wary of on any wireless network, especially an unsecured one.
Luckily, it’s fairly easy to setup a VPN and protect your laptop’s or phone’s communication. Traffic going over SSL/TLS get this sort of protection automatically (as long as you pay attention to certificate trust errors), but if you ever hit a URL over http your cookies and sessions just got hijacked. Your own VPN mitigates this, and you can set it up yourself. For this guide I’m going to be setting up OpenVPN on a DigitalOcean box running Ubuntu but it should be similar on other platforms. Don’t have a DigitalOcean account yet? Sign up here.
We’ve created a handy automated script to create a VPN. You can find the script on GitHub.
Download the script, and then run it:
chmod +x openvpn.sh
View the configuration file:
Copy/Paste it into OpenVPN and you’re good to go!
First thing’s first, log into the box and get the basics up and going.
Once you’ve got the basic infrastructure in place, install OpenVPN:
sudo aptitude install openvpn
And extract the basic configuration files examples:
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gzip -d /etc/openvpn/server.conf.gz
Next up, it’s time to set up the authentication before we head back to customize the config. I recommend setting up a quick Public Key Infrastructure — essentially your own SSL certificates. You’ll want a key and certificate for the VPN and keys/certificates for the clients.
On your VPN:
sudo openssl req -newkey rsa:4096 -keyout /etc/openvpn/vpn-key.pem -out vpn.csr
On your CA’s environment (hopefully elsewhere):
Then transfer your cacert.pem and vpn-cert.pem files back to the VPN box into /etc/openvpn.
Create an additional shared-secret for extra security.
sudo openvpn --genkey --secret /etc/openvpn/ta.key
Next, create some Diffie-Hellman parameters for OpenVPN. Change 4096 to your key size if it’s smaller, and note that a 4096 bit prime will take awhile to find on an EC2 micro.
sudo openssl dhparam -out /etc/openvpn/dh4096.pem 4096
Lock down the private files:
sudo chmod 600 /etc/openvpn/vpn-key.pem
sudo chmod 600 /etc/openvpn/ta.key
Create the tunnel so your VPN acts as a NAT for the clients
sudo sysctl -w net.ipv4.ip_forward=1
Also uncomment the line in /etc/sysctl.conf to persist this across restarts.
sudo iptables -I FORWARD -i tun0 -o eth0 -s 10.8.0.0/24 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -I FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -t nat -I POSTROUTING -o eth0 -s 10.8.0.0/24 -j MASQUERADE
Finally, modify the openvpn configuration (/etc/openvpn/server.conf) with your setup. Here’s a quick example of the important pieces:
# Which TCP/UDP port should OpenVPN listen on? port 80 # TCP or UDP server? proto udp # "dev tun" will create a routed IP tunnel, dev tun # SSL/TLS root certificate (ca), certificate # (cert), and private key (key). Each client # and the server must have their own cert and # key file. The server and all clients will # use the same ca file. ca cacert.pem cert vpn-cert.pem key vpn-key.pem # This file should be kept secret # Diffie hellman parameters. dh dh4096.pem # Configure server mode and supply a VPN subnet # for OpenVPN to draw client addresses from. # The server will take 10.8.0.1 for itself, # the rest will be made available to clients. # Each client will be able to reach the server # on 10.8.0.1. Comment this line out if you are # ethernet bridging. See the man page for more info. server 10.8.0.0 255.255.255.0 # Maintain a record of client <-> virtual IP address # associations in this file. If OpenVPN goes down or # is restarted, reconnecting clients can be assigned # the same virtual IP address from the pool that was # previously assigned. ifconfig-pool-persist ipp.txt # If enabled, this directive will configure # all clients to redirect their default # network gateway through the VPN, causing # all IP traffic such as web browsing and # and DNS lookups to go through the VPN # (The OpenVPN server machine may need to NAT # or bridge the TUN/TAP interface to the internet # in order for this to work properly). push "redirect-gateway def1 bypass-dhcp" # Certain Windows-specific network settings # can be pushed to clients, such as DNS # or WINS server addresses. CAVEAT: # http://openvpn.net/faq.html#dhcpcaveats # The addresses below refer to the public # DNS servers provided by opendns.com. push "dhcp-option DNS 188.8.131.52" push "dhcp-option DNS 184.108.40.206" # Uncomment this directive to allow different # clients to be able to "see" each other. # By default, clients will only see the server. # To force clients to only see the server, you # will also need to appropriately firewall the # server's TUN/TAP interface. client-to-client # Uncomment this directive if multiple clients # might connect with the same certificate/key # files or common names. This is recommended # only for testing purposes. For production use, # each client should have its own certificate/key # pair. # # IF YOU HAVE NOT GENERATED INDIVIDUAL # CERTIFICATE/KEY PAIRS FOR EACH CLIENT, # EACH HAVING ITS OWN UNIQUE "COMMON NAME", # UNCOMMENT THIS LINE OUT. ;duplicate-cn # The keepalive directive causes ping-like # messages to be sent back and forth over # the link so that each side knows when # the other side has gone down. # Ping every 10 seconds, assume that remote # peer is down if no ping received during # a 120 second time period. keepalive 10 120 # For extra security beyond that provided # by SSL/TLS, create an "HMAC firewall" # to help block DoS attacks and UDP port flooding. # # The server and each client must have # a copy of this key. # The second parameter should be '0' # on the server and '1' on the clients. tls-auth ta.key 0 # This file is secret # Enable compression on the VPN link. # If you enable it here, you must also # enable it in the client config file. comp-lzo # It's a good idea to reduce the OpenVPN # daemon's privileges after initialization. user nobody group nogroup # The persist options will try to avoid # accessing certain resources on restart # that may no longer be accessible because # of the privilege downgrade. persist-key persist-tun # Output a short status file showing # current connections, truncated # and rewritten every minute. status openvpn-status.log # Set the appropriate level of log # file verbosity. # # 0 is silent, except for fatal errors # 4 is reasonable for general usage # 5 and 6 can help to debug connection problems # 9 is extremely verbose verb 4
Whew, you’re almost there now! Create some client certificates and configure your computer or phone to connect. Our favorite VPN application is Viscosity. As you try out a connection, tail /var/log/syslog for connection errors. LZO compression and the ta.key/direction are especially important to get a stable connection.
Now you hopefully have a VPN set up. It may be a tad bit slower than without protection, but your data will be heavily encrypted over the public WiFi. Got any suggestions or OpenVPN configurations for other clients? Let me know!