Language
Category
Search

How to setup openVPN server with Easy-RSA on Linux

Complete guide to install and configure OpenVPN Server with Easy-RSA on Slackware Linux. Learn how to create certificates and keys to establish a secure and functional VPN

How to setup openVPN server with Easy-RSA on Linux
At Open source By Rudi Drusian Lange
Published on
Last updated

Introduction

OpenVPN is an open-source virtual private network (VPN) solution that allows creating secure connections between devices, protecting network traffic from interception. Its flexibility and support for strong encryption make it ideal for businesses and users who need secure remote access or interconnection between networks.

This article details the process of installing and configuring an OpenVPN server and client on Linux, also covering the creation of digital certificates using the Easy-RSA script. The certificate generation process will be presented briefly and technically, focusing on practical application for OpenVPN operation.

For a deeper understanding of certificate management, including conceptual aspects, security criteria, and details on using Easy-RSA, we recommend reading the complementary article:

Installation Environment

The configurations demonstrated in this article were tested on Slackware Linux 15.0 (64-bit), using OpenVPN 2.5.5 and Easy-RSA 3.3.0.

This tutorial can be adapted to other Linux distributions with minor modifications, mainly in the OpenVPN installation command and the method of automatic service startup. Whenever possible, specific commands for different distributions will be presented, but these commands have not been tested.

Otherwise, the steps for downloading Easy-RSA, configurations, and certificate creation should be the same in most distributions.

Installing OpenVPN

OpenVPN is available in the official Slackware repositories.

# bash

# Slackware
slackpkg install openvpn

Commands for installation on other distributions:

# bash

# Debian and Ubuntu
sudo apt install openvpn

# Fedora
sudo dnf install openvpn

# Arch Linux
sudo pacman -S openvpn

# openSUSE
sudo zypper install openvpn

Downloading Easy-RSA

Easy-RSA is a script that facilitates the creation and management of keys and certificates necessary for secure communication between client and server. The script should be executed as a regular user, without administrative permissions.

For security reasons, Easy-RSA will be installed on a USB drive, whose path will be represented here by the mount point /mnt/usb. Using a removable device allows keeping the certificate management structure offline, reducing the risk of private key exposure. For more details on the security practices involved, refer to the article mentioned in the introduction.

Note: The USB drive must be formatted with a Linux-compatible file system (ext3, ext4, xfs, etc.). Otherwise, it will not be possible to execute the script.

To download Easy-RSA directly to the USB drive, use the following commands:

$ bash

cd /mnt/usb
git clone https://github.com/OpenVPN/easy-rsa

Configuring EasyRSA

Before starting, it is necessary to adjust the value of some default script variables to ensure data consistency during certificate issuance. Make a copy of the example file vars.example to vars:

$ bash

cd easy-rsa/easyrsa3/
cp vars.example vars
vi vars

Now, customize the vars file with your favorite editor. Uncomment the lines below and configure with your information:

vars

# Organizational fields
set_var EASYRSA_REQ_COUNTRY  "US" # Country
set_var EASYRSA_REQ_PROVINCE "California" # State
set_var EASYRSA_REQ_CITY     "Los Angeles" # City
set_var EASYRSA_REQ_ORG      "My Company" # Organization name
set_var EASYRSA_REQ_EMAIL    "contact@mycompany.com.br" # Email
set_var EASYRSA_REQ_OU       "IT Department" # Organizational Unit

# Expiration (in days)
set_var EASYRSA_CA_EXPIRE   7300 # CA validity
set_var EASYRSA_CERT_EXPIRE 3650 # Validity of issued certificates

The first set of variables refers to organizational fields, values that will be incorporated into the issued certificates. The second set of variables defines the expiration time of the (CA) certificate, and the certificates generated for the VPN server and clients.

The other variables present in the vars file should only be changed with prior knowledge of their functions and will not be covered in this article.

Running Easy-RSA

The easyrsa script is located in easy-rsa/easyrsa3, from the initial directory cloned with the git command. The basic format for executing the command is:

./easyrsa command [ options ]

Where command is the name of the command to be executed and options are the parameters that customize the command. To get help on a specific command, use:

./easyrsa help [ command ]

When executed without any parameters, the ./easyrsa script will display a list of available commands.

Initializing the PKI

This step creates the basic directory structure necessary for managing keys and certificates. Execute the command ./easyrsa init-pki.

Warning! This command removes all previously created certificates. Use it only when starting a new configuration or if you need to reconfigure the entire system.

$ bash

# Access the EasyRSA directory
cd /mnt/usb/easy-rsa/easyrsa3/

# Initialize the PKI
./easyrsa init-pki

With the Public Key Infrastructure created, you are ready to create a Certificate Authority (CA). Note that a new folder called pki/ has been created, where requests, private keys, and issued certificates will be stored, among other things.

Creating Your Own Certificate Authority (CA)

A CA is the entity responsible for issuing and managing digital certificates, which ensure security and authenticity in online communications.

During the creation of the CA's private key, you will be prompted for a password from which the file encryption will be generated. Enter a strong password and remember it, as it will be needed when signing new certificates.

You will also need to enter a name (Common Name) that will be used only for display. Choose a name to represent your CA; common options include: username, hostname, or server name.

Execute the command ./easyrsa build-ca:

# bash

# Access the EasyRSA directory
cd /mnt/usb/easy-rsa/easyrsa3/

# Create the CA
./easyrsa build-ca

If everything goes well, you will be able to see some new files inside the pki/ folder, including the ca.crt certificate.

Generating the TLS Key and Diffie-Hellman (DH) Parameters

Before proceeding with the creation of keys and certificates for the VPN client and server, two more files are needed. The TLS key prevents third parties from interfering or discovering that the VPN is in operation, while the Diffie-Hellman (DH) parameters allow OpenVPN to create a shared secret without transmitting the actual key.

$ bash

# Generate the TLS key
./easyrsa gen-tls-crypt-key

# Generate the Diffie-Hellman (DH) parameters
./easyrsa gen-dh

The TLS key can be found in pki/private/easyrsa-tls.key and the file containing the DH parameters in pki/dh.pem.

Fictional Scenario

To illustrate the following examples, let's consider a fictional scenario where employees of an office work remotely and need to connect to the company's network to perform their duties.

In this context, the OpenVPN server will be installed in the office, while the VPN clients will be configured on the employees' devices at their homes.

Generating Key and Certificate for the Server

In this step, a private key and a request for the VPN server will be generated. The request, when signed by the CA, will be converted into a certificate. The nopass parameter will be used to disable password encryption for the key.

Using a password requires it to be entered every time the VPN service is started, which may not be feasible on remote servers or those without easy keyboard access. The command follows the format:

./easyrsa gen-req [ server-name ] [ options ]

Confirm the server name when prompted during the process.

$ bash

./easyrsa gen-req office nopass

The request was generated in pki/reqs/office.req and the private key is in pki/private/office.key.

Sign the request with the following command. Answer yes when prompted to confirm the request details and enter the CA password to complete the signing.

$ bash

./easyrsa sign-req server office

The certificate will be available in pki/issued/office.crt.

Configuring the Server

From this point on, all commands must be executed as root or using sudo. Copy the following files generated by Easy-RSA to the OpenVPN configuration directory:

# bash

cp /mnt/usb/easy-rsa/easyrsa3/pki/ca.crt /etc/openvpn/certs/
cp /mnt/usb/easy-rsa/easyrsa3/pki/issued/office.crt /etc/openvpn/certs/
cp /mnt/usb/easy-rsa/easyrsa3/pki/dh.pem /etc/openvpn/certs/
cp /mnt/usb/easy-rsa/easyrsa3/pki/private/office.key /etc/openvpn/keys/
cp /mnt/usb/easy-rsa/easyrsa3/pki/private/easyrsa-tls.key /etc/openvpn/keys/

In Slackware, the OpenVPN configuration directory contains a link to sample files. Make a copy of the server.conf file to the OpenVPN folder and rename it to office.conf. If you are using another distribution and do not find this file, a complete version of the configuration file will be provided.

# bash

cd /etc/openvpn/
cp sample-config-files/server.conf office.conf

Create the ccd/ directory inside the OpenVPN folder. It will be used for client-specific configurations:

# bash

mkdir /etc/openvpn/ccd

Open the office.conf file with your favorite text editor. Below is a commented example of a functional configuration file for an OpenVPN server:

office.conf

##############################################
#   Example configuration for a OpenVPN      #
#  server with support for multiple clients. #
##############################################

local x.x.x.x  # Local IP address on which OpenVPN should listen
port  1194     # TCP/UDP port used by OpenVPN
proto udp      # Transport protocol (TCP or UDP)
dev   tun      # Tunnel type: routed (tun) or Ethernet (tap)

ca       /etc/openvpn/certs/ca.crt           # CA certificate
dh       /etc/openvpn/certs/dh.pem           # Diffie-Hellman (DH) parameters
cert     /etc/openvpn/certs/office.crt       # Server certificate
key      /etc/openvpn/keys/office.key        # Server private key
tls-auth /etc/openvpn/keys/easyrsa-tls.key 0 # TLS key (0 on server and 1 on client)

;crl-verify  /etc/openvpn/crl.pem # Certificate Revocation List

topology subnet                # Subnet /24 (255.255.255.0)
server 10.8.0.0 255.255.255.0  # Set the VPN network, server will be 10.8.0.1
ifconfig-pool-persist ipp.txt  # Keeps a record of IPs assigned to clients

# Sends a route to clients,
# allowing access to internal networks
push "route 192.168.10.0 255.255.255.0"

# Set a folder for client-specific
# configurations. Allows assigning
# fixed IPs and routes. 
client-config-dir ccd

# Uncomment to allow clients to
# communicate with each other
;client-to-client

# Sends a ping every 10 seconds and considers
# the client offline after 120 seconds
keepalive 10 120

cipher AES-256-GCM # Default encryption algorithm
data-ciphers AES-256-GCM:AES-128-GCM:AES-256-CBC # Supported algorithms
;data-ciphers-fallback AES-256-CBC # Support for older versions

# Disables compression for security reasons
allow-compression no

# Maximum number of simultaneous clients
max-clients 100

# Reduces privileges after initialization
user nobody
group nobody

# Improves connection stability
persist-key # Prevents reloading keys after a reconnection
persist-tun # Keeps the VPN interface active during a reconnection

# Path to log files
status      /var/log/openvpn-status.log
log-append  /var/log/openvpn.log

verb 3   # Log detail level
mute 20  # Silences repeated log messages after 20 displays

# Notifies clients when the server is
# restarted so they can reconnect
explicit-exit-notify 1

Tips

You can enable the service only for IPv4 using proto udp4 or only for IPv6 with proto udp6. If you prefer TCP, use proto tcp4 or proto tcp6.

It is possible to configure multiple OpenVPN servers simultaneously. To do this, simply generate the corresponding certificates and create a separate configuration file for each server within the OpenVPN directory. For example, you can have office.conf, hr.conf, it.conf, etc. In Slackware, the OpenVPN startup script will automatically load all configuration files ending in .conf within /etc/openvpn.

The entry ;crl-verify /etc/openvpn/crl.pem refers to the Certificate Revocation List. More information about this feature can be found here.

File and Directory Permissions

To increase security, it is necessary to set appropriate permissions for the files and directories within /etc/openvpn, ensuring that only authorized users have access.

# bash

# Set root as the owner of
# OpenVPN files and directories
chown -R root:root /etc/openvpn

# Only root can read and write
# configuration files
chmod 600 *.conf

# Set root as the owner and
# assign the nobody group to the
# ccd/ folder and the ipp.txt file
chown -R root:nobody ccd/ ipp.txt

# Read-only for root on
# keys and certificates
chmod -R 400 keys/ certs/

# Full access for root, read
# and execute for nobody on ccd/
chmod 750 ccd/

# Allows read and write for
# root and nobody on the ipp.txt file
chmod 660 ipp.txt

On Linux, folders need execute (x) permission to be accessed, except for the root user. Therefore, directories storing keys and certificates are configured as read-only.

Keys, certificates, and main configuration files (.conf) are read before privileges are reduced to the nobody user. Therefore, these files must belong to the root user and group. Keys and certificates only need read permission (400). Main configuration files (.conf) need read and write permission (600) for root.

The nobody user needs read and execute permission on the ccd/ directory to access client-specific configuration files. Additionally, it needs read and write permission on the ipp.txt file, which records the assigned IP addresses.

To verify the directory structure and applied permissions, use the command:

# bash

tree -ugp

├── [drwxr-x--- root     nobody  ]  ccd
├── [dr-------- root     root    ]  certs
│   ├── [-r-------- root     root    ]  ca.crt
│   ├── [-r-------- root     root    ]  dh.pem
│   └── [-r-------- root     root    ]  office.crt
├── [-rw------- root     root    ]  office.conf
├── [-rw-rw---- root     nobody  ]  ipp.txt
├── [dr-------- root     root    ]  keys
│   ├── [-r-------- root     root    ]  easyrsa-tls.key
│   └── [-r-------- root     root    ]  office.key

Starting the OpenVPN Server

The following commands are specific to Slackware. If you are using another distribution, consult the corresponding documentation, as the process may vary.

Before starting the service, grant execute permission to the OpenVPN startup script:

# bash

chmod +x /etc/rc.d/rc.openvpn

By setting this permission, the script will be executed automatically at system startup.

Commands to manage the service:

# bash

# Start the service
/etc/rc.d/rc.openvpn start

# Stop the service
/etc/rc.d/rc.openvpn stop

# Restart the service
/etc/rc.d/rc.openvpn restart

Checking Logs

Checking logs is essential to ensure that OpenVPN is functioning correctly. To facilitate debugging, it is recommended to open multiple terminals and monitor the logs while starting and stopping the service.

To follow the logs in real-time, use the following commands:

# bash

# Service log
tail -f /var/log/openvpn.log

# Connection log
tail -f /var/log/openvpn-status.log

# System log
tail -f /var/log/syslog

The above commands display new messages as they are logged until manually interrupted.

Debugging Errors

If a problem occurs in the configuration, OpenVPN will usually indicate the error in the logs. For example, if the ccd/ directory is not created or if its permissions do not allow access by the nobody user, you may receive the following message:

Options error: --client-config-dir fails with 'ccd': No such file or directory (errno=2)

Check the logs to identify and fix errors during service startup. If OpenVPN starts correctly, the openvpn.log file will display the following message: Initialization Sequence Completed.

Important

In this example, OpenVPN was configured to reduce privileges after initialization, switching to the nobody user. However, when shutting down OpenVPN on Slackware, both on the server and client, permission errors occur when removing IPs and routes. These failures generate messages like the following in the logs:

/var/log/openvpn.log

/usr/sbin/ip addr del dev tun0 10.8.0.1/24
RTNETLINK answers: Operation not permitted
Linux ip addr del failed: external program exited with error status: 2

To work around this issue, various approaches were tested without success, such as executing external scripts via the down and down-pre options along with the script-security directive, configuring sudo to allow the nobody user to execute the ip command, and using the openvpn-plugin-down-root.so plugin.

The good news is that, even with the error messages, the necessary actions are executed correctly: the IPs and routes are removed, and the VPN interface is deactivated as expected. During the tests conducted for this material, no functional issues arising from this error were identified, so the adopted option was simply to ignore it.

If you wish to avoid these messages, an alternative is to run OpenVPN directly as root, without reducing privileges. However, this may have security implications.

Checking the VPN

Confirm if the VPN interface has been created:

# bash

ifconfig

tun0: flags=4305[UP,POINTOPOINT,RUNNING,NOARP,MULTICAST]  mtu 1500
        inet 10.8.0.1  netmask 255.255.255.0  destination 10.8.0.1

If the interface is active, your server is running and ready to receive connections. Now, let's move on to the client configuration.

Generating Key and Certificate for the Client

In this step, a private key and a certificate request for the VPN client will be generated. Execute the commands from the Easy-RSA base directory. In the example, we use /mnt/usb/easy-rsa/easyrsa3/. When prompted, confirm the client name. Here, we will use home.

$ bash

./easyrsa gen-req home nopass

This will generate the request in pki/reqs/home.req and the private key in pki/private/home.key.

Sign the request using the CA's private key. Answer yes when prompted to confirm the details and enter the CA password when prompted:

$ bash

./easyrsa sign-req client home

The client certificate will be generated in pki/issued/home.crt.

Configuring the Client

Copy the files generated by Easy-RSA to the OpenVPN configuration directory. In this article, the files are stored on a USB drive. If transferring them to a remote location, use secure methods such as SSH (scp, sftp) or HTTPS:

# bash

cp /mnt/usb/easy-rsa/easyrsa3/pki/ca.crt /etc/openvpn/certs/
cp /mnt/usb/easy-rsa/easyrsa3/pki/issued/home.crt /etc/openvpn/certs/
cp /mnt/usb/easy-rsa/easyrsa3/pki/private/home.key /etc/openvpn/keys/
cp /mnt/usb/easy-rsa/easyrsa3/pki/private/easyrsa-tls.key /etc/openvpn/keys/

Create the configuration file home.conf in the OpenVPN configuration directory. You can use the example file client.conf, available in sample-config-files, as a base.

Open the home.conf file with your favorite editor.

# bash

vi /etc/openvpn/home.conf

Below is a commented example of a functional configuration file for an OpenVPN client:

home.conf

###################################################
# Example configuration for an OpenVPN client     #
###################################################

client                # Configure as client
dev tun               # Use a routed tunnel (tun)
proto udp             # TCP or UDP?
remote 10.0.0.68 1194 # Server IP and port

ca       /etc/openvpn/certs/ca.crt           # CA certificate
cert     /etc/openvpn/certs/home.crt         # Client certificate
key      /etc/openvpn/keys/home.key          # Client private key
tls-auth /etc/openvpn/keys/easyrsa-tls.key 1 # TLS key (1 on client)

# If a domain name is used in the "remote"
# parameter, this option makes the client
# try to resolve it indefinitely
resolv-retry infinite

# Uses random ports when connecting to the server
nobind

# Reduces privileges after initialization
user nobody
group nobody

# Improves connection stability
persist-key # Keeps keys loaded after a reconnection
persist-tun # Keeps the network interface active during a reconnection

# Requires the server certificate to be correctly validated
remote-cert-tls server

# Defines the encryption algorithm for communication
cipher AES-256-GCM

# Path to log files
status      /var/log/openvpn-status.log
log-append  /var/log/openvpn.log

verb 3   # Log message detail level
mute 20  # Silences repeated log messages after 20 occurrences

Starting the OpenVPN Client

Grant execute permission to the OpenVPN startup script:

# bash

chmod +x /etc/rc.d/rc.openvpn

With this permission, the script can be executed manually and will also start automatically with the system.

Commands to manage the service:

# bash

# Start the service
/etc/rc.d/rc.openvpn start

# Stop the service
/etc/rc.d/rc.openvpn stop

# Restart the service
/etc/rc.d/rc.openvpn restart

Checking Logs

As with the server, logs are essential for diagnosing issues and verifying that the OpenVPN client is functioning correctly.

Use the following commands to monitor logs in real-time:

# bash

# Service log
tail -f /var/log/openvpn.log

# Connection log
tail -f /var/log/openvpn-status.log

# System log
tail -f /var/log/syslog

Checking the VPN

If the message Initialization Sequence Completed appears in the openvpn.log file, it indicates that the client has started correctly. To confirm that the VPN is working as expected, check if the VPN interface has been created and if the routes configured with the push command on the server have been applied correctly:

# bash

# Check if the tun0 interface has been created
ifconfig

tun0: flags=4305[UP,POINTOPOINT,RUNNING,NOARP,MULTICAST]  mtu 1500
        inet 10.8.0.2  netmask 255.255.255.0  destination 10.8.0.2

# List the configured network routes
route -n

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.10.0    10.8.0.1        255.255.255.0   UG    0      0        0 tun0

If everything is correct, your VPN tunnel is active and ready for use.

Conclusion

This text provides a detailed guide for configuring an OpenVPN tunnel on Linux, using Easy-RSA for certificate and key management. It covers everything from installing the necessary packages to creating and signing certificates, configuring the OpenVPN server and client, adjusting file and directory permissions, and checking logs to ensure the service is functioning correctly.

For a deeper understanding of certificate management, including conceptual aspects, security criteria, and details on using Easy-RSA, we recommend reading the complementary article:

References

Older articles from this site served as a starting point for the creation of this text. The manuals (man pages) available on Slackware Linux were also used.

Site Notes

This is not my original language and I don't speak it very well. I used my little knowledge and translators tools to compose the text of this article. Sorry for possible spelling or grammatical errors, suggestions for corrections are appreciated and can be sent to the contact email in the footer of the site. My intention is to share some knowledge and I hope this translation is good enough.


Some of the content on this website, including text, images, graphics and other materials, may be generated or enhanced by artificial intelligence (AI) tools. For more details on the use of AI, please see our Term of Use.