Running an VPN server on your local area network will allow outside clients to connect to your server and access the network as if they were directly connected to it. This is a common setup for many companies, which let their employees connect to the local business network remotely, so that they have access to internal resources that are only available on the local network. Linux administrators and power users may also be interested in setting up an VPN server at home, since they can then use their laptop or other portable device to connect to their home network while on the go.
One of the best implementations of a VPN system is OpenVPN. It is completely open source and supports many features for customization. In this tutorial, we will go through the step by step instructions of installing and setting up OpenVPN on a Linux system. This will include installation of Easy-RSA for CA and client certificates. Then, we will show how to use a client system to connect to the VPN server and begin accessing the local network of the server. Follow along with us below to get started.
In this tutorial you will learn:
- How to install OpenVPN Server on major Linux distros
- How to configure a Certificate Authority server with Easy-RSA
- How to configure OpenVPN server settings
- How to generate certificates and keys for VPN clients
- How to manage the OpenVPN service
- How to configure IP forwarding kernel parameter
- How to create client configuration files
- How to connect to the OpenVPN server
Category | Requirements, Conventions or Software Version Used |
---|---|
System | Any Linux distro |
Software | OpenVPN |
Other | Privileged access to your Linux system as root or via the sudo command. |
Conventions |
# – requires given linux commands to be executed with root privileges either directly as a root user or by use of sudo command$ – requires given linux commands to be executed as a regular non-privileged user |
This tutorial will assume that you have at least three devices. One is for the OpenVPN server, another is for the certificate authority, and finally at least one client device that you plan on using to connect to the VPN server.
Setting Up a Certificate Authority
First, we will set up the system that we plan on using for the certificate authority (CA). Follow the step by step instructions below to finish the CA server:
- First, install the Easy-RSA package. This will be the tool that we use in order to generate a private key which will then sign requests from incoming client connections that need the CA to verify the identity of the OpenVPN server. On Debian and Ubuntu based systems:
$ sudo apt install easy-rsa
On Fedora based systems:
$ sudo dnf install easy-rsa
- Next, let’s get started with configuring Easy-RSA. We will do this by creating a directory for our Public Key Infrastrucure (PKI). This can be named whatever you want, but we will keep it straightforward for the sake of example:
$ mkdir ~/easy-rsa
- Next, we can either copy all the Easy-RSA files into our new PKI directory, or just create a symbolic link to them. The advantage of creating the symbolic link is that we will not need to modify our PKI directory in case there are future updates to the Easy-RSA package. Execute the following command to create the link:
$ ln -s /usr/share/easy-rsa/* ~/easy-rsa/ $ cd ~/easy-rsa
- Once we are in the
~/easy-rsa
directory, we run the script that initializes it as a PKI directory.$ ./easyrsa init-pki
- Next, we need to set some variables in our configuration. This can be done by creating a file named
vars
inside of the PKI directory~/easy-rsa
.$ nano vars
The following content can be pasted inside; just adapt it to reflect your own information:
set_var EASYRSA_REQ_COUNTRY "US" set_var EASYRSA_REQ_PROVINCE "LA" set_var EASYRSA_REQ_CITY "Los Angeles" set_var EASYRSA_REQ_ORG "LinuxConfig.org" set_var EASYRSA_REQ_EMAIL "admin@linuxconfig.org" set_var EASYRSA_REQ_OU "Linux Tutorials" set_var EASYRSA_ALGO "ec" set_var EASYRSA_DIGEST "sha512"
After editing the file to your satisfaction, save changes and exit it.
- Next, we will run the
build-ca
script. This will build the Certificate Authority, which generates a public and private key pair.$ ./easyrsa build-ca
You will be prompted to enter a passphrase that secures the key pair. Then, enter a name that represents your CA server, such as the hostname or username. We use
linuxconfig-CA
in the screenshot below: - Your server is now ready to act as a Certificate Authority. All clients that need to interact with your CA will need a copy of the
ca.crt
file, which should be stored in the~/easy-rsa/pki
directory, if you have been following along with us.$ cat ~/easy-rsa/pki/ca.crt
It is up to you how you choose to distribute the file, but all VPN clients will need a copy of it.
Be sure to keep your
ca.key
file secure. This file is stored at ~/easy-rsa/pki/private/ca.key
and should never leave the system. If this file becomes compromised, the purpose of the CA will be rendered useless. OpenVPN and Easy-RSA Installation
Now we move over to the VPN server. This is where we will install the VPN server software, while the CA server we configured in the previous section will be resposible for issuing or revoking certificates.
The first step is to install the OpenVPN software and Easy-RSA. These can be easily installed via official repositories on all major Linux distros. You can use the appropriate command below to install OpenVPN and Easy-RSA with your system’s package manager.
To install OpenVPN and Easy-RSA on Ubuntu, Debian, and Linux Mint:
$ sudo apt install openvpn easy-rsa
To install OpenVPN and Easy-RSA on Fedora, CentOS, AlmaLinux, and Red Hat:
$ sudo dnf install openvpn easy-rsa
To install OpenVPN and Easy-RSA on Arch Linux and Manjaro:
$ sudo pacman -S openvpn easy-rsa
Setting Up OpenVPN Server and Easy-RSA
We will now begin setting up the VPN server. The first few steps will look familiar, as we have to repeat some things that we also did on the CA server. Let’s get started.
- First, create the
easy-rsa
directory as we did before, and create a symbolic link it to the installed files.$ mkdir ~/easy-rsa $ ln -s /usr/share/easy-rsa/* ~/easy-rsa/ $ cd ~/easy-rsa
- Create a
vars
file, but this time we do not need to fill out all of the info that we did on the CA.$ nano vars
- Paste the following lines into the file, and save it:
set_var EASYRSA_ALGO "ec" set_var EASYRSA_DIGEST "sha512"
These are the recommended security settings for both maximum speed and security. You can, of course, change them as you see fit.
- Inside of the
~/easy-rsa
directory, we run the script that initializes it as a PKI directory.$ ./easyrsa init-pki
- Next, we will generate a private key for the VPN server, as well as a Certificate Signing Request (CSR). In later steps, this request will need to be signed by the CA that we configured earlier. Take a look at the following command syntax:
$ ./easyrsa gen-req linuxconfig-server nopass
Here, we are passing the
gen-req
option to theeasyrsa
script. Then, we pass a name for our VPN server, which will belinuxconfig-server
. Lastly, thenopass
option will get rid of password protection on the request file, which simplifies the entire process. - Now we need to copy the VPN server’s private key to the OpenVPN directory. The output from the previous command should tell you the full path to your private key. In our case, the following command is used:
$ sudo cp ~/easy-rsa/pki/private/linuxconfig-server.key /etc/openvpn/server/
You would need to replace
linuxconfig-server.key
with the name of your own private key. - The next step is to transfer the CSR over to the CA server for it to be signed. You can transfer the file over however you would like, for example with the
scp
command.$ scp ~/easy-rsa/pki/reqs/linuxconfig-server.req linuxconfig@ca_server:/tmp
- Switching to the CA server now. Now that the
.req
file is transferred over to the CA server, we will import it and then sign the request:$ cd ~/easy-rsa $ ./easyrsa import-req /tmp/linuxconfig-server.req linuxconfig-server $ ./easyrsa sign-req server linuxconfig-server
Make sure you substitute your own common names where necessary. Ours is simply
linuxconfig-server
. You will also be prompted for the password that we configured earlier on the CA server. - Now we need to transfer the
ca.key
andlinuxconfig-server.crt
files from the CA server back to the VPN server. Usescp
or your preferred method to do so:$ scp ~/easy-rsa/pki/issued/linuxconfig-server.crt linuxconfig@vpn_server:/tmp $ scp ~/easy-rsa/pki/ca.crt linuxconfig@vpn_server:/tmp
- Switching back to the VPN Server now. On the VPN server, take the files out of the
/tmp
directory that we just transferred and place them in the/etc/openvpn/server
directory. You will need root permissions to move them:$ sudo mv /tmp/{linuxconfig-server.crt,ca.crt} /etc/openvpn/server
- As a final security measure, we can generate a
tls-crypt
pre shared key. This boosts the security for the OpenVPN server and makes it easier to process incoming traffic.$ cd ~/easy-rsa $ openvpn --genkey secret ta.key
- Copy the generated
ta.key
file over to the/etc/openvpn/server/
directory:$ sudo cp ta.key /etc/openvpn/server
Now we are ready to move on to generating certificates and keys for each client that will be connecting to the VPN.
Generate Certificates and Keys for Clients
These steps will be performed on the VPN server, until we eventually switch over to the CA server, which will be clearly indicated. You will need to repeat these steps for each VPN client. This is where some Bash scripting might come in handy, in case you want to help automate the process in the future.
- First, let’s create a directory where we will be storing the keys for the clients.
$ mkdir ~/client-keys
- Navigate to the Easy-RSA directory, and then use the
easyrsa
script to generate a request for a client. In this example, our client will be namedlinuxconfig-client
. Change yours as needed:$ cd ~/easy-rsa $ ./easyrsa gen-req linuxconfig-client nopass
- Copy the newly created
linuxconfig-client.key
file over to the~/client-keys
directory that we created earlier:
$ cp ~/easy-rsa/pki/private/linuxconfig-client.key ~/client-keys
- We will also need to transfer the
linuxconfig-client.req
file over to the CA server to be signed. Usescp
or some other method to do so:$ scp ~/easy-rsa/pki/reqs/linuxconfig-client.req linuxconfig@ca_server:/tmp
- Switching to the CA server now. Import and sign the certificate request for the VPN client on the CA server:
$ cd ~/easy-rsa $ ./easyrsa import-req /tmp/linuxconfig-client.req linuxconfig-client $ ./easyrsa sign-req client linuxconfig-client
You will be prompted for the CA password that was configured in earlier steps. This should all look familiar, as the process is pretty much the same as when we signed the CSR for the VPN server.
- Let’s transfer the
linuxconfig-client.crt
file to the VPN server:$ scp ~/easy-rsa/pki/issued/linuxconfig-client.crt linuxconfig@vpn_server:/tmp
- Switching back to the VPN Server now. On the VPN server, copy the
linuxconfig-client.crt
to the directory we made earlier,~/client-keys
:$ cp /tmp/linuxconfig-client.crt ~/client-keys
We will also need to copy the
ta.key
andca.crt
files over to that directory:$ cp ~/easy-rsa/ta.key ~/client-keys $ sudo cp /etc/openvpn/server/ca.crt ~/client-keys
OpenVPN Configuration
OpenVPN has various example files that can be used to get a jumpstart with your own VPN server configurations. We will use one of these files and begin to customize it for our needs. You can also apply your own customizations along the way, but some of the suggestions seen below will be necessary to apply in order to work with the previous configuration we have set up.
Note that the following steps are to be performed on the VPN server.
- We will start by taking the
server.conf
example file from the OpenVPN documentation and copying it over to the/etc/openvpn/server
directory.$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/server/
- Open the newly copied file to start editing it:
$ sudo nano /etc/openvpn/server/server.conf
- We will need to configure this file to use the TLS certificate that we made earlier. Locate the following line and comment it out by adding a
;
character in front of it:tls-auth ta.key 0 # This file is secret
Below that, add the following line:
tls-crypt ta.key
The final result should look like:
;tls-auth ta.key 0 # This file is secret tls-crypt ta.key
- Next, locate the following
cipher
line and comment it out:cipher AES-256-CBC
Right below it, add the following two lines:
cipher AES-256-GCM auth SHA256
The final result should look like:
;cipher AES-256-CBC cipher AES-256-GCM auth SHA256
This will force our VPN connection to use better encryption than the default config.
- Since we have configured our VPN server to use ECC (Elliptic Curve Cryptography) instead of DH (Diffie-Hellman), we will need to locate the following
dh
line and comment it out:dh dh2048.pem
Right below that, add the following line:
dh none
The final result should look like this:
;dh dh2048.pem dh none
- To reduce the OpenVPN daemon’s privileges when it is initialized, and therefore reduce its potential attack surface, locate and uncomment the following lines:
;user nobody ;group nobody
Remove the;
in front of them, so that it reads:user nobody group nobody
- If you want to reroute all client traffic through the VPN, then you can locate the following line and uncomment it:
;push "redirect-gateway def1 bypass-dhcp"
Be sure to remove the preceding
;
to uncomment it.This is not strictly necessary but it is the behavior that most VPNs use, so it is what clients will expect.
- Uncomment the following lines that give the VPN clients some DNS servers to use for name resolution. These are the IPs to OpenDNS servers, but you can put any DNS server IPs you want:
;push "dhcp-option DNS 208.67.222.222" ;push "dhcp-option DNS 208.67.220.220"
Be sure to remove the two preceding
;
characters to uncomment these lines. - Lastly, locate the following lines:
cert server.crt key server.key
We will need to edit these to point to the files that we generated earlier. In our example, we used
linuxconfig-server
as the common name, so we will change these to:cert linuxconfig-server.crt key linuxconfig-server.key
All set, so save your changes to this file and exit it.
Configure IP Forwarding
On the OpenVPN server, we will need to change the IP forwarding kernel paramater in order to make sure that VPN clients can forward requests to the OpenVPN server, which can then forward them on towards a final destination.
- Edit the following file with root permissions:
$ sudo nano /etc/sysctl.conf
- At the bottom of the file, add the following line:
net.ipv4.ip_forward = 1
Save your changes and exit the file.
- Then, for the changes to take effect, execute:
$ sudo sysctl -p
Start OpenVPN Service
Now that OpenVPN has been configured, we can start the service.
The following command will start the OpenVPN service:
$ sudo systemctl start openvpn-server@server.service
If you want OpenVPN to start up automatically whenever the server turns on, then we can use systemctl enable
as follows:
$ sudo systemctl -f enable openvpn-server@server.service
To check the status of the service at any time, use the following command:
$ systemctl status openvpn.service
Create Client Configuration File
The last step is to create a configuration file for your VPN client. This file, along with the .crt
files and .key
files can then be sent to the VPN clients in order to initiate a connection with the VPN server.
- First, copy the
client.conf
example file to the~/client-keys
directory that we created earlier:$ cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-keysclient.conf
- This is only a template file and we will need to make several changes to it. Open the file to begin editing it:
$ nano ~/client-keys/client.conf
- Locate the following line:
remote my-server-1 1194
This is where we need to specify the IP of our VPN server. The
1194
is just the port that OpenVPN is running on, so only change this part if necessary. Replace themy-server-1
with the IP address of your OpenVPN server. - Just as we did in the server config file, uncomment the following two lines:
;user nobody ;group nobody
- Locate the following lines and comment them out:
ca ca.crt cert client.crt key client.key
These will be irrelevant for us, since we are going to use in-line configuration.
- Locate the following line and comment it out:
tls-auth ta.key 1
This is an irrelevant line and we will be using an in-line configuration anyway.
- Locate the following line and comment it out:
cipher AES-256-CBC
Replace it with the following two lines:
cipher AES-256-GCM auth SHA256
The final result becomes:
;cipher AES-256-CBC cipher AES-256-GCM auth SHA256
- At the bottom of this file, add the following line:
key-direction 1
Save and close the file when finished.
- We will now combine all of these certificates, config, and key files into a single
.ovpn
file that can be sent to the client for easy connecting.$ cd ~/client-keys $ cat client.conf > linuxconfig-client.ovpn $ echo '<CA>' >> linuxconfig-client.ovpn $ cat ca.crt >> linuxconfig-client.ovpn $ echo '</CA>' >> linuxconfig-client.ovpn $ echo '<cert>' >> linuxconfig-client.ovpn $ cat linuxconfig-client.crt >> linuxconfig-client.ovpn $ echo '</cert>' >> linuxconfig-client.ovpn $ echo '<key>' >> linuxconfig-client.ovpn $ cat linuxconfig-client.key >> linuxconfig-client.ovpn $ echo '</key>' >> linuxconfig-client.ovpn $ echo '<tls-crypt>' >> linuxconfig-client.ovpn $ cat ta.key >> linuxconfig-client.ovpn $ echo '</tls-crypt>'
This is a bit cumbersome to do, especially at scale, which is why some Bash scripting is recommended if you plan to do this often. At any rate, the final result is a complete
linuxconfig-client.ovpn
file that can be sent to the OpenVPN client.
Connecting to OpenVPN Server
Connecting to the VPN server is the easiest part. Once you have received all of the files that were generated on the OpenVPN server, use the following command syntax to connect:
$ sudo openvpn --config linuxconfig-client.ovpn
The instructions will of course vary across different operating systems like MacOS and Windows, but essentially the process is nearly the same – just provide the .ovpn
file to the OpenVPN client program.
Closing Thoughts
In this tutorial, we saw how to set up an OpenVPN server on a Linux system. This also included the setup of a separate Certificate Authority server using Easy-RSA. The process is quite long, but allows us to self host a VPN server with the best security measures. Now you know how to generate key pairs and configurations for future client connections and can distribute them out in the form of
.opvn
files.