If you need to encrypt traffic from your computer or mobile device, you have many options. You could buy a commercial VPN solution, or you could sign up for a VPN service and pay a monthly fee. Or for less money, you could create your own VPN and gain the use of a Linux VPS (Virtual Private Server) anywhere in the world. This roll-your-own option is made possible through the use of the open source OpenVPN project, Linux, and a few open source client-side applications.
The VPS-based setup described here is designed to encrypt all the traffic from your laptop, desktop, or mobile phone to your VPN server, which then unencrypts that traffic and passes it on to its destination. This can be very useful if you're using the Internet from a coffee shop, a hotel, or a conference and you do not trust the network.
[ Also on InfoWorld: Teach your router new tricks with DD-WRT [1]. | Get expert networking how-to advice from InfoWorld's Networking Deep Dive [2] PDF special report. | Learn how to secure your systems with Roger Grimes' Security Adviser blog [3] and Security Central newsletter [4]. ]
Putting this VPN together is generally the work of only a few minutes, and it requires minimal Linux command-line skills. The only tools you'll need are an SSH client and a VPS.
You can purchase a VPS on a monthly, quarterly, or yearly basis from any number of service providers. Some larger services offer VPS services in several different countries and allow you to choose where your server will run. In most cases, it's best to find a VPS that's located close to where you intend to generate the most traffic; the further away you are, the higher the tunnel latency will be, and the connection may be slower than you'd like. However, if you want your Internet traffic to appear to originate from Switzerland while you connect from New York or Los Angeles, you can do that as well.
This guide will show you how to create your own VPN using a VPS running Debian Squeeze, but the general configuration will work on any number of other distributions.
If you will use the VPS only for the VPN, you don't need significant resources. Many VPS providers offer mini or micro VPS options that have 128MB or 256MB of RAM, a single CPU core, and 5GB of storage. That's plenty to run a VPN for several users. You will want to pay attention to the allowed traffic per month if you plan on pushing lots of data through the connection, however. Some providers offer 500GB or even 1TB of traffic per month. The monthly cost is typically anywhere from $5 to $10.
When purchasing your VPS, make sure it's a hardware-emulated VPS based on KVM or Xen, not a container instance based on Linux-VServer or OpenVZ. We will need access to the TAP/TUN elements of the Linux kernel to create the VPN, and that can be difficult or impossible to access on other forms of virtualization due to their internal architecture. Some providers have implemented ways of providing TAP/TUN devices to their OpenVZ-based VPSes, but this support differs from provider to provider.
Once you've purchased your VPS, you should receive an email with the IP address and root login information. Fire up your SSH client (you can download PuTTY [5] for Windows or use iTerm or native SSH from the Mac OS X Terminal) and make an SSH connection using that IP and root credentials. You'll wind up with a command prompt like so:
root@localhost:~#
Your prompt may look a little different depending on how the provider names the VPS, but the important part is the # at the end. The # signifies that you're logged into the server as root and can make the necessary changes.
OpenVPN server configuration
The first thing to do is install OpenVPN:
root@localhost:~# apt-get install openvpn
The apt-get
command locates and downloads the OpenVPN package and all the necessary dependencies for you. Once installation is complete, we're ready to start configuring our server. We can use scripts included with OpenVPN to create our certificates. Let's start by copying these scripts to a new folder:
root@localhost:~# cp -pr /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/easy-rsa
Now, let's move into that directory and start configuring the scripts:
root@localhost:~# cd /etc/openvpn/easy-rsa
We need to edit the vars file. You can use Vim or Nano (or any text editor, of course). If you're not familiar with Vim, you'll find Nano to be easier.
root@localhost:/etc/openvpn/easy-rsa# nano vars
At the bottom of the file, you'll see several variables that you can change to reflect your location and other information. These can also be left as is if you do not want or need to specify that information:
# These are the default values for fields
# that will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
Save the file (Ctrl-O in Nano) and exit the editor.
Now, we need to source the vars file:
root@localhost:/etc/openvpn/easy-rsa# source ./vars
Next, we need to make the scripts executable:
root@localhost:/etc/openvpn/easy-rsa# chmod +x ./*
To make sure we're ready to go, initialize the key directory:
root@localhost:/etc/openvpn/easy-rsa# ./clean-all
Then we build our CA (certificate authority):
root@localhost:/etc/openvpn/easy-rsa# ./build-ca
This process will prompt you for some more information, but the information you added to the vars file should be the defaults.
Now we build a keyfile:
root@localhost:/etc/openvpn/easy-rsa# ./build-key-server server
You will again be prompted for the certificate information, and usually you can just hit Enter at each prompt. You do not need to enter a password here. When asked to sign the certificate, answer "y," and enter "y" again when prompted to commit the request.
Next, we need to build a Diffie-Hellman file:
root@localhost:/etc/openvpn/easy-rsa# ./build-dh
Then we need to build a remote client certificate:
root@localhost:/etc/openvpn/easy-rsa# ./build-key remote1
If you want to protect this certificate with a password, use this command:
root@localhost:/etc/openvpn/easy-rsa# ./build-key-pass remote1
The password will be required every time you connect to the VPN; if that's not desired, use the build-key command listed first. Most installations will not need or want a password on the certificate.
You will again be prompted for the certificate information, and you can usually just hit Enter through all the prompts, answering "y" at the end as you did with the build-key-server command above.
Now that we've made all the keys, we need to put the new files into place. To do that, we move into the keys directory that the script created:
root@localhost:/etc/openvpn/easy-rsa# cd keys
root@localhost:/etc/openvpn/easy-rsa/keys#
And we copy the files to the /etc/openvpn directory:
root@localhost:/etc/openvpn/easy-rsa/keys# cp ca.crt /etc/openvpn
root@localhost:/etc/openvpn/easy-rsa/keys# cp server.crt /etc/openvpn
root@localhost:/etc/openvpn/easy-rsa/keys# cp server.key /etc/openvpn
root@localhost:/etc/openvpn/easy-rsa/keys# cp dh1024.pem /etc/openvpn
We also need to copy some files to our client machine. You can use WinSCP [6] to do this on Windows, the scp
command on Linux, or Cyberduck [7] on Mac OS X. Start up your SCP client, connect to the server using the IP address and root credentials you used for the SSH session, and copy these files to your client system:
/etc/openvpn/easy-rsa/keys/ca.crt
/etc/openvpn/easy-rsa/keys/remote1.crt
/etc/openvpn/easy-rsa/keys/remote1.key
These will be used to connect to your VPN server.
Now, we need to create our OpenVPN configuration file. We move to the /etc/openvpn directory, and create a new file (with Nano):
root@localhost:/etc/openvpn/easy-rsa/keys# cd /etc/openvpn
root@localhost:/etc/openvpn # nano vpnserver.conf
Then copy and paste this configuration:
port 10000
proto udp
dev-type tun
dev vpnclient
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
comp-lzo
duplicate-cn
server 10.200.200.0 255.255.255.0
client-to-client
keepalive 10 120
push "dhcp-option DNS 8.8.8.8"
push "redirect-gateway def1"
persist-key
persist-tun
user nobody
group nogroup
log openvpn.log
verb 1
Save the file (Ctrl-O) and exit. Note that if you want to use a different DNS server, you can change the 8.8.8.8 in the example to a server located at your VPS provider, or any DNS server you wish. The 8.8.8.8 server is Google's DNS server.
We're almost done with the server. We just need to configure routing and network address translation:
root@localhost:/etc/openvpn # echo "1" > /proc/sys/net/ipv4/ip_forward
root@localhost:/etc/openvpn # /sbin/iptables -t nat -A POSTROUTING -s 10.200.200.0/24 -o eth0 -j MASQUERADE
And we need to make these changes persist after a reboot. To do this, we edit /etc/sysctl.conf to remove the # at the beginning of the line:
net.ipv4.ip_forward=1
Then save the file. To open the file with Nano:
root@localhost:/etc/openvpn # nano /etc/sysctl.conf
We also need to add the iptables
line to be run at startup. A quick way to do this is to add it to /etc/rc.local:
root@localhost:/etc/openvpn # nano /etc/rc.local
Above the line reading "exit 0," paste the iptables
command:
/sbin/iptables -t nat -A POSTROUTING -s 10.200.200.0/24 -o eth0 -j MASQUERADE
The server configuration is now complete. Let's start/restart the OpenVPN service:
root@localhost:/etc/openvpn # service openvpn restart
The way this is configured, a tunnel device will be created on the server, and the address of 10.200.200.1 will be assigned to that device. When a client connects to the server, the client will be assigned an address in the 10.200.200.0/24 network, and all routes will be configured on the client to permit data to pass through the encrypted tunnel to the server-side tunnel interface. Then, the net.ipv4.ip_forward
value will allow the VPN server to route that traffic through its public network interface, and (based on the iptables
command) NAT will translate traffic from the VPN through the single public IP address. In short, all traffic from a connecting client will be routed through the VPN server.
OpenVPN client configuration
Now we need to configure a client. The server setup above is configured to allow a client to connect as long as it has the proper certificate (the remote1.crt). This does not require a username or password, unless you chose to enter a password when creating the certificate. However, even if the server does not require a password, you can still choose to require a username and password to connect from your client, and this can be configured with or without a client certificate requirement.
The most secure of these methods would be to require a username and password in addition to the client certificate; we will detail the steps to do that later on. If you prefer to require usernames and passwords, you may want to read the steps near the end before continuing; it may save you some time.
For now, we'll configure a client to use only the client certificate.
On your client system, you will need to create an OpenVPN configuration file that you can then import into your VPN client. You can use a simple text editor. You should name it myvpn.ovpn or something similar, and make sure that the file is saved as plain text and the extension is .ovpn.
remote <your server's public IP address goes here>
port 10000
proto udp
dev tun
comp-lzo
client
resolv-retry infinite
nobind
persist-key
persist-tun
ns-cert-type server
verb 3
ca ./ca.crt
cert ./remote1.crt
key ./remote1.key
ping 10
ping-restart 60
Place this file and the ca.crt, remote1.crt, and remote1.key files in a new directory, perhaps called openvpn, under your Documents folder. Now that we have our OpenVPN config file, we need a VPN client that can put it to use.
Windows clients. For Windows systems, we'll use the OpenVPN Windows client [8]. Install the client, and bring up the main window. Click the + sign next to Connection Profiles and click Local File, as we're going to import the configuration we just created and stored in the directory where our certificates and key live. Click Import, navigate to this directory (I named it openvpn), and select the myvpn.ovpn file. Give it a friendly name if you like, and check "Completely trust this profile." Click Save, then double-click the new connection profile. In a few seconds, you should be connected to your new VPN server.
Mac clients. For the Mac, you should download Tunnelblick [9], which is a very capable VPN client that supports OpenVPN. Install it, and you'll see a new icon in your menu bar that looks like a dark arch. Click that and select VPN Details. Click the + sign at the bottom left of the VPN Details window, followed by "I have configuration files," then "OpenVPN Configurations," then "Open Private Configurations Folder." A new Finder window will pop up showing the folder where our certificates and key live. Copy all of the files from the folder (I named it openvpn), including the certificates, key, and myvpn.ovpn file.
Now you can close the VPN Details window. Click the Tunnelblick icon in the upper right, and you should see your new VPN connection there. Select "Connect myvpn," and within a few seconds you should be connected.
Mobile clients. You can download the official OpenVPN client [8] for your iPhone, iPad, or Android device, or you can use a third-party app. You will need to copy the certificates, key, and configuration files to your mobile device and import them into the client in a similar manner to the Windows and Mac client setups.
Adding username and password authentication
Our current OpenVPN server configuration allows for multiple clients to use the same certificate to authenticate to the server. Thus, you can install a client on any system and copy those files over, as well as connect to your VPN. However, you may want to add extra security by requiring a username and password every time anyone tries to connect to the VPN. We can do that by changing a few configuration lines in the server and client configuration files, and adding users to our VPS.
First, we need to modify the server's configuration. In our SSH session, we need to edit the /etc/openvpn/vpnserver.conf file:
root@localhost:/etc/openvpn/easy-rsa/keys# cd /etc/openvpn
root@localhost:/etc/openvpn # nano vpnserver.conf
Then we need to add the following line to the file. The placement doesn't matter, but you might want to add it after the client-to-client line:
plugin /usr/lib/openvpn/openvpn-auth-pam.so "login login USERNAME password PASSWORD"
Save the file (Ctrl-O) and exit Nano. Then restart the service:
root@localhost:/etc/openvpn # service openvpn restart
Now, we need to create some users. You can do this with the useradd
command. We may not want these users to be able to SSH into the server, however, so we need to set their shell to nologin
, as follows:
root@localhost:/etc/openvpn # useradd -s /usr/sbin/nologin myuser
Then set a password:
root@localhost:/etc/openvpn # passwd myuser
Enter the password twice.
Finally, we need to edit our client configuration, and simply add this line:
auth-user-pass
This will tell the client to prompt for a username and password. You may need to delete and reimport your client configuration into your OpenVPN client after making this change.
Note that this method of client authentication still requires the client certificate and is the most secure of all three methods.
Requiring only a username and password
If you do not want to require a client certificate to connect, but want to use only usernames and passwords, you can do so by adding this line to the vpnserver.conf file on the server:
client-cert-not-required
Then restart the service:
root@localhost:/etc/openvpn # service openvpn restart
This will cause the server to use a client certificate if it is presented, but it will allow a client to connect without a certificate if a valid username and password are used. Note that the ca.crt file is still required on the client side. (However, the two lines in our client configuration that specify the remote1.crt and remote1.key files can be removed.) It's important to note that you should have configured usernames and passwords as described above before making this change.
Though it may seem daunting, this entire OpenVPN configuration process shouldn't take more than 15 minutes from the time you log in to your new VPS to the time you make your first connection with your client. You can save the certificates, keys, and server configuration we created, as well as set up other VPN servers, or move your server to another provider and have a new server up and running in just a few minutes.
Then, any time you want to be sure that your traffic is encrypted from your location to your personal VPN server, just fire up your client and go.
This article, "How to roll your own VPN [10]," was originally published at InfoWorld.com [11]. Follow the latest developments in security [12], networking [13], and open source software [14] at InfoWorld.com. Get a digest of the key stories each day in the InfoWorld Daily newsletter [15]. For the latest business technology news, follow InfoWorld on Twitter [16].