How To Install OpenVPN for Ubuntu Systems

Install OpenVPN

When installing the OpenVPN server, it is recommended to switch to superuser mode to ensure all dependencies that require additional permissions can be installed. You can do this by logging in as a superuser using the command sudo su or by using the command sudo before each command. In this guide, the second option is used.

OpenVPN is a package in the Ubuntu software repository and can be installed directly with the following command:

sudo apt install openvpn

In addition, you need to install the auxiliary tool EasyRSA, which contains a series of scripts and configurations to help you quickly generate the certificates, and public and private key pairs required by OpenVPN. EasyRSA is a set of scripts, so you can clone its GitHub repository.

sudo apt install git
git clone https://github.com/OpenVPN/easy-rsa.git

Generate CA Certificate

Enter the script directory of EasyRSA.

cd easy-rsa/easyrsa3

Create a backup of the vars.example file.

cp vars.example vars

Find the following parameters in the vars file, uncomment them, and then modify them according to your own needs. Do NOT leave any field blank. Save and exit the file when you are ready.

nano vars

Look for the following lines, uncomment them, and modify as needed:

set_var EASYRSA_REQ_COUNTRY    "US"
set_var EASYRSA_REQ_PROVINCE   "California"
set_var EASYRSA_REQ_CITY       "San Francisco"
set_var EASYRSA_REQ_ORG        "Copyleft Certificate Co"
set_var EASYRSA_REQ_EMAIL      "me@example.net"
set_var EASYRSA_REQ_OU         "My Organizational Unit"

Execute the following command to generate a public key:

./easyrsa init-pki

If the following information is generated, it means that the generation of the public key system is successful:

Notice

'init-pki' complete; you may now create a CA or requests
Your newly created PKI dir is:
* /opt/openvpn/easy-rsa/easyrsa3/pki


* Using Easy-RSA configuration: /opt/openvpn/easy-rsa/easyrsa3/vars


* The preferred location for 'vars' is within the PKI folder.
To silence this message move your 'vars' file to your PKI or declare your 'vars' file with option: --vars=<FILE>

* Using x509-types directory: /opt/openvpn/easy-rsa/easyrsa3/x509-types

Create a CA Certificate.

📝 NOTE: If you don't want to enter a password every time, you can use the nopass parameter to cancel the password. In the output, you will also be prompted to enter the public name of the CA. You can use the default one by hitting Enter.

To generate the CA without a password, run the following command:

./easyrsa build-ca nopass

If you see the following information, it means that the CA certificate was successfully generated:

* Using SSL: openssl OpenSSL 1.1.1f 31 Mar 2020

* Using Easy-RSA configuration: /opt/openvpn/easy-rsa/easyrsa3/vars

* The preferred location for 'vars' is within the PKI folder.
To silence this message move your 'vars' file to your PKI or declare your 'vars' file with option: --vars=<FILE>

....+++++
.+++++
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is 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]:CN


Notice

CA creation complete and you may now import and sign cert requests. Your new CA certificate file for publishing is at:
/opt/openvpn/easy-rsa/easyrsa3/pki/ca.crt

Now, the ca.crt file in the pki directory and the ca.key file in the pki/private directory are the public and private key pairs used by the SSL certificate.

Generate Server Certificate, Encrypted File and Private Key

📝 NOTE: The server’s Common Name in the following example is the default one. If you also used the default name, you need to hit Enter when prompted to type a Common Name.

Generate the server certificate, key, and encryption files.

./easyrsa gen-req server nopass

If you see the following information, it means that the certificate request file was successfully generated:

* Using SSL: openssl OpenSSL 1.1.1f 31 Mar 2020 2

* Using Easy-RSA configuration: /opt/openvpn/easy-rsa/easyrsa3/vars 4

* The preferred location for 'vars' is within the PKI folder.
  To silence this message move your 'vars' file to your PKI
  or declare your 'vars' file with option: --vars=<FILE> 8

Generating a RSA private key
    +++++
...................................................................+++++
writing new private key to '/opt/openvpn/easy-rsa/easyrsa3/pki/9a43662d/temp.9b3278ae'

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is 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) [server]:

Notice

Keypair and certificate request completed. Your files are:
req: /opt/openvpn/easy-rsa/easyrsa3/pki/reqs/server.req
key: /opt/openvpn/easy-rsa/easyrsa3/pki/private/server.key

Copy the server private key to the OpenVPN configuration file directory.

cp pki/private/server.key /etc/openvpn/

Generate a Public Key

Since we use one server to act as both the CA server and the VPN server, you need to sign it yourself, which will generate a file with the same name. Therefore, you need to rename the server request file server.req first.

Rename the server request file with the following command:

mv pki/reqs/server.req pki/reqs/server2.req

Import the request where server is the server’s name specified earlier:

./easyrsa import-req pki/reqs/server2.req server

Use the following command to issue a request:

./easyrsa sign-req server server
confirm: yes
📝 NOTE: The first server here is the request type, which can be either client or server, and the second server is the server name specified earlier.

Remember to change the file path here, and copy server.crt and ca.crt to the OpenVPN configuration path:

sudo cp pki/ca.crt pki/issued/server.crt /etc/openvpn/

Generate Encrypted Files

Generate a Diffie-Hellman key file to enhance the VPN's security.

./easyrsa gen-dh
* Using Easy-RSA configuration: /opt/openvpn/easy-rsa/easyrsa3/vars

* The preferred location for 'vars' is within the PKI folder.
To silence this message move your 'vars' file to your PKI or declare your 'vars' file with option: --vars=<FILE>

Generating DH parameters, 2048 bit long safe prime, generator 2 This is going to take a long time
.....................+............+..................+.................+.+.....+......+.........................
DH parameters appear to be ok.


Notice



DH parameters of size 2048 created
at: /opt/openvpn/easy-rsa/easyrsa3/pki/dh.pem

Generate Diffie-Hellman signatures.

openvpn --genkey --secret ta.key

Copy the generated files to the OpenVPN configuration path.

sudo cp ta.key pki/dh.pem /etc/openvpn/

Now, all the files on the server side are generated and copied to the appropriate OpenVPN configuration path.

Generate Client Certificate and Key Pair

Prepare a directory to store client files.

mkdir -p ~/client-configs/keys

Modify the permissions of the directory to ensure security.

sudo chmod -R 700 ~/client-configs

Generate a client request file.

./easyrsa gen-req client1 nopass
Common name:Enter
📝 NOTE:
  • Considering that there may be several clients, it is called client1 here. Of course, the name can also be modified.
  • When prompted for a Common Name, hit Enter to accept the default name.

Copy the generated key to the client directory for the next steps.

cp pki/private/client1.key ~/client-configs/keys/

Modify the name of the client request file.

mv pki/reqs/client1.req pki/reqs/client.req

Import the request file.

./easyrsa import-req pki/reqs/client.req client1

Issue the request.

./easyrsa sign-req client client1
Confirm:yes

Remember to change the file path here, and copy client1.crt, ta.key, and ca.crt to the OpenVPN configuration path.

cp pki/issued/client1.crt ta.key pki/ca.crt ~/client-configs/keys/

Configure OpenVPN Service

Copy a sample configuration file.

sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gzip -d /etc/openvpn/server.conf.gz

Open the configuration file.

sudo nano /etc/openvpn/server.conf

Find the tls-auth configuration in the file. If it is commented, uncomment it and modify it to look like the following. Also, add a key-direction 0 configuration:

tls-auth ta.key 0 # This file is secret
key-direction 0

Find the cipher configuration in the file. If it is commented, uncomment it and modify it to look like the following, and add an auth SHA256 configuration:

cipher AES-256-CBC
auth SHA256

Find the dh configuration in the file. The default should be dh2048.pem. Modify it to the following:

dh dh.pem
📝 NOTE: Be sure to turn on the duplicate-cn option if all clients use the same certificate and key to connect to the VPN. Otherwise, only one client per certificate is allowed to connect to the VPN.

To enable this option, find and uncomment the following line in the configuration file:

duplicate-cn

Find the push routes configurations in the configuration file and add the following line to push the 172.19.174.1 segment to client 10.0.8.x:

push "route 172.19.174.1 255.255.254.0"

Find the user permission configuration in the file and uncomment it. This will ensure the OpenVPN process runs with lower permissions, making it safer on Linux systems. Modify the file to include the following:

user nobody
group nogroup

Configure OpenVPN Service (Optional)

📝 NOTE: This is an optional configuration. It will be more convenient to follow the steps below after completing the OpenVPN service configuration mentioned above.

To pass all traffic through the VPN, find and uncomment the following lines in the configuration file:

push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"

Modify the default port number and protocol.

port 6666
proto udp

If the protocol is changed to TCP, you should change explicit-exit-notify to 0 to avoid errors.

explicit-exit-notify 0

If you didn't use the default names for some of the previous files, don't forget to update the configuration file accordingly. Ensure the paths and filenames for the following lines match your setup:

cert server.crt
key server.key

Adjust the Server Network Settings and Enable IP Forwarding

Open the configuration file.

sudo nano /etc/sysctl.conf

Find and uncomment the following line:

net.ipv4.ip_forward=1

You can check the current configuration with the following command:

sudo sysctl -p
📝 NOTE: If your server has a firewall, you need to configure it to allow the VPN to pass through.

Start the OpenVPN Service

Start OpenVPN. If there is no output, OpenVPN has started normally.

sudo systemctl start openvpn

If there is an error, you can use the following two commands to debug the error:

systemctl status openvpn
journalctl -xe

If OpenVPN starts normally, don't forget to configure it to start on boot with the following command:

sudo systemctl enable openvpn

Create a Client Profile

Create a directory to store the generated files.

mkdir -p ~/client-configs/files
chmod 700 ~/client-configs/files
mkdir -p ~/client-configs/keys
chmod 700 ~/client-configs/keys

Copy the sample configuration file.

cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf

Open the configuration file and modify it as follows:

nano ~/client-configs/base.conf

# Server IP and Port

client
dev tun
remote server_IP_address 6666
# protocol
proto udp
# permission
user nobody
group nogroup
remote-cert-tls server
# certificate file
ca ca.crt
cert client1.crt
key client1.key
cipher AES-256-CBC
# This line does not have to be added
auth SHA256
# This line needs to be added, 0 on the server, 1 on the client
key-direction 1
#If it is to configure the client file and the /etc/openvpn/update-resolv-conf file exists in Linux, uncomment
# script-security 2
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
#If not, no action uncomment
📝 NOTE: Remember to change the server_IP_address placeholder with the public IP address or domain name of your server.

Generate the client configuration file, following the next steps:

First, create a new file.

nano ~/client-configs/make_config.sh
  • Copy the following content into the file and save it:
#!/bin/bash
# First argument: Client identifier

KEY_DIR=~/client-configs/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf

cat ${BASE_CONFIG} \
<(echo -e '<ca>') \
${KEY_DIR}/ca.crt \
<(echo -e '</ca>\n<cert>') \
${KEY_DIR}/${1}.crt \
<(echo -e '</cert>\n<key>') \
${KEY_DIR}/${1}.key \
<(echo -e '</key>\n<tls-auth>') \
${KEY_DIR}/ta.key \
<(echo -e '</tls-auth>') \
> ${OUTPUT_DIR}/${1}.ovpn
  • Edit the permissions of the generated file.
chmod 700 ~/client-configs/make_config.sh
  • Run the script with the client name that corresponds to the name used when generating the certificate and key pair (e.g., client1):
cd ~/client-configs
sudo bash ./make_config.sh client1
📝 NOTE: If all configurations are done properly, a .ovpn file will be generated in the ~/client-configs/file directory. This file can be copied to the desired location.

FAQ

  • To check the status of the OpenVPN service, run the following command:
systemctl status openvpn
  • To reload the OpenVPN service, run the following command:
systemctl restart openvpn

Updated