OpenVPN is a powerful open-source VPN platform designed to establish secure point-to-point and site-to-site connections. It relies on encrypted tunnels based on TLS (Transport Layer Security) to safely transfer data across untrusted networks such as the Internet. With support for multiple encryption methods like AES-256, OpenVPN ensures that network communication is shielded from eavesdropping and man-in-the-middle threats.
This guide walks you through installing OpenVPN on Ubuntu 24.04 and configuring it to create secure, end-to-end encrypted connections between the VPN server and client systems.
Prerequisites
Before you begin, ensure that you:
- Have an Ubuntu 24.04 server and a non-root user that can run commands with sudo.
Matching infrastructure at centron
No hardware needed to follow along: ccloud³ VMs with full root access start at €3.12 per month, billed by the hour and ready in seconds. Rent a cloud server →
Install OpenVPN
OpenVPN can be installed directly from Ubuntu’s official repositories. Follow the steps below to refresh your APT package index and install the OpenVPN package.
Update the APT package index
$ sudo apt updateInstall OpenVPN
$ sudo apt install openvpn -yCheck the OpenVPN version
$ openvpn --versionYour output should look similar to this:
OpenVPN 2.6.12 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] [DCO]
library versions: OpenSSL 3.0.13 30 Jan 2024, LZO 2.10
DCO version: N/A
Originally developed by James Yonan
.................................................................
OpenVPN 2.6.12 is installed based on the above output.
Create the OpenVPN Server Private Key, Certificate, and TLS Encryption Files
OpenVPN needs a server certificate, private key, and encryption files validated by a certificate authority (CA). Easy-RSA is a tool used to generate these certificates and keys for applications like OpenVPN. The instructions below explain how to install Easy-RSA, set up the public key infrastructure (PKI), create a CA, and generate server certificates and keys.
Install Easy-RSA
$ sudo apt install easy-rsa -yNavigate to the home directory
$ cdCreate a new easy-rsa directory
$ mkdir easy-rsaLink the Easy-RSA scripts
$ ln -s /usr/share/easy-rsa/* easy-rsa/List the easy-rsa directory
$ ls easy-rsaOutput:
easyrsa openssl-easyrsa.cnf vars.example x509-types
Switch to the easy-rsa directory
$ cd easy-rsaCreate a vars file
$ nano varsAdd CA configuration values
set_var EASYRSA_REQ_COUNTRY "Germany"
set_var EASYRSA_REQ_PROVINCE "Bavaria"
set_var EASYRSA_REQ_CITY "Bamberg"
set_var EASYRSA_REQ_ORG "Docs"
set_var EASYRSA_REQ_EMAIL "linuxuser@example.de"
set_var EASYRSA_REQ_OU "Community"
set_var EASYRSA_ALGO "ec"
set_var EASYRSA_DIGEST "ta222"These values define the organization information for your certificate authority.
Initialize the PKI
$ ./easyrsa init-pkiOutput:
Notice
------
'init-pki' complete; you may now create a CA or requests.
Your newly created PKI dir is:
* /home/linuxuser/easy-rsa/pki
Using Easy-RSA configuration:
* /home/linuxuser/easy-rsa/vars
Build the CA
$ ./easyrsa build-caEnter a secure passphrase and specify a common name such as OpenVPN-CA.
Notice
------
CA creation complete. Your new CA certificate is at:
* /home/linuxuser/easy-rsa/pki/ca.crt
Generate the server certificate request
$ ./easyrsa gen-req vpnserver nopassOutput paths:
Notice
------
Private-Key and Public-Certificate-Request files created.
Your files are:
* req: /home/linuxuser/easy-rsa/pki/reqs/vpnserver.req
* key: /home/linuxuser/easy-rsa/pki/private/vpnserver.key
Sign the server certificate request
$ ./easyrsa sign-req server vpnserverConfirm with yes and enter your CA passphrase.
Notice
------
Certificate created at:
* /home/linuxuser/easy-rsa/pki/issued/vpnserver.crt
Verify the server certificate
$ ls pki/issuedOutput:
vpnserver.crt
Create the HMAC key for TLS authentication
$ sudo openvpn --genkey secret ta.key$ lsOutput:
df.pem easyrsa openssl-easyrsa.cnf pki ta.key vars vars.example x509-types
Generate Diffie-Hellman parameters
$ ./easyrsa gen-dhOutput:
Generating DH parameters, 2048 bit long safe prime
.....................
DH parameters appear to be ok.
Notice
------
DH parameters of size 2048 created at:
* /home/linuxuser/easy-rsa/pki/dh.pem
Verify the dh.pem file
$ ls pki/Output:
ca.crt dh.pem .....................
Copy certificate and key files to /etc/openvpn
$ sudo cp ta.key pki/ca.crt pki/private/vpnserver.key pki/issued/vpnserver.crt pki/dh.pem /etc/openvpn/Configure OpenVPN
OpenVPN relies on configuration files stored in /etc/openvpn to define tunnel interfaces and manage related systemd services. Files placed inside /etc/openvpn are controlled using the openvpn@ service, while additional configurations inside /etc/openvpn/server are handled through openvpn-server@. The steps below describe how to create a new OpenVPN server configuration within /etc/openvpn to activate a VPN tunnel interface on your machine.
Copy the server configuration template
$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/Switch to the OpenVPN directory
$ cd /etc/openvpnEdit the server.conf file
$ sudo nano server.confOptional: Uncomment the local directive and replace the placeholder IP address with your server’s public IP address.
local 192.0.2.100Verify the tunnel device type
dev tuntun creates routed IP tunnels, while tap generates Ethernet-based tunnels.
Specify CA, certificate, and key paths
ca /etc/openvpn/ca.crt
cert /etc/openvpn/vpnserver.crt
key /etc/openvpn/vpnserver.keyThese directives define the CA file, the public certificate, and the private key used for secure server verification.
Define the Diffie-Hellman file
dh /etc/openvpn/dh.pemEnable strong encryption ciphers
data-ciphers AES-256-GCM:AES-128-GCM:?CHACHA20-POLY1305:AES-256-CBC
data-ciphers-fallback AES-256-CBCDefine the HMAC authentication algorithm
auth SHA512Configure the VPN subnet
server 10.10.10.0 255.255.255.0Redirect all client traffic through VPN
push "redirect-gateway def1 bypass-dhcp"Define DNS resolvers for VPN clients
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 1.1.1.1"Enable TLS authentication
tls-auth /etc/openvpn/ta.key 0 # This file is secretChange user and group for security
user nobody
group nogroupExample of a modified server.conf
port 1194
proto udp
dev tun
ca /etc/openvpn/ca.crt
cert /etc/openvpn/vpnserver.crt
key /etc/openvpn/vpnserver.key
dh /etc/openvpn/dh.pem
data-ciphers AES-256-GCM:AES-128-GCM:?CHACHA20-POLY1305:AES-256-CBC
data-ciphers-fallback AES-256-CBC
auth SHA512
topology subnet
server 10.10.10.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 1.1.1.1"
keepalive 10 120
tls-auth /etc/openvpn/ta.key 0
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
verb 3
explicit-exit-notify 1Test the OpenVPN server configuration
$ sudo openvpn --config /etc/openvpn/server.confExpected success output:
...
2025-07-10 22:21:00 IFCONFIG POOL IPv4: base=10.10.10.2 size=253
2025-07-10 22:21:00 IFCONFIG POOL LIST
2025-07-10 22:21:00 Initialization Sequence Completed
Press Ctrl + C to exit the test.
Enable IP Forwarding
IP forwarding must be enabled on the server so OpenVPN clients can access the Internet through the VPN tunnel.
Edit sysctl.conf
$ sudo nano /etc/sysctl.confUncomment the following line:
net.ipv4.ip_forward=1This enables IPv4 forwarding for routing VPN client traffic.
Apply changes
$ sudo sysctl -pOutput:
net.ipv4.ip_forward = 1
Check the public network interface
$ ip route | grep defaultExample output:
default via 192.0.2.1 dev enp1s0 proto dhcp src 192.0.2.100 metric 100
Check UFW firewall status
$ sudo ufw statusIf needed, install UFW and allow SSH
$ sudo apt install ufw -y && sudo ufw allow sshEdit UFW before.rules to enable NAT
$ sudo nano /etc/ufw/before.rulesAdd the following before *filter, replacing enp1s0 with your public interface:
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.10.10.0/24 -o enp1s0 -j MASQUERADE
COMMITEnable IP forwarding within UFW
$ sudo nano /etc/ufw/sysctl.confUncomment:
net/ipv4/ip_forward=1Allow forwarded packets in UFW
$ sudo nano /etc/default/ufwModify:
DEFAULT_FORWARD_POLICY="ACCEPT"Reload UFW
$ sudo ufw reloadSecure the OpenVPN Server
Follow the instructions below to allow traffic to reach your OpenVPN service using the default firewall settings.
Permit traffic entering through the tun0 interface
$ sudo ufw allow in on tun0Permit outgoing connections from tun0
$ sudo ufw allow out on tun0Allow traffic to the OpenVPN port 1194/udp
$ sudo ufw allow 1194/udpReload UFW to activate the new firewall rules
$ sudo ufw reloadCheck that UFW is enforcing the correct rules
$ sudo ufw statusOutput:
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
Anywhere on tun0 ALLOW Anywhere
1194/udp ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
Anywhere (v6) on tun0 ALLOW Anywhere (v6)
1194/udp (v6) ALLOW Anywhere (v6)
Anywhere ALLOW OUT Anywhere on tun0
Anywhere (v6) ALLOW OUT Anywhere (v6) on tun0
Manage the OpenVPN Server
OpenVPN relies on systemd services to handle VPN tunnel interfaces defined inside the /etc/openvpn directory. Follow the instructions below to activate, manage, and inspect your server’s OpenVPN service.
Enable OpenVPN to start automatically at boot
$ sudo systemctl enable openvpn@server.serviceOutput:
Created symlink /etc/systemd/system/multi-user.target.wants/openvpn@server.service → /usr/lib/systemd/system/openvpn@.service.
Start the OpenVPN service
$ sudo systemctl start openvpn@server.serviceCheck the current OpenVPN service status
$ sudo systemctl status openvpn@server.serviceOutput:
● openvpn@server.service - OpenVPN connection to server
Loaded: loaded (/usr/lib/systemd/system/openvpn@.service; enabled; preset: enabled)
Active: active (running) since Thu 2025-07-10 22:27:07 UTC; 6s ago
...
Verify the tun0 interface is active
$ ip addr show dev tun0Output:
4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq state UNKNOWN group default qlen 500
link/none
inet 10.10.10.1/24 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::42ab:ad8b:dd59:baf4/64 scope link stable-privacy
valid_lft forever preferred_lft forever
Create a Client Certificate and Private Key Pair
Each OpenVPN client needs its own certificate and private key to authenticate with the server. Follow these steps to generate a client key pair and certificate request.
Create a keys directory for client files
$ sudo mkdir -p /etc/openvpn/client/keysMove into the Easy-RSA directory
$ cd ~/easy-rsaCreate a certificate request for a new client
$ ./easyrsa gen-req vpnclient1 nopassPress Enter when asked to confirm the common name.
Notice
------
Private-Key and Public-Certificate-Request files created.
Your files are:
* req: /home/linuxuser/easy-rsa/pki/reqs/vpnclient1.req
* key: /home/linuxuser/easy-rsa/pki/private/vpnclient1.key
Sign the client certificate request
$ ./easyrsa sign-req client vpnclient1Confirm with yes when prompted, then enter your CA passphrase.
Notice
------
Certificate created at:
* /home/linuxuser/easy-rsa/pki/issued/vpnclient1.crt
Copy the certificate and key to the client keys directory
$ sudo cp pki/issued/vpnclient1.crt /etc/openvpn/client/keys$ sudo cp pki/private/vpnclient1.key /etc/openvpn/client/keysCreate OpenVPN Client Configuration Files
Copy the example client configuration
$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/clientMove into the client configuration directory
$ cd /etc/openvpn/clientRename the client.conf to vpnclient1.ovpn
$ sudo mv client.conf vpnclient1.ovpnChoose your file format depending on your client device. .ovpn is recommended for graphical OpenVPN clients on Windows, macOS, iOS, or Android.
Edit the client configuration file
$ sudo nano vpnclient1.ovpnSet the remote OpenVPN server address
remote 192.0.2.100 1194Comment out CA, cert, and key directives
#ca ca.crt
#cert client.crt
#key client.keyDefine encryption algorithms
data-ciphers AES-256-GCM:AES-128-GCM:?CHACHA20-POLY1305:AES-256-CBCSpecify the authentication digest
auth SHA512Your updated client file should resemble the following:
client
dev tun
proto udp
remote 192.0.2.100 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305:AES-256-CBC
auth SHA512
verb 3Append certificate, key, and TLS authentication blocks
$ sudo bash -c 'cat <> vpnclient1.ovpn
$(< /etc/openvpn/ca.crt)
$(< keys/vpnclient1.crt)
$(< keys/vpnclient1.key)
$(< /etc/openvpn/ta.key)
key-direction 1
EOF'Verify the appended OpenVPN client file
$ cat vpnclient1.ovpnCopy the final .ovpn file to your home directory
$ cp vpnclient1.ovpn ~/vpnclient1.ovpnTest the OpenVPN Server
Use OpenVPN Connect to test the connection between your client and server.
Download OpenVPN Connect
Install the OpenVPN Connect application from the official website for your device.
Open a terminal session on your workstation
$ cdConnect to the server using SFTP
$ sftp linuxuser@SERVER-IPList files and verify vpnclient1.ovpn exists
sftp> lsDownload the client configuration file
sftp> get vpnclient1.ovpnOutput:
Fetching /home/linuxuser/vpnclient1.ovpn to vpnclient1.ovpn
vpnclient1.ovpn 100% 8281 539.1KB/s 00:00
Import the configuration into OpenVPN Connect
Open the app → click UPLOAD FILE → browse to the downloaded file → import it. Confirm the server hostname and connect.
Verify the public IP through curl
$ curl ifconfig.meTest internet connectivity
$ ping google.comOutput:
Pinging google.com [172.217.170.174] with 32 bytes of data:
Reply from 172.217.170.174: bytes=32 time=26ms TTL=108
Reply from 172.217.170.174: bytes=32 time=28ms TTL=108
Reply from 172.217.170.174: bytes=32 time=36ms TTL=108
Reply from 172.217.170.174: bytes=32 time=29ms TTL=108
Ping statistics:
Sent = 4, Received = 4, Lost = 0 (0% loss)
Average = 29ms
Troubleshooting
Fixing Connection Timeout
Open your client configuration and ensure the remote directive is correct.
$ code vpnclient1.ovpnremote 192.0.2.100 1194Check UFW and ensure the port is allowed:
$ sudo ufw status$ sudo ufw allow 1194/tcp$ sudo ufw reloadFixing Authentication/Decrypt Packet Errors
These errors usually indicate incorrect TLS authentication settings.
View server logs:
$ sudo journalctl -xeu openvpn-server@server.serviceInspect the ta.key file
$ sudo cat /etc/openvpn/ta.keyYour output should resemble:
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
1ba01f852d75016a3fd1b3b88aef9609
d52f7dd4e7858f0a219f5b9ec65b37c1
efe9458fe0e06b2ae4d1f9fee3aee929
959bd0e9e260588023fed611d803a769
108dfd5157dd95f6a627c486361e7c6d
753d65f6c25fd2278a44a872e5178f0f
58b2fddb9f3b223dc0ebc0ff95e4a58e
a2cc037f8ebaad2f56bd2cafc07a57ae
04e637dfda193c37a91833eeebd664b4
60e9d6a04a86f0407ad7ca6e458d5573
9163933ecc29b567d26f5b70789fe2f5
d523f0ab7c667929a1023d5098d517f3
17f7b227a8eafaf9804fcf2713d753c7
ff35d5c36e035a123ac68a49bc67473d
fba57989354045fe4305a705d5effa3d
36d447f62b9ef46e2aec61562c2900eb
-----END OpenVPN Static key V1-----Verify server configuration values
$ sudo nano /etc/openvpn/server.confdata-ciphers AES-256-GCM:AES-128-GCM:?CHACHA20-POLY1305:AES-256-CBC
auth SHA512Verify client configuration TLS and cipher settings
$ nano /etc/openvpn/client/vpnclient1.ovpnEnsure these values match the server exactly:
# ...static key...key-direction 1data-ciphers AES-256-GCM:AES-128-GCM:?CHACHA20-POLY1305:AES-256-CBC
auth SHA512Transfer the updated .ovpn file to your device and try connecting again.
Conclusion
You have successfully installed OpenVPN on Ubuntu 24.04, configured the server, generated client keys, and established a functional VPN connection. OpenVPN lets you run multiple tunnel configurations over different ports and supports numerous clients. For continued learning, consult the official OpenVPN documentation.
Testen Sie Ihr Setup auf ccloud³
Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.