Build a Real VPN with OpenVPN
A real, genuine, honest-to-gosh virtual private network (VPN) is an encrypted network-to-network virtual tunnel that connects trusted endpoints. It is not an HTTPS web portal that trusts all clients. In this example we can build a proper strong VPN with OpenVPN.
The definition of VPN has been stretched beyond recognition with the proliferation of HTTPS VPNs which trust all clients. These do work for shopping sites, which permit only limited client access; many are sold to businesses as ‘Easy client-less configuration!’ to provide remote employee access. Personally, we do not trust them as extensions of our networks. A VPN connects two networks, such as branch offices or a remote worker, to an office server. A real VPN requires that both the server and clients authenticate to each other.
Setting up a VPN where both servers and clients authenticate to each other is a bit of work and that is why ‘Easy client-less configuration!’ sells. However, it’s really not that hard to set up a proper strong OpenVPN server. You need two hosts on different networks to set up a nice OpenVPN test lab, such as a couple of virtual machines, or two hosts on different networks, like a wireless and a wired machine. All hosts need OpenVPN and Easy-RSA installed.
Set up PKI
First, create a proper public key infrastructure (PKI) on the server. Your OpenVPN server is the machine that external users will connect to. As with all Linux servers, ‘server’ refers to function and a computer can be both a server and a client.
A PKI offers several advantages; you have a Certificate Authority (CA) which simplifies key distribution and management, as well as allowing you to revoke client certificates at the server. When you don’t use a CA, the server needs a copy of every client certificate. A CA does not need all those client certificates; it only needs to know whether the client certificates have been signed by the CA. (OpenVPN also supports static keys, which are fine for one or two users;
Remember, private keys must always be protected and never shared, while public keys are meant to be shared. In OpenVPN, the public key is called a certificate and has a ‘.crt’ extension and the private key is called a key with a ‘.key’ extension.
In the olden days, OpenVPN came with nice helper scripts to set this up: the ‘Easy-RSA’ scripts. These are now maintained as a separate project, so if your Linux distribution does not package them, you can get them fresh from GitHub. Browse the Releases page to get ready-to-use tarballs. You might want to download them from GitHub anyway in order to get the current 3.0.1 release. This release dates back to October 2015, however a lot of Linux distributions are stuck on the old 2.x releases.
Let’s go ahead and use the new release.
Download and unpack the ‘Easy-RSA’ tarball into your ‘/etc/openvpn’ directory. Change to your ‘Easy-RSA’ directory, then run the below command to initialize your new PKI/
$ sudo ./easyrsa init-pki
‘init-pki’ complete; you may now create a CA or requests.
Your newly created PKI dir should be: ‘/etc/openvpn/easyrsa/pki’
Now go ahead and create your new CA.
$ sudo ./easyrsa build-ca
Generating a 2048 bit RSA private key
........................................................+++ ................+++ writing new private key to '/etc/openvpn/easyrsa/pki/private/ca.key.tJXulR8Ery' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: -----
What you are about to enter is something called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank. For some fields there will be a default value, If you enter ‘.’, the field will be left blank.
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:server.net
CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at the below.
Copy your new ‘ca.crt’ into ‘/etc/openvpn’ on all client machines. The next step takes place on your client machine, creating a PKI environment, the client’s private key, and a signing request.
Replace ‘AliceRemote’ with whatever name you want to identify the client.
$ sudo ./easyrsa init-pki $ sudo ./easyrsa gen-req AliceRemote [...]
Keypair and certificate request completed.
Your files are shown below.
Copy the ‘.req’ file to your server, import it, and then sign it.
$ sudo ./easyrsa import-req /media/carla/4gbstik/AliceRemote.req AliceRemote $ sudo ./easyrsa sign-req client AliceRemote [..]
Certificate created at: ‘/etc/openvpn/easyrsa/pki/issued/AliceRemote.crt’
Copy the signed certificate to the client machine. Now both server and client have all the necessary certificates and key pairs.
If you plan to use TLS, you need to generate ‘Diffie-Hellman’ parameters on the server. Go ahead and do it.
$ sudo ./easyrsa gen-dh
Look in your ‘openvpn/examples/‘ directory for configuration file examples. This is a complete example server configuration and it goes in ‘/etc/openvpn/server.conf’. Edit the commented options for your own setup.
port 1194 proto udp dev tun keepalive 10 120 status openvpn-status.log verb 3 persist-tun persist-key ifconfig-pool-persist /etc/openvpn/ipp.txt
# Your server keys
ca /etc/openvpn/easyrsa/pki/ca.crt key /etc/openvpn/easyrsa/pki/private/ca.key dh /etc/openvpn/easyrsa/pki/dh.pem # Set server mode, and define a virtual pool of IP # addresses for clients to use. Use any subnet # that does not collide with your existing subnets. server 192.168.10.0 255.255.255.0 # Set up route(s) to subnet(s) behind # OpenVPN server push "route 192.168.11.0 255.255.255.0" push "route 192.168.12.0 255.255.255.0" Client Configuration
Use this on your client. This example is ‘/etc/openvpn/client.conf’.
client dev tun proto udp resolv-retry infinite nobind persist-key persist-tun # The hostname/IP address and port of the server remote servername 1194 # Your certificates and keys cert /etc/openvpn/easyrsa/pki/AliceRemote.crt ca /etc/openvpn/easyrsa/pki/ca.crt key /etc/openvpn/easyrsa/pki/private/AliceRemote.key
Connecting to the Server
Start OpenVPN on the server from the command line by referencing the configuration file, for example ‘openvpn /etc/openvpn/server.conf’. Start it on the client in the same way, for example ‘openvpn /etc/openvpn/client.conf’.
You may name your configuration files anything you want, and you may create multiple files for multiple server and client configurations. Once your OpenVPN tunnel is established, it is just like having a shielded Ethernet cable to carry your session safely over untrusted networks, and you can log into your usual programs just as though you were sitting next to the server.
This should get you up and running. There are many configuration and command line options for OpenVPN; see the OpenVPN Documentation. Easy-RSA has a lot of good ‘how tos’ on GitHub and bundled in the tarball.