Post

Step-by-Step Guide: Setting Up and Troubleshooting OpenVPN on Ubuntu 24.04

Step-by-Step Guide: Setting Up and Troubleshooting OpenVPN on Ubuntu 24.04

Welcome Reader, No hacking today :) We will set up an OpenVPN server on Ubuntu 20.04.

Install OpenVPN and EasyRSA

We will use apt to install the following packages.

1
$ sudo apt install openvpn easy-rsa -y

Verify the installation.

1
2
3
$ openvpn --version
# Expected output
OpenVPN 2.6.x ...

Set Up EasyRSA for Certificate Authority (CA)

Create the directory and initialize EasyRSA.

1
2
3
4
mkdir -p ~/easy-rsa
ln -s /usr/share/easy-rsa/* ~/easy-rsa/
cd ~/easy-rsa
cp vars.example vars

Editing the vars file.

1
2
3
4
5
6
7
8
root@vpn-server:~/easy-rsa# nano vars
# Add the lines at the of the file
set_var EASYRSA_REQ_COUNTRY    "US"
set_var EASYRSA_REQ_PROVINCE   "California"
set_var EASYRSA_REQ_CITY       "San Francisco"
set_var EASYRSA_REQ_ORG        "MyVPN"
set_var EASYRSA_REQ_EMAIL      "admin@example.com"
set_var EASYRSA_REQ_OU         "IT"

Save and exit. Now, we will initialize and build the CA.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
root@vpn-server:~/easy-rsa# ./easyrsa init-pki
Notice
------
'init-pki' complete; you may now create a CA or requests.
Your newly created PKI dir is:
* /root/easy-rsa/pki
Using Easy-RSA configuration:
* /root/easy-rsa/vars
root@vpn-server:~/easy-rsa# ./easyrsa build-ca nopass
Using Easy-RSA 'vars' configuration:
< ... SNIP ... >
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:vpn-server
Notice
------
CA creation complete. Your new CA certificate is at:
* /root/easy-rsa/pki/ca.crt

Generate Server Certificate and Keys

Run the following.

1
2
3
./easyrsa gen-req server nopass
./easyrsa sign-req server server
cp pki/ca.crt pki/issued/server.crt pki/private/server.key /etc/openvpn/

Generate the Diffie-Hellman key exchange.

1
2
./easyrsa gen-dh
mv pki/dh.pem /etc/openvpn/

Generate a tls-crypt key.

1
openvpn --genkey secret /etc/openvpn/ta.key

Configure OpenVPN Server

Create the OpenVPN server config file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ sudo nano /etc/openvpn/server.conf
# Paste this
port 1194
proto udp
dev tun
ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh /etc/openvpn/dh.pem
tls-crypt /etc/openvpn/ta.key
topology subnet
server 172.16.20.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
keepalive 10 120
data-ciphers AES-256-GCM:AES-128-GCM:AES-256-CBC
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
explicit-exit-notify 1
auth SHA512
compress lz4
allow-compression asym
client-to-client

Enable and Start OpenVPN

Enable OpenVPN at boot.

1
sudo systemctl enable openvpn

Start OpenVPN.

1
sudo systemctl start openvpn

Verify that it’s running.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ sudo systemctl status openvpn
● openvpn@server.service - OpenVPN connection to server
     Loaded: loaded (/usr/lib/systemd/system/openvpn@.service; enabled; preset: enabled)
     Active: active (running) since Sun 2025-03-16 07:44:30 UTC; 49ms ago
       Docs: man:openvpn(8)
             https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
             https://community.openvpn.net/openvpn/wiki/HOWTO
   Main PID: 24898 (openvpn)
     Status: "Initialization Sequence Completed"
      Tasks: 1 (limit: 10)
     Memory: 1.4M (peak: 1.6M)
        CPU: 32ms
     CGroup: /system.slice/system-openvpn.slice/openvpn@server.service
             └─24898 /usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --cd /etc/openvpn --script-security 2 --config /etc/open>
Mar 16 07:44:30 vpn-server systemd[1]: Starting openvpn@server.service - OpenVPN connection to server...
Mar 16 07:44:30 vpn-server systemd[1]: Started openvpn@server.service - OpenVPN connection to server..

If you face an error, try stopping and starting the service again.

Setip Firewall for OpenVPN

Enable the firewall and add the following rule.

1
2
3
sudo ufw enable
sudo ufw allow 1194/udp
sudo ufw reload

Check that OpenVPN is listening on port 1194.

1
2
$ sudo netstat -tulnp | grep 1194
udp        0      0 0.0.0.0:1194          0.0.0.0:*               1234/openvpn

Create a Client Profile

Generate the client certificate.

1
2
./easyrsa gen-req client1 nopass
./easyrsa sign-req client client1

Copy client certificates.

1
2
3
mkdir -p /etc/openvpn/client
cp pki/ca.crt pki/issued/client1.crt pki/private/client1.key /etc/openvpn/client/
cp /etc/openvpn/ta.key /etc/openvpn/client/

Create the client configuration file. The files will be located under /etc/openvpn/client. Don’t forget to change the host-ip.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ sudo nano /etc/openvpn/client/client1.ovpn
# Paste the following
client
dev tun
proto udp
remote host-ip 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
data-ciphers AES-256-GCM:AES-128-GCM:AES-256-CBC
auth SHA512
compress lz4
allow-compression asym
verb 3
explicit-exit-notify 2
<ca>
-----BEGIN CERTIFICATE-----
(Paste contents of /etc/openvpn/client/ca.crt here)
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
(Paste contents of /etc/openvpn/client/client1.crt here)
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
(Paste contents of /etc/openvpn/client/client1.key here)
-----END PRIVATE KEY-----
</key>
<tls-crypt>
-----BEGIN OpenVPN Static key V1-----
(Paste contents of /etc/openvpn/client/ta.key here)
-----END OpenVPN Static key V1-----
</tls-crypt>

After creating the file, move the file to the client’s machine. I will use my Windows machine to connect with the VPN server.

Connected Successfuly

Verifying the connection.

1
2
3
4
5
6
7
8
9
PS C:\Users\beric\Downloads\Documents> ping 172.16.20.1 -n 3
Pinging 172.16.20.1 with 32 bytes of data:
Reply from 172.16.20.1: bytes=32 time=8ms TTL=64
Reply from 172.16.20.1: bytes=32 time=3ms TTL=64
Reply from 172.16.20.1: bytes=32 time=3ms TTL=64
Ping statistics for 172.16.20.1:
    Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 3ms, Maximum = 8ms, Average = 4ms

Enable Internet Access for VPN Clients

Enable IP forwarding with the following command.

1
2
3
4
5
6
7
sudo sysctl -w net.ipv4.ip_forward=1
# Permanent Changes
sudo nano /etc/sysctl.conf
# Add or uncomment the following line
net.ipv4.ip_forward=1
# Apply the chnages
sudo sysctl -p

Setup NAT for Inernet Routing. We can find our NAT interface with the following command.

1
2
3
4
ip route show | grep default
# Expected output
default via 192.168.18.1 dev enp0s3 proto dhcp metric 100
                                |--> Interface

Set up NAT (IP Masquerading) to forward VPN traffic.

1
sudo iptables -t nat -A POSTROUTING -s 172.16.20.0/24 -o enp0s3 -j MASQUERADE

Allow VPN traffic forwarding.

1
2
sudo iptables -A FORWARD -i tun0 -o enp0s3 -j ACCEPT
sudo iptables -A FORWARD -i enp0s3 -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT

Save the IP tables.

1
2
sudo apt update && sudo apt install -y iptables-persistent
sudo netfilter-persistent save

Push Default routes to VPN clients.

1
2
3
4
5
sudo nano /etc/openvpn/server.conf
# Add the following
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 1.1.1.1"

Save the file and restart the VPN server.

1
sudo systemctl restart openvpn@server

If you face any errors, please don’t hesitate to ask in the comments. Thanks for reading.

This post is licensed under CC BY 4.0 by the author.