SSH VPN tutorial

How To Setup Openvpn On Ubuntu Server

13 min read
Configuring a custom payload and free SSH account on the HTTP Injector Android application.

Mastering Secure Remote Access: A Comprehensive Guide to Setting Up OpenVPN on Ubuntu Server

In an increasingly interconnected digital landscape, the imperative for robust network security has never been more pronounced. Whether you’re a burgeoning startup safeguarding proprietary data, a remote professional accessing critical resources, or simply an individual prioritizing online privacy, a Virtual Private Network (VPN) stands as an indispensable cornerstone of your cybersecurity architecture. Among the myriad VPN solutions available, OpenVPN distinguishes itself as a formidable, open-source contender, renowned for its unparalleled security features, flexibility, and cross-platform compatibility. When deployed on an Ubuntu server, it creates a highly secure and customizable gateway for all your remote access needs.

This comprehensive guide is meticulously crafted for system administrators, network engineers, and technically inclined individuals seeking to establish a secure, reliable, and high-performance OpenVPN server on an Ubuntu environment. We will navigate through each critical step, from initial server preparation to advanced client configuration, ensuring you gain not only a functional VPN but also a profound understanding of the underlying principles. Prepare to delve deep into the intricacies of Public Key Infrastructure (PKI), firewall management, and network routing, transforming your Ubuntu server into a formidable bastion of secure communication.

Why OpenVPN on Ubuntu Server? The Unbeatable Combination

Before we embark on the technical journey, let’s briefly underscore the compelling advantages of this specific pairing:

  • Robust Security: OpenVPN leverages industry-standard SSL/TLS protocols for key exchange and employs a highly customizable encryption suite, including AES, Blowfish, and more. Its reliance on a strong Public Key Infrastructure (PKI) with certificates ensures mutual authentication, making it incredibly resilient against eavesdropping and unauthorized access.
  • Open Source Transparency: Being open-source, OpenVPN’s codebase is subject to continuous scrutiny by a global community of security experts. This transparency fosters trust and allows for rapid identification and patching of potential vulnerabilities, making it a more secure choice than many proprietary alternatives.
  • Flexibility and Customization: OpenVPN is incredibly versatile. It can operate over both UDP (User Datagram Protocol) for speed and TCP (Transmission Control Protocol) for reliability, making it adaptable to various network conditions. Its extensive configuration options allow for fine-tuning performance, security parameters, and routing rules.
  • Cross-Platform Compatibility: OpenVPN offers client software for virtually every operating system imaginable – Windows, macOS, Linux, Android, iOS. This ensures that users can connect from almost any device.
  • Ubuntu’s Stability and Community Support: Ubuntu Server is a popular, stable, and well-documented Linux distribution. Its vast community and extensive repositories simplify installation, maintenance, and troubleshooting, making it an ideal host for critical services like OpenVPN.

Prerequisites for Your OpenVPN Deployment

Before we dive into the configuration, ensure you have the following in place:

  • An Ubuntu Server Instance: This guide assumes you have a fresh installation of an Ubuntu Server (e.g., 20.04 LTS or 22.04 LTS). It can be a physical machine, a virtual machine (VM), or a cloud instance (AWS, Azure, Google Cloud, DigitalOcean, Linode, etc.).
  • Root or Sudo Privileges: You’ll need administrative access to install packages and modify system configurations.
  • Basic Linux Command-Line Familiarity: Comfort with commands like apt, cd, cp, nano/vim, systemctl, etc., will be beneficial.
  • Static Public IP Address or Domain Name: Your OpenVPN server needs a consistent public IP address for clients to connect. If your server’s public IP is dynamic, consider using a Dynamic DNS (DDNS) service. For production environments, a dedicated domain name pointing to your server is highly recommended.
  • Open Ports: Ensure that the default OpenVPN port (1194 UDP) is open on your server’s network firewall (if applicable) and any upstream network devices (e.g., router, cloud security groups).

Step-by-Step Guide: Setting Up OpenVPN on Ubuntu Server

This section will walk you through the entire setup process, providing detailed commands and explanations for each step. We’ll leverage Easy-RSA, a command-line utility for managing a PKI, to simplify certificate generation.

Step 1: Update Your Ubuntu Server

It’s always a best practice to ensure your server’s package list and installed packages are up to date. This ensures you have the latest security patches and stable software versions.


sudo apt update
sudo apt upgrade -y

Step 2: Install OpenVPN and Easy-RSA

The core components we need are the OpenVPN server package and Easy-RSA, which will help us manage our digital certificates.


sudo apt install openvpn easy-rsa -y

Step 3: Configure the Certificate Authority (CA)

A Certificate Authority (CA) is the root of trust in our PKI. It’s responsible for issuing and signing digital certificates for both the OpenVPN server and its clients. We’ll set up a dedicated directory for Easy-RSA.

First, create a directory for your PKI and copy the Easy-RSA scripts into it:


mkdir ~/easy-rsa
cp -r /usr/share/easy-rsa/* ~/easy-rsa/

Now, navigate into the Easy-RSA directory and initialize the PKI:


cd ~/easy-rsa
chmod 700 .
./easyrsa init-pki

Next, build the CA. You’ll be prompted to enter a Common Name (CN) for your CA. This can be anything descriptive, like “MyOpenVPN_CA”.


./easyrsa build-ca nopass

The nopass option means the CA key won’t be password-protected. For higher security, especially in production, you might want to omit nopass and set a strong password. Remember this password, as you’ll need it to sign certificates.

Step 4: Generate Server Certificate and Key

Now we’ll generate the server’s private key and a certificate request, then sign it with our CA.

Generate the server key and certificate request. You’ll be prompted for a Common Name for the server; use something like “server”.


./easyrsa gen-req server nopass

Sign the server certificate with the CA. You’ll be asked to confirm, type “yes”. If you set a password for your CA, you’ll need to enter it here.


./easyrsa sign-req server server

Step 5: Generate Diffie-Hellman Parameters and TLS Authentication Key

The Diffie-Hellman (DH) parameters are crucial for secure key exchange, ensuring forward secrecy. The TLS authentication key (ta.key) provides an additional layer of security, protecting against DoS attacks and UDP port scanning.

Generate DH parameters. This can take some time, especially for larger key sizes (e.g., 4096 bits). The default is 2048 bits, which is generally sufficient.


./easyrsa gen-dh

Generate the TLS authentication key:


openvpn --genkey --secret pki/ta.key

Step 6: Configure the OpenVPN Server

Now that we have all our cryptographic assets, it’s time to set up the OpenVPN server configuration file.

First, copy all the generated certificates and keys to the OpenVPN configuration directory:


sudo mkdir /etc/openvpn/server
sudo cp pki/ca.crt /etc/openvpn/server/
sudo cp pki/issued/server.crt /etc/openvpn/server/
sudo cp pki/private/server.key /etc/openvpn/server/
sudo cp pki/dh.pem /etc/openvpn/server/dh.pem
sudo cp pki/ta.key /etc/openvpn/server/ta.key

Next, create the main OpenVPN server configuration file, typically named server.conf:


sudo nano /etc/openvpn/server/server.conf

Paste the following configuration into the file. We’ll go through key directives:


# OpenVPN Server Configuration

# Which local IP address should OpenVPN listen on? (Optional)
# local A.B.C.D

# Which port should OpenVPN listen on?
port 1194

# Use UDP for faster connections, TCP for reliability (e.g., over restrictive networks)
proto udp

# Use a TUN device for IP tunneling
dev tun

# CA certificate, server certificate, and server key
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key

# Diffie-Hellman parameters for key exchange
dh /etc/openvpn/server/dh.pem

# TLS-Auth key for an extra layer of security (HMAC signature)
tls-auth /etc/openvpn/server/ta.key 0 # This is the server side

# VPN subnet and netmask for clients
# This defines the virtual IP addresses assigned to clients
# Example: 10.8.0.0 255.255.255.0 will assign IPs from 10.8.0.2 to 10.8.0.254
server 10.8.0.0 255.255.255.0

# Push DNS servers to clients (e.g., Google DNS, Cloudflare DNS)
# Google DNS:
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
# Cloudflare DNS:
# push "dhcp-option DNS 1.1.1.1"
# push "dhcp-option DNS 1.0.0.1"

# Redirect all client traffic through the VPN (full tunnel)
# This pushes a default route to the client, effectively making the VPN server their default gateway.
push "redirect-gateway def1 bypass-dhcp"

# Allow clients to "see" each other (optional)
client-to-client

# Keepalive for connection stability (ping every 10 seconds, timeout after 120 seconds)
keepalive 10 120

# Persist key and tunnel to avoid renegotiation on connection drops
persist-key
persist-tun

# Cipher for data encryption (AES-256-GCM is highly recommended for modern systems)
cipher AES-256-GCM

# Authentication hash algorithm
auth SHA256

# Compress VPN traffic (optional, can improve performance but may increase CPU usage)
# comp-lzo
# For newer OpenVPN clients, consider:
# compress lz4-v2
# push "compress lz4-v2"

# User and group for OpenVPN process (run as non-root for security)
user nobody
group nogroup

# Status log file
status /var/log/openvpn/openvpn-status.log

# Verbosity level (0-9, 3 is good for production, 5 for debugging)
verb 3

# Log file for OpenVPN messages
log-append /var/log/openvpn/openvpn.log

# Enable management interface (optional, for monitoring and control)
# management localhost 7505

Save and close the file (Ctrl+X, Y, Enter in Nano).
Create the log directory:


sudo mkdir -p /var/log/openvpn

Step 7: Adjust Network Configuration (IP Forwarding)

For the OpenVPN server to properly route client traffic to the internet, IP forwarding must be enabled on the server. This allows the kernel to pass packets between network interfaces.


sudo nano /etc/sysctl.conf

Uncomment or add the following line:


net.ipv4.ip_forward=1

Save and close the file. Apply the changes without rebooting:


sudo sysctl -p

Step 8: Configure Firewall (UFW)

UFW (Uncomplicated Firewall) is the default firewall management tool on Ubuntu. We need to allow OpenVPN traffic and enable NAT (Network Address Translation), specifically masquerading, so clients can access the internet through the server’s public IP.

First, allow SSH and the OpenVPN port (1194 UDP):


sudo ufw allow ssh
sudo ufw allow 1194/udp

Next, we need to configure UFW for NAT. Find your server’s public network interface. You can often find it using ip a or ifconfig. Common names are eth0, ens3, enp0s3, etc. Let’s assume it’s eth0 for this example.


sudo nano /etc/default/ufw

Change DEFAULT_FORWARD_POLICY="DROP" to DEFAULT_FORWARD_POLICY="ACCEPT".

Now, edit the UFW rules to add NAT (masquerading):


sudo nano /etc/ufw/before.rules

Add the following lines at the very top of the file, after the comments but before the *filter line:


# START OPENVPN RULES
# Allow all on tun0 interface
-A ufw-before-input -i tun0 -j ACCEPT
-A ufw-before-output -o tun0 -j ACCEPT
-A ufw-before-forward -i tun0 -j ACCEPT
-A ufw-before-forward -o tun0 -j ACCEPT
# NAT for OpenVPN clients
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES

Important: Replace eth0 with your actual public network interface name if it’s different. Replace 10.8.0.0/24 with your OpenVPN subnet if you changed it in server.conf.

Save and close the file. Now, enable and restart UFW:


sudo ufw disable
sudo ufw enable
sudo ufw status verbose

Verify that UFW is active and the rules are correctly applied.

Step 9: Start and Enable OpenVPN Service

With all configurations in place, we can now start the OpenVPN service and enable it to launch automatically at boot time.


sudo systemctl start openvpn@server
sudo systemctl enable openvpn@server
sudo systemctl status openvpn@server

Check the status to ensure it’s running without errors. You can also check the logs for any issues:


sudo tail -f /var/log/openvpn/openvpn.log

Step 10: Generate Client Certificates and Configuration Files

Each client connecting to your OpenVPN server needs its own unique certificate and key, signed by your CA. We’ll also create a client configuration file (.ovpn) that bundles all necessary information for easy client setup.

Return to your Easy-RSA directory:


cd ~/easy-rsa

Generate a client key and certificate request (e.g., for “client1”). You’ll be prompted for a Common Name; use “client1” or any unique identifier for the client.


./easyrsa gen-req client1 nopass

Sign the client certificate with the CA:


./easyrsa sign-req client client1

Now, let’s create a directory to store client configuration files and move the necessary files there:


mkdir -p ~/client-configs/files
chmod 700 ~/client-configs/files
cp pki/ca.crt ~/client-configs/files/
cp pki/issued/client1.crt ~/client-configs/files/
cp pki/private/client1.key ~/client-configs/files/
cp pki/ta.key ~/client-configs/files/

Create a base client configuration file template (base.conf) in ~/client-configs:


nano ~/client-configs/base.conf

Paste the following content:


# OpenVPN Client Configuration

client
dev tun
proto udp

# Replace YOUR_SERVER_IP with your server's public IP address or domain name
remote YOUR_SERVER_IP 1194

resolv-retry infinite
nobind

persist-key
persist-tun

ca ca.crt
cert client1.crt
key client1.key

remote-cert-tls server

tls-auth ta.key 1 # This is the client side

cipher AES-256-GCM
auth SHA256

# For newer OpenVPN clients, if you enabled compression on server:
# compress lz4-v2
# verb 3

Crucially, replace YOUR_SERVER_IP with your OpenVPN server’s actual public IP address or domain name.

Save and close base.conf. Now, create a script to generate the final .ovpn client file, which embeds all certificates and keys:


nano ~/client-configs/make_config.sh

Paste the following script:


#!/bin/bash

# Script to generate client OpenVPN configuration files

if [ -z "$1" ]; then
    echo "Usage: $0 "
    exit 1
fi

CLIENT_NAME=$1
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf

if [ ! -f "$OUTPUT_DIR/$CLIENT_NAME.crt" ]; then
    echo "Client certificate not found for $CLIENT_NAME. Please generate it first."
    exit 1
fi

cat ${BASE_CONFIG} 
    <(echo -e '<ca>') 
    ${OUTPUT_DIR}/ca.crt 
    <(echo -e '</ca>n<cert>') 
    ${OUTPUT_DIR}/${CLIENT_NAME}.crt 
    <(echo -e '</cert>n<key>') 
    ${OUTPUT_DIR}/${CLIENT_NAME}.key 
    <(echo -e '</key>n<tls-auth>') 
    ${OUTPUT_DIR}/ta.key 
    <(echo -e '</tls-auth>') 
    > ${OUTPUT_DIR}/${CLIENT_NAME}.ovpn

echo "Client configuration for ${CLIENT_NAME}.ovpn created in ${OUTPUT_DIR}"

Save and close the script. Make it executable:


chmod 700 ~/client-configs/make_config.sh

Now, generate the .ovpn file for “client1”:


~/client-configs/make_config.sh client1

Your client configuration file client1.ovpn is now located in ~/client-configs/files/. You will need to securely transfer this file to your client device. A common method is using scp:


scp ~/client-configs/files/client1.ovpn user@your_local_machine_ip:/path/to/destination/

On your client device, import this .ovpn file into your OpenVPN client software (e.g., OpenVPN Connect, Tunnelblick, NetworkManager). Once imported, you should be able to connect to your newly established OpenVPN server.

Advanced Considerations and Best Practices

A functional OpenVPN setup is a great start, but a truly secure and robust deployment requires adherence to best practices and consideration of advanced features.

Security Hardening

  • Stronger Ciphers and Authentication: While AES-256-GCM and SHA256 are strong, always stay updated with the latest recommendations. Periodically review your cipher and auth directives.
  • Non-Root Execution: We configured OpenVPN to run as nobody:nogroup, which is a good security measure. Ensure the directories and files it accesses have appropriate permissions.
  • Multi-Factor Authentication (MFA): For critical environments, integrate OpenVPN with MFA solutions (e.g., Google Authenticator via PAM modules) to add an extra layer of security beyond just certificates.
  • Regular Updates: Keep your Ubuntu server and OpenVPN packages updated to protect against known vulnerabilities.
  • Physical Security: If your server is physical, ensure its physical access is restricted.

Client Management and Revocation

As clients come and go, you’ll need a way to revoke access for compromised or departed users. Easy-RSA facilitates this through a Certificate Revocation List (CRL).

To revoke a client certificate (e.g., client1):


cd ~/easy-rsa
./easyrsa revoke client1
./easyrsa gen-crl
sudo cp pki/crl.pem /etc/openvpn/server/crl.pem
sudo systemctl restart openvpn@server

You also need to add the crl-verify directive to your server.conf: