Installing OpenVPN on Ubuntu 24.04
Installing OpenVPN on Ubuntu 24.04
OpenVPN is an open-source, full-featured VPN solution that enables secure site-to-site and point-to-point connections. OpenVPN creates encrypted tunnels using TLS (Transport Layer Security) to secure data transmission over untrusted networks such as the Internet between clients and servers. It supports multiple encryption algorithms, including AES-256, to encrypt traffic and protect network communication from man-in-the-middle and eavesdropping attacks. This guide walks through installing OpenVPN on Ubuntu 24.04 and configuring it to create secure end-to-end encrypted connections between the VPN server and client devices. By the end, you'll have a working OpenVPN server with a signed client certificate ready to import into any OpenVPN client. Before you begin, you need access to an Ubuntu 24.04 server as a non-root user with sudo privileges.
1. Install OpenVPN
OpenVPN is available in the default package repositories on Ubuntu 24.04.
Update the APT package index:
$ sudo apt updateInstall OpenVPN:
$ sudo apt install openvpn -yVerify the installed OpenVPN version:
$ openvpn --versionYour output should be similar to the one below.
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 .................................................................
2. Create the OpenVPN Server Private Key, Certificate, and TLS Encryption Files
OpenVPN requires a server certificate, private key, and encryption files signed by a trusted certificate authority (CA) to enable VPN tunnel connections. Easy-RSA is a certificate authority management tool for applications like OpenVPN that issue digital certificates, including server certificates and private key pairs.
Install Easy-RSA:
$ sudo apt install easy-rsa -yNavigate to your user's home directory:
$ cdCreate a new easy-rsa directory:
$ mkdir easy-rsaLink the
/usr/share/easy-rsadirectory to easy-rsa to access the Easy-RSA script and package files:$ ln -s /usr/share/easy-rsa/ * easy-rsa/List the easy-rsa directory and verify the linked files:
$ ls easy-rsaOutput:
easyrsa openssl-easyrsa.cnf vars.example x509-typesChange to the easy-rsa directory:
$ cd easy-rsaCreate a new vars configuration using a text editor such as
nano:$ nano varsAdd the following certificate authority configuration to the file:
set_var EASYRSA_REQ_COUNTRY "US" set_var EASYRSA_REQ_PROVINCE "Georgia" set_var EASYRSA_REQ_CITY "Atlanta" set_var EASYRSA_REQ_ORG "Example Org" set_var EASYRSA_REQ_EMAIL "li*******@example.com" set_var EASYRSA_REQ_OU "Community" set_var EASYRSA_ALGO "ec" set_var EASYRSA_DIGEST "sha512"This configuration specifies the organizational information for building your CA, including the country, city, administrative email, and unit details.
Initialize the PKI using the easy-rsa script:
$ ./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/varsBuild the CA to generate the root public certificate and private key pair:
$ ./easyrsa build-caEnter a strong passphrase for signing certificate requests and repeat it when prompted to secure the CA, then enter a common name for the CA, such as
OpenVPN-CA. Verify the generatedca.crtCA certificate path in the output:Notice ------ CA creation complete. Your new CA certificate is at: * /home/linuxuser/easy-rsa/pki/ca.crtGenerate a new server certificate request. Replace
vpnserverwith your desired server common name.$ ./easyrsa gen-req vpnserver nopassPress Enter when prompted to verify the common name, then verify the generated public certificate request and private key paths when successful:
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.keySign the server certificate request using the CA:
$ ./easyrsa sign-req server vpnserverEnter
yesand press Enter when prompted to verify the certificate request, then enter your CA passphrase when prompted to sign it. Your output should look like the one below when successful.Notice ------ Certificate created at: * /home/linuxuser/easy-rsa/pki/issued/vpnserver.crtList the
pki/issueddirectory to verify the generated server certificate:$ ls pki/issuedOutput:
vpnserver.crtGenerate a
ta.keyHMAC signature file to enable TLS verification and authentication on the OpenVPN server:$ sudo openvpn --genkey secret ta.keyList your working directory files to verify the generated
ta.keyfile:$ lsOutput:
df.pem easyrsa openssl-easyrsa.cnf pki ta.key vars vars.example x509-typesCreate a strong Diffie-Hellman parameters file to secure key exchange for encrypted OpenVPN sessions:
$ ./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.pemList the
pkidirectory to verify the generateddh.pemfile:$ ls pki/Output:
ca.crt dh.pem .....................Copy the
ca.crt,vpnserver.key,vpnserver.crt,ta.key, anddh.pemfiles to the/etc/openvpndirectory:$ sudo cp ta.key pki/ca.crt pki/private/vpnserver.key pki/issued/vpnserver.crt pki/dh.pem /etc/openvpn/
3. Configure OpenVPN
OpenVPN uses server and client configurations in the /etc/openvpn directory to create tunnel interfaces and the respective systemd services. /etc/openvpn contains the server configurations you can manage with the openvpn@ service, while /etc/openvpn/server contains additional configurations manageable with the openvpn-server@ service.
Copy the sample OpenVPN server configuration template to the
/etc/openvpndirectory:$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/Navigate to the
/etc/openvpndirectory:$ cd /etc/openvpnOpen the copied
server.conffile:$ sudo nano server.confMake the following edits:
Optional: Remove
;to uncomment thelocaldirective and replacea.b.c.dwith the server IP address OpenVPN should use to listen for incoming connections. Replace192.0.2.100with your server's actual public IP address.local 192.0.2.100Find the
devdirective and verify the default OpenVPN tunnel type (tuncreates routed IP tunnels, whiletapcreates Ethernet tunnels).dev tunFind the
ca,cert, andkeyoptions, then replace the defaultca.crt,server.crt, andserver.keyvalues with the actual paths to your certificate authority, server certificate, and server private key files.ca /etc/openvpn/ca.crt cert /etc/openvpn/vpnserver.crt key /etc/openvpn/vpnserver.keyFind the
dhdirective and replacedh2048.pemwith your actual Diffie-Hellman file path.dh /etc/openvpn/dh.pemFind the
data-ciphersdirective, remove;to uncomment it to enable OpenVPN to use strong, modern ciphers for encryption, then adddata-ciphers-fallback AES-256-CBCas a fallback.data-ciphers AES-256-GCM:AES-128-GCM:?CHACHA20-POLY1305:AES-256-CBC data-ciphers-fallback AES-256-CBCAdd the following
authdirective belowdata-ciphersto specify the HMAC digest algorithm, such asSHA512, for authenticating each packet.auth SHA512Find the
serverdirective and specify the VPN subnet to assign client addresses. For example, change the default10.8.0.0subnet to10.10.10.0.server 10.10.10.0 255.255.255.0Find the
;push "redirect-gateway def1 bypass-dhcp"directive and remove;to uncomment it, redirecting all traffic through the VPN.push "redirect-gateway def1 bypass-dhcp"Find the
dhcp-optiondirectives and replace the default addresses with your preferred DNS servers, such as8.8.8.8and1.1.1.1, then remove;to uncomment the options.push "dhcp-option DNS 8.8.8.8" push "dhcp-option DNS 1.1.1.1"Find the
tls-authdirective, uncomment it, replaceta.keywith your actual key path, and keep0as the direction.tls-auth /etc/openvpn/ta.key 0 # This file is secretFind the
userandgrouppair, replaceopenvpnwithnobodyandnogrouprespectively to run OpenVPN with reduced privileges, then remove;to uncomment the options.user nobody group nogroupSave and close the file. Your modified
server.conffile should look like the one below.
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 and verify it runs without errors:
$ sudo openvpn --config /etc/openvpn/server.confYour output should be similar to the one below when the configuration test is successful. Press
Ctrl+Cto stop the configuration test.... 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
Enable IP Forwarding
Open the
/etc/sysctl.conffile to enable IP forwarding on the server:$ sudo nano /etc/sysctl.confFind the
# net.ipv4.ip_forward=1directive and remove#to uncomment it:net.ipv4.ip_forward = 1This configuration enables IP forwarding, allowing OpenVPN clients to route traffic through the VPN.
Apply the
/etc/sysctl.confconfiguration changes:$ sudo sysctl -pOutput:
net . ipv4 . ip_forward = 1Run the following command to verify the public network interface on your server:
$ ip route | grep defaultNote the public interface name like
enp1s0in your output, similar to the one below.default via 192.0.2.1 dev enp1s0 proto dhcp src 192.0.2.100 metric 100Check the UFW status and verify that it's installed:
$ sudo ufw statusIf it's not installed, run the following command to install UFW and allow SSH traffic:
$ sudo apt install ufw -y && sudo ufw allow sshOpen the
/etc/ufw/before.rulesfile to enable NAT through the firewall:$ sudo nano /etc/ufw/before.rulesAdd the following POSTROUTING policy configuration before the
*filtersection. Replaceenp1s0with your actual public interface name.*nat :POSTROUTING ACCEPT [0:0] -A POSTROUTING -s 10.10.10.0/24 -o enp1s0 -j MASQUERADE COMMITThis firewall configuration modifies the default POSTROUTING policy in the nat table to masquerade all traffic from the
10.10.10.0/24VPN subnet through the server'senp1s0public network interface.Open the
/etc/ufw/sysctl.conffile to enable IP forwarding through UFW:$ sudo nano /etc/ufw/sysctl.confFind the
#net/ipv4/ip_forward=1directive and remove#to uncomment it:net/ipv4/ ip_forward = 1This configuration enables IP forwarding through the firewall to route packets between the OpenVPN tun interface and other interfaces on the server.
Open the
/etc/default/ufwfile to allow forwarded packets through UFW:$ sudo nano /etc/default/ufwFind the
DEFAULT_FORWARD_POLICYdirective and change the default value fromDROPtoACCEPT:DEFAULT_FORWARD_POLICY = "ACCEPT"Reload UFW to apply the firewall configuration changes:
$ sudo ufw reload
4. Secure the OpenVPN Server
Allow incoming connections to the
tun0OpenVPN interface:$ sudo ufw allow in on tun0Allow outgoing connections from the
tun0interface:$ sudo ufw allow out on tun0Allow network connections to the
1194OpenVPN server port:$ sudo ufw allow 1194/udpReload UFW to apply the firewall configuration changes:
$ sudo ufw reloadCheck the UFW status to verify the active firewall rules:
$ sudo ufw statusOutput:
Status: active To ActionFrom -- ---------- 22/tcp ALLOW Anywhere Anywhere on tun0 ALLOW Anywhere 1194/udp ALLOW Anywhere 22/tcp (v6)ALLOW Anywhere (v6) Anywhere (v6) on tun0ALLOW Anywhere (v6) 1194/udp (v6)ALLOW Anywhere (v6) Anywhere ALLOW OUT Anywhere on tun0 Anywhere (v6)ALLOW OUT Anywhere (v6) on tun0
5. Manage the OpenVPN Server
OpenVPN uses systemd to manage the VPN interfaces based on the server configurations in the /etc/openvpn directory.
Enable the OpenVPN service to start automatically at boot:
$ sudo systemctl enable o******@server.serviceOutput:
Created symlink /etc/systemd/system/multi-user.target.wants/o******@server.service โ /usr/lib/systemd/system/openvpn@.service.Start the OpenVPN service:
$ sudo systemctl start o******@server.serviceView the OpenVPN service status and verify that it runs without errors:
$ sudo systemctl status o******@server.serviceOutput:
โ o******@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 that the
tun0OpenVPN interface is active and correctly configured on the server:$ 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
OpenVPN requires a valid client certificate and private key pair to connect to the VPN server.
- Create a new
keysdirectory in/etc/openvpn/clientto store the client encryption keys:$ sudo mkdir -p /etc/openvpn/client/keys - Navigate to the easy-rsa directory:
$ cd ~/easy-rsa - Generate a new certificate request usin
Comments
No comments yet. Start the discussion.