Virtual private networks (VPNs) allow you to hide your online data transmissions and enhance your security while browsing the Internet from public places. Many online service providers offer both free and paid VPN options for you to use. However, even the best paid plans can be unreliable or slow at times.
If only you could create your own VPN between your mobile computer and your home computer.
Actually, that process is easier than you might think. Today we’ll discuss how you can use OpenVPN to create a secure connection between a client and server on a Linux machine.
Keep in mind that we’ll be creating a routing configuration and not a bridging one, which should be fine for most use cases. Windows users can follow along by reading the OpenVPN documentation, beginning with the section on setting up a Certificate Authority. Commands used in Windows will be similar to those shown below.
What You Need
You will need two computers – one is the server machine while the other is the client. The server machine can be your home desktop or a Linux instance from DigitalOcean or Linode. The client machine is the computer that you are using regularly. As this tutorial is done on Linux, both computers need to run Linux as well.
Note: In this tutorial, we will be using Ubuntu as our distro for both the server and client machine.
To get started, you need to install OpenVPN and Easy-RSA on your server. Then install OpenVPN on your client machine.
On Ubuntu you should install Easy-RSA from this Github page. Ubuntu includes Easy-RSA version 2 in its repositories. The Github link offers Easy-RSA version 3, which follows the commands I will use in this article.
sudo apt-get install openvpn git clone https://github.com/OpenVPN/easy-rsa.git
In the directory you cloned the Github repository into, copy the “easyrsa3” directory it contains into “/etc/easy-rsa/.”
sudo mkdir /etc/easy-rsa sudo cp -r ./easyrsa3/* /etc/easy-rsa/
Public Key Infrastructure (PKI)
OpenVPN makes use of a Public Key Infrastructure (PKI) to establish the identity of servers and clients so those separate entities can talk to one another. The PKI uses a master Certificate Authority (CA) alongside individual certificates and private keys for each server and client.
The CA must sign the server and client certificates. OpenVPN then checks to see that the server authenticates the identity of each client, and, at the same time, each client checks the identity of the server.
The setup here is more complicated than you might find for PPTP-style connections, but it provides better security to users and gives the server more freedom to accept or deny requested incoming client connections.
Creating the CA Certificate
For tighter security it is recommended that your CA machine be different from your server. For brevity, this article will use the same machine for both tasks. You should alter your file-copying procedures to accommodate your situation – whether it’s using
scp for network transfers or using a USB key to manually move files.
Note: if you use a separate computer as your CA, you will need to install Easy-RSA on that machine.
1. Change directories to “/etc/easy-rsa/:”
2. If necessary, copy “/etc/easy-rsa/vars.example” to “/etc/easy-rsa/vars.” Then, open vars to edit its contents:
sudo cp ./vars.example ./vars sudo nano ./vars
3. Enter the details such as your country, province, city, organization, and email. Uncomment the lines shown here by removing the “#” at the beginning of each one.
Once you are done with the editing, save (Ctrl + o) and exit (Ctrl + x).
4. Initialize your new PKI and generate the Certificate Authority keypair that you will use to sign individual server and client certificates:
export EASYRSA=$(pwd) sudo ./easyrsa init-pki sudo ./easyrsa build-ca
Copy the ca.crt file you just created to your OpenVPN server directory. You should also change its owner and group with Chown:
sudo cp /etc/easy-rsa/pki/ca.crt /etc/openvpn/server/ sudo chown root:root /etc/openvpn/server/ca.crt
Creating the Server Certificate and Private Key
Change back to your Easy-RSA directory and generate the server certificate and its private key:
cd /etc/easy-rsa sudo ./easyrsa init-pki sudo ./easyrsa gen-req ServerName nopass
You can change “ServerName” in the command above to whatever name you wish. Make sure you reflect that change when you copy your new key to the OpenVPN server directory:
sudo cp /etc/easy-rsa/pki/private/ServerName.key /etc/openvpn/server/
Diffie-Hellman Parameters File
OpenVPN makes use of the Diffie-Hellman (DH) key exchange method of securely exchanging cryptographic keys across a network. You will create a DH parameters file with the following command:
sudo openssl dhparam -out /etc/openvpn/server/dh.pem 2048
The final number, 2048, in that command shows the number of bits used in creating the file. For example, you could use 4096, but it would take a lot longer to generate the file and wouldn’t improve security much. The default is 2048, and that value is sufficient for most use cases.
Hash-based Message Authentication
OpenVPN also uses a Hash-based Message Authentication (HMAC) signature to guard against vulnerabilities in SSL/TLS handshakes. Create the file with this command:
sudo openvpn --genkey --secret /etc/openvpn/server/ta.key
At this point you will have created a number of files for your server. Now it’s time to create files for your clients. You can repeat this process multiple times for as many clients as you need. You can create client files safely on any computer with Easy-RSA installed.
Enter the Easy-RSA directory and initialize the PKI again if you haven’t done so already:
cd /etc/easy-rsa sudo ./easyrsa init-pki
Create a client key and certificate. Change directories if you skipped the previous step.
cd /etc/easy-rsa sudo ./easyrsa gen-req ClientName nopass
If you repeat the process, you don’t need to initialize the PKI for each new client. Just make sure to change “ClientName” to be unique every time.
Signing Server and Client Certificates
The CA must now sign your server and client certificates.
If you look in your “/etc/easy-rsa/pki/reqs/” file, you should see all the request (.req) files Easy-RSA created in the previous
easyrsa gen-req commands.
In this screenshot there are only two .req files. Your number will vary if you made more than one client in the previous step.
If you used a separate CA machine, you must now transfer those .req files to the CA for signing. Once that is complete, change to the Easy-RSA directory and sign your files with the following commands, making sure to reflect the proper location of each .req and the name of each server and client.
cd /etc/easy-rsa sudo ./easyrsa import-req /etc/easy-rsa/pki/reqs/ServerName.req Server1 sudo ./easyrsa import-req /etc/easy-rsa/pki/reqs/ClientName.req Client1 sudo ./easyrsa sign-req server Server1 sudo ./easyrsa sign-req client Client1
Note that you will need to provide Easy-RSA with a different name for your server and client certificates. ServerName.req will be used here, for example, to create Server1.crt.
You should now find two new files – “/etc/easy-rsa/pki/issued/Server1.crt” and “/etc/easy-rsa/pki/issued/Client1.crt” – that you’ll transfer to their respective machines (seen in the next section of this article). You can delete any .req files that remain.
Passing Along the .CRT Files
Now the signed certificates (each .crt) are ready to work for their owners. Move the server file to its OpenVPN location and make a new directory for the client certificates:
sudo mv /etc/easy-rsa/pki/issued/Server1.crt /etc/openvpn/server/ sudo chown root:root /etc/openvpn/server/Server1.crt sudo mkdir /etc/easy-rsa/pki/signed sudo mv /etc/easy-rsa/pki/issued/Client1.crt /etc/easy-rsa/pki/signed/
Creating the “…pki/signed/” folder here gives you a labeled location to place multiple client certificates.
Shared Server and Client Files
Now you should have five files in your “/etc/openvpn/server/” directory: ca.crt, dh.pem, Server1.crt, ServerName.key, and ta.key.
You will need two of those same files in your OpenVPN client folder on the client’s machine. Copy them over using
scp or a flash disk as appropriate. Copy both “/etc/openvpn/server/ca.crt” and “/etc/openvpn/server/ta.key” to your client’s “/etc/openvpn/client/.”
Make sure to copy your client certificate and key to that same location. Copy “/etc/easy-rsa/pki/signed/Client1.crt” and “/etc/easy-rsa/pki/private/ClientName.key” to your client’s “/etc/openvpn/client/.” Repeat this process for any additional clients you may have created.
For any client, you should now have four files in “/etc/openvpn/client:” Client1.crt, ClientName.key, ca.crt, and ta.key.
Server and Client Configuration Files
Your last step before starting the VPN is to edit configuration files for the server and client. First, locate the “default server.conf” and “client.conf” files. They will likely be in one of these locations:
- “/usr/share/doc/openvpn/examples/sample-config-files/” (Ubuntu configs are located here)
Note: On Ubuntu you will need to unpack the “server.conf.gz” file. Use
gunzip -d ./server.conf.gz to get the server.conf file from the compressed package.
Copy each config file to its respective “/etc/openvpn/server/” and “/etc/openvpn/client/” directory.
In server.conf make the following changes. Make sure the names and locations of your ca.crt, Server1.crt, ServerName.key, and dh.pem are listed in your config file. You may need to use full paths – like a line that reads “cert /etc/openvpn/server/Server1.crt.”
tls-auth... line to read
tls-crypt ta.key. Again, a full path may be necessary.
Uncomment (remove the “;”) from the “user nobody” and “group nobody” lines.
For your client you will make similar changes. After making the config file, reflect the names and locations of your ca.crt, Client1.crt, ClientName.key, and ta.key (with the same move from
tls-crypt...), insert the name or IP address and port of your server.
Time to Connect
Now you can start your server and client. This is a simple matter if everything above went as planned.
Start the server with:
and the client with:
The successful creation of a VPN will show the client’s output reading “Initialization Sequence Completed” at the end of its output. You will also find a new type of connection in your available network interfaces.
This screenshot shows the “tun0” interface. That’s what the OpenVPN server made. You can see its address as 10.8.0.1 and ping that address from the client to verify a successful connection.
Routing Internet Traffic Through the Server
At this point you’ll probably want to access the Internet through your server from your remote client. To do this, you’ll first need to change your server configuration file. Add the line
push ‘redirect-gateway def1 to your server configuration file.
echo "push \"redirect-gateway def1\"" | sudo tee -a /etc/openvpn/server/server.conf
You will also need to tell your server to properly route the client’s Internet traffic requests. This command will alter your Iptables packet filtering rules:
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
If you haven’t changed the “server 10.8.0.0 255.255.255.0” line in your server.conf file, the IP address in that command should work. You will need to change “eth0” to match your server’s ethernet interface. You can see from previous screenshots that my machine uses “enp19s0.”
Next, you can push DNS settings to the client. Any address a client can reach may be pushed. You can use this command as a starting point:
echo "push \"dhcp-option DNS 10.8.0.1\"" | sudo tee -a /etc/openvpn/server/server.conf
Finally, you can enable packet forwarding on the server as follows:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
You should now be able to use your client to access the Internet through the VPN.
I know this has been a long road. Hopefully you have found success in creating a VPN and connecting to the Internet in a secure manner.
If nothing else, this will have been a good learning experience for what it takes to create a secure digital tunnel. Thanks for joining me to the end.
Our latest tutorials delivered straight to your inbox