This post was last tested and updated for Ubuntu 24.04 LTS.

A VPN encrypts data traffic between two points. For general internet browsing, it is NOT necessarily end-to-end encrypted.

There are many reasons why a VPN may be necessary:

  • Connect from home to the office over the public internet (sensitive information),
  • Hide your traffic from the network administrator (ISP, hotel, Wi-Fi, etc),
  • Access region-restricted content (streaming, ACL, etc),
  • Download copyrighted or censored material,
  • And more.

What are the alternatives to VPN and what type of “protection” do they offer?

Expected Internet Service Provider Incognito Mode Public VPN Private VPN (truly end-to-end) Tor Network Only Tor Browser Observations
Tracking Protection NO NO NO NO Tunneling your traffic over an encrypted network does not make tracking any harder. All identifiable information still passes through the tunnel.
Fingerprinting Protection NO NO NO NO NO Only the Tor Browser removes or replaces identifiable information (fingerprints), making all users appear the same.
Geo-blocking Evasion NO NO Geo-blocking is usually based on IP address (e.g. streaming services). This is one of the most common uses of VPN for the general public.
Man-in-the-middle Protection NO NO NO NO NO Tunneling traffic over third-party networks is always susceptible to MITM attacks. Even Tor exit nodes should never be trusted.

NOTE: Websites with SSL/TLS (HTTPS) are end-to-end encrypted between the browser and the server (e.g. internet banking via browser or app). Your ISP or network administrator may know you are connecting to your bank or email provider, but they cannot see the content or tamper with it. On the other hand, if you are torrenting through a public VPN, the VPN provider can see your traffic in plain text, though the rest of the internet cannot see you behind the VPN server, and your traffic is mixed with that of many other users. Keep this in mind!


DEPLOYING A PRIVATE VPN SERVER

Download the installation script:

wget https://git.io/vpn -O openvpn-install.sh

If the command above does not work, get the script directly from GitHub – Nyr/OpenVPN Install [Link] or [OpenVPN-Install].

chmod -v +x openvpn-install.sh
sudo ./openvpn-install.sh

The script will ask a few questions. It is recommended to use:

First question: UDP;
Second question: default port 1194;
Third question: Google DNS;
The fourth question is the name you want to give to the specific client you are creating, for example: client1

The script creates a configuration file at /root/client1.ovpn (the filename matches the name you gave).

This file must be transferred to the client machine. It is recommended to use an encrypted transfer method such as:

scp [user]@[ip or hostname of the server]:/root/client1.ovpn .

The service starts automatically on the server and can be managed with:

sudo systemctl stop [email protected]
sudo systemctl start [email protected]
sudo systemctl restart [email protected]
sudo systemctl status [email protected]

From the client side (a Linux desktop, for example), run the following commands:

dig +short myip.opendns.com @resolver1.opendns.com
sudo apt install openvpn
sudo cp client1.ovpn /etc/openvpn/client.conf
sudo systemctl start openvpn@client
ping 10.8.0.1 -c 2
dig +short myip.opendns.com @resolver1.opendns.com

If you run these commands in order: the first checks your current public IP (your home ISP or the public Wi-Fi you are on); the fourth connects to the VPN; the fifth pings the VPN server twice through the tunnel; and the sixth checks your public IP again, this time returning the IP of your VPN server. Verify that it changed!

Note that on the client side, the VPN runs as a service and starts automatically on boot. To enable or disable this behaviour:

sudo nano /etc/default/openvpn

Find and uncomment the line AUTOSTART=”none” to prevent it from starting automatically.

For configuring OpenVPN Client in pfSense, see the next post [Link].


CUSTOMIZING CLIENT-SIDE: /etc/openvpn/client.conf

  • pull-filter ignore “redirect-gateway”
    • Prevents all traffic from being tunneled. Only traffic destined for the VPN network will go through the tunnel.
  • dhcp-option DNS 10.8.0.254
    • Forces a specific DNS server for this client over the VPN connection. DNS servers received during the connection will have lower priority.
  • dhcp-option Domain test.local
    • Forces a specific domain for this client over the VPN connection. Useful for Active Directory environments and can be combined with the DNS option.

CUSTOMIZING SERVER-SIDE: /etc/openvpn/server/server.conf

  • #server-ipv6 fddd:1194:1194:1194::/64
    • Comment this line to prevent IPv6 address assignment.
  • #ifconfig-pool-persist ipp.txt
    • Comment this line to allow dynamic IP assignment, or edit the file to assign static IPs per client.
  • push “dhcp-option DNS 8.8.4.4”
    • Add or comment out as many of these lines as needed, listed in the desired priority order.
  • duplicate-cn
    • Adding this line allows the same client certificate to be used for multiple simultaneous connections.

IMPORTANT: Stop the service before editing configuration files, and start it again afterward.


OPENVPN MONITOR

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

Add the following line at the end:

management 127.0.0.1 17562

Before restarting the service, verify that port 17562 is not already in use, then confirm the service starts correctly.

lsof -i :17562
sudo systemctl restart [email protected]
sudo systemctl status [email protected]

Install all dependencies:

sudo apt install git apache2 libapache2-mod-wsgi python3-geoip2 python3-ipaddr python3-humanize python3-bottle python3-semantic-version geoip-database geoipupdate
sudo git clone https://github.com/furlongm/openvpn-monitor.git /var/www/openvpn-monitor

Configure the monitor:

sudo cp /var/www/openvpn-monitor/openvpn-monitor.conf{.example,}
cd /var/www/openvpn-monitor
grep -irl 5555 . | xargs -I {} sed -i 's/5555/17562/' {} (double check)

Adjust the configuration to match your location:

sudo nano /var/www/openvpn-monitor/openvpn-monitor.conf

Example:

[openvpn-monitor]
site=DFTorres
logo=logo.jpg
latitude=43.6655
longitude=-79.4204
maps=True
maps_height=500
geoip_data=/var/lib/GeoIP/GeoLite2-City.mmdb
datetime_format=%d/%m/%Y %H:%M:%S

[VPN1]
host=localhost
port=17562
name=Staff VPN
show_disconnect=False

Download and place the GeoLite2-City.mmdb file from the GitHub repository [Link].

Configure Apache:

sudo nano /etc/apache2/sites-available/openvpn-monitor.conf

Paste the following into the new file:

ScriptAlias / /var/www/html/openvpn-monitor/openvpn-monitor.py
<Directory /var/www/html/openvpn-monitor>
Options +ExecCGI
AddHandler cgi-script .py
DirectoryIndex openvpn-monitor.py

AllowOverride None
Require ip 192.168.0.0/16
</Directory>

Replace 192.168.0.0/16 with your allowed network.

Set ownership to the www-data user:

sudo chown -R www-data: /var/www/openvpn-monitor/

Check the configuration syntax, enable the new site, and disable the default site:

sudo apachectl -t
sudo a2ensite openvpn-monitor.conf
sudo a2dissite 000-default.conf
sudo a2enmod cgi
sudo systemctl restart apache2

Try accessing your server in a browser at http://server-ip-or-name/

If the Python script is not executing and instead displays its source code, you may need to update the first line of the .py file (#!/usr/bin/env python) to match your server’s Python configuration:

sudo nano /var/www/openvpn-monitor/openvpn-monitor.py

Replace the first line with:

#!/usr/bin/python3

Or if that does not work:

#!/usr/bin/python

If this server hosts other websites, customize openvpn-monitor.conf using a VirtualHost block as shown below, and skip the step to disable the default site (sudo a2dissite 000-default.conf):

<VirtualHost *:80>
ServerAdmin [email protected]
ServerName openvpn-server-name-or-ip
DocumentRoot /var/www/html/openvpn-monitor
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

<Directory /var/www/html/openvpn-monitor>
Options +ExecCGI
AddHandler cgi-script .py
DirectoryIndex openvpn-monitor.py
AllowOverride None
Require ip 192.168.0.0/16
</Directory>

Instead of restricting access by IP (Require ip 192.168.0.0/16), you can expose the monitor on the internet using password authentication:

sudo apt-get install apache2-utils
sudo htpasswd -c /etc/apache2/.htpasswd user1
sudo htpasswd /etc/apache2/.htpasswd user2
...

NOTE: use the -D argument to delete a user.

Repeat the third line for each additional user you want to create.

sudo nano /etc/apache2/sites-available/openvpn-monitor.conf

Add the bold lines to the existing configuration:

<Directory /var/www/openvpn-monitor/>
Options +ExecCGI
AddHandler cgi-script .py
DirectoryIndex openvpn-monitor.py
AllowOverride None

AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Directory>

Restart Apache and test the page.

OpenVPN Monitor provides real-time information about connected users. IPFM complements it by acting as an IP Flow Meter, logging total data usage per user.


IP FLOW METER

sudo apt install ipfm
sudo systemctl stop ipfm
sudo cp /etc/ipfm.conf /etc/ipfm.conf.bkp
sudo nano /etc/ipfm.conf

Since the VPN network is 10.8.0.0/24, configure it as follows:

DEVICE tun0
NEWLOG
LOG 10.8.0.0/255.255.255.0
FILENAME "/var/log/ipfm/vpn-%Y-%m-%d"
DUMP EVERY 1 minute
CLEAR NEVER
SORT TOTAL

Restart the service and watch the folder for reports:

sudo systemctl start ipfm
watch -n 1 "ls -l /var/log/ipfm/"

Log files will appear in the directory and be updated every minute. A new file is created at the start of each month.


CHECK FOR CONNECTED CLIENTS

Add the following lines to /etc/openvpn/server/server.conf:

management 127.0.0.1 7505
log-append /var/log/openvpn.log
status /var/log/openvpn-status.log
verb 3

Restart the service and test the management interface with netcat or telnet:

nc 127.0.0.1 7505
echo "status 3" | timeout 1 nc 127.0.0.1 7505 | grep -E "^CLIENT_LIST"
sudo cat /var/log/openvpn-status.log
sudo tail -f /var/log/openvpn.log

If you only need a secure connection for up to 2 simultaneous devices, such as a smartphone and a laptop, consider using the OpenVPN Access Server [Link]. Licensing details are available at [Link].

OpenVPN-AS is a full-featured web-based GUI that simplifies the setup considerably. The only limitation is that more than 2 users requires a paid license.

Read Also

Performance OpenVPN vs WireGuard [Link]

Setting Up WireGuard VPN [Link]

pfSense with OpenVPN Client [Link]

GRE VPN Tunnel on Cisco [Link]