App Support.

We're here to help.



Setting up an OpenVPN server with Ubuntu and Viscosity

This guide will walk you through the steps involved in setting up an OpenVPN server on an Ubuntu host that allows you to securely access your home/office network from a remote location and optionally send all of your network traffic through it so you can access the internet securely as well.

Before using this guide, we highly recommend you read through our Introduction to Running an OpenVPN Server Article.

Preparation

For this guide, we assume:

  • You have already installed the latest LTS version of Ubuntu (22.04 at time of writing)
  • You have root access to this installation
  • This installation of Ubuntu is a clean install
  • Know the name of your network interfaces (instructions just below)
  • You have access to the server via Terminal or SSH
  • You are able to copy files on and off the server using SCP or a similar protocol
  • You already have a copy of Viscosity installed on your client device

If you need to download and install a copy of Ubuntu, information can be found at https://www.ubuntu.com/download. We won't be covering the details of setting up an Ubuntu instance, many guides can be found online. If you are running a different version of Ubuntu, it's very likely that many or even all of the steps outlined in this guide will still apply. If you are looking to setup an OpenVPN server on a different operating system, please check out our other guides.

If you don't have a copy of Viscosity already installed on your client, then please check out this setup guide for installing Viscosity (Mac | Windows).

If you're new to SSH or SCP, we have some instructions in our Introduction Guide.

To get the name of your Primary Network Interface (WAN Access), run the following on your Ubuntu server:
ip route | grep default | awk '{print $5}'. You should see an interface name similar to "ens224" or "enp1s0". If you are using a different version of Ubuntu, you may need to run just ip route | grep default instead and look for the interface name in the output.

If you have a second network interface for accessing machines on your local network, you will need the name of this as well when setting up the firewall and routing.

Support

Unfortunately we cannot provide any direct support for setting up your own OpenVPN server. We provide this guide as a courtesy to help you get started with, and make the most of, your copy of Viscosity. We've thoroughly tested the steps in this guide to ensure that, if you follow the instructions detailed below, you should be well on your way to enjoying the benefits of running your own OpenVPN server.

For further information or help with Ubuntu, there are a range of community resources available at https://www.ubuntu.com/community

Getting Started

First, update your server:

sudo apt update
sudo apt -y upgrade

You may be informed that you need to restart after the package upgrades are complete. If so, go ahead and restart, then log back in and continue on.

To set up an OpenVPN server, we need to install OpenVPN. To ensure that we're using the latest version of OpenVPN, we need to add the offical OpenVPN repository. Run the following commands, waiting for each to complete:

sudo mkdir -p /etc/apt/keyrings
sudo sh -c 'curl -fsSL https://swupdate.openvpn.net/repos/repo-public.gpg | gpg --dearmor > /etc/apt/keyrings/openvpn-repo-public.gpg'
sudo sh -c 'echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/openvpn-repo-public.gpg] https://build.openvpn.net/debian/openvpn/stable jammy main" > /etc/apt/sources.list.d/openvpn-aptrepo.list'

Note 1: The above command is for Ubuntu 22.04, which has the codename of "Jammy Jellyfish". If you are using a different version of Ubuntu you will need to replace "jammy" in the command above with the matching one-word codename for your Ubuntu version. For example, Ubuntu 22.10 is "kinetic", while Ubuntu "23.04 is "lunar". A list of Ubuntu versions and their codenames can be found here.
Note 2: The above command assumes you are using a 64-bit Intel/AMD processor. If you are instead using a 64-bit ARM processor, please replace "amd64" in the command above with "arm64".

Now we can install OpenVPN with the following commands:

sudo apt update
sudo apt -y install openvpn


Generating Configurations, Certificates and Keys

The next step is to generate your configurations for the server and your clients as well as certificates to go with them. You can do this easily by following the Creating Certificates and Keys Guide. You can either follow the section for Ubuntu and copy your client configurations off the server (we recommend this), or generate everything on your PC or Mac and copy the server folder that is generated onto your Ubuntu server.

If you use the default DNS Server (10.8.0.1), you will need to setup a DNS server yourself, instructions are at the end of this article. We recommend instead using an existing DNS server, a publically available DNS server like Google's (8.8.8.8 and 8.8.4.4) is the easiest.

Once you have generated your Configurations, you will need to transfer the server configuration to your server, or transfer your client configurations off your server. If you have local access, a USB drive is the easiest. If not, we have some help on how to transfer files with SCP in our Introduction Guide.

IP Forwarding

In order to forward our requests passing through the VPN, we want the OpenVPN server to act like a router. As such, we need to enable IP forwarding. In the terminal, we can enable IP forwarding on the Ubuntu server by entering:

echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

However, every time we reboot the server, this command will be undone. To ensure that doesn't happen, we need to modify the sysctl.conf file using nano. Enter:

sudo nano /etc/sysctl.conf

Scroll down to the section:

# Uncomment the next line to enable packet forwarding for IPv4
#net.ipv4.ip_forward=1

Delete the ‘#’ character at the start of the line so that it now becomes:

net.ipv4.ip_forward=1

When you are done, press ctrl + x to exit nano. Save the changes when prompted.

To ensure that hosts on the home/office network can find the VPN server, we need to make the server respond to any ARP requests:

echo 1 | sudo tee /proc/sys/net/ipv4/conf/ens224/proxy_arp

where ens224 is the network interface of the home/office network if you have two network interfaces, or your Primary Network Interface (WAN) otherwise (See Preparation section for more information).

Firewall Rules

We will use the Uncomplicated Firewall (ufw) that is installed by default on Ubuntu to control how traffic is passed through the OpenVPN server. If your Ubuntu server is externally accessible (has a direct connection to the internet with its own IP address, without a router), then you should use ufw to allow the OpenVPN port we have set up above (1194). Otherwise, we will set ufw to allow all traffic and configure the settings for routing.

If your Ubuntu server DOES NOT need ufw to protect it (i.e. it is behind a router or has a different firewall set up), you need to set the default input rule to allow all traffic to pass through ufw by default. To do so, we need to modify the configuration file.

  1. Open this file in nano:
    sudo nano /etc/default/ufw
  2. Scroll down to the section:
    # Set the default input policy to ACCEPT, DROP, or REJECT. Please note that if
    # you change this you will most likely want to adjust your rules.
    DEFAULT_INPUT_POLICY="DROP"
  3. Since our server will not be using this firewall for protection, change this from "DROP" to "ACCEPT"
  4. Scroll down to the section:
    # Set the default forward policy to ACCEPT, DROP or REJECT.  Please note that
    # if you change this you will most likely want to adjust your rules
    DEFAULT_FORWARD_POLICY="DROP"
  5. Change the forward policy from "DROP" to "ACCEPT"
  6. Press ctrl + x to exit nano. Save the changes when prompted.

If your Ubuntu server DOES need ufw to protect it, you need to tell it which ports to allow as it has the default input and forward policies of DROP. If you are running the OpenVPN server from some remote location, you will need to SSH into it to change any settings. As such, we need to tell the firewall to permit SSH traffic.

  1. Entering the following into the terminal:
    sudo ufw allow ssh
  2. The VPN traffic we will send to the OpenVPN server will be over UDP on port 1194, so enter into the terminal:
    sudo ufw allow 1194/udp

If you have other services running on your Ubuntu server, then you need to make sure that you allow their traffic through ufw as well. Make sure to add any allow rules for any other ports your Ubuntu server is listening on (such as a Plex media server or maybe your own email server).

Next, regardless of your network setup, you need to set up the routing rules for ufw.

  1. Open the ufw configuration file in nano:
    sudo nano /etc/ufw/before.rules
  2. Move the cursor below the section:
    #
    # rules.before
    #
    # Rules that should be run before the ufw command line added rules. Custom
    # rules should be added to one of these chains:
    # ufw-before-input
    # ufw-before-output
    # ufw-before-forward
  3. Paste in the following:
    # START OPENVPN RULES
    # NAT table rules
    *nat
    :POSTROUTING ACCEPT [0:0]

    # Uncomment the next POSTROUTING line and replace ens224 with the name
    # of your Local Network Interface if you have a second network interface
    # for accessing machines on your local network
    # Allow OpenVPN client to communicate with local home network
    #-A POSTROUTING -s 10.8.0.0/24 -d 192.168.0.0/24 -o ens32 -j MASQUERADE

    # Allow traffic from OpenVPN client to your WAN and/or LAN via ens224
    -A POSTROUTING -s 10.8.0.0/24 -o ens224 -j MASQUERADE
    COMMIT
    # END OPENVPN RULES
    • Replace ens224 with the name of your Primary Network Interface if it is different (See Preparation section for more information)
  4. Move the cursor below the section:
    # Don't delete these required lines, otherwise there will be errors
    *filter
    :ufw-before-input - [0:0]
    :ufw-before-output - [0:0]
    :ufw-before-forward - [0:0]
    :ufw-not-local - [0:0]
    # End required lines
  5. Paste in the following:
    #Accept all traffic to and from VPN
    -A ufw-before-input -i tun+ -j ACCEPT
    -A ufw-before-output -i tun+ -j ACCEPT

    # Forward traffic to and from the VPN
    -A ufw-before-forward -s 10.8.0.0/24 -j ACCEPT
    -A ufw-before-forward -d 10.8.0.0/24 -j ACCEPT
  6. Press ctrl + x to exit nano. Save the changes when prompted.

Ufw is now ready to be activated.

  1. In the terminal, type:
    sudo ufw enable
  2. If you are SSH’d into this Ubuntu instance, it will display the prompt:
    Command may disrupt existing ssh connections. Proceed with operation (y|n)?
    To which you should reply with y.

The following output will then be displayed (regardless of SSH or not)

Firewall is active and enabled on system startup

Starting the OpenVPN Server

At this point the basics are complete. Your server configuration and files should be on your server, either generated on the server, or copied on from where you generated them.

First, copy the server configuration files to the OpenVPN directory using the command below. Replace "/path/to/configs/server" with the correct path to where the files are on your server.

sudo cp /path/to/configs/server/* /etc/openvpn/

Now start your server, and enable it to start after a reboot as well.

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

To check the server status, enter:

sudo systemctl status openvpn@server

To which it should reply with:

Active: active (running) since Wed 2023-09-01 12:00:00 UTC; 4s ago

If the server is not listed as active (running), you should see a log output displaying what has gone wrong.

Your OpenVPN server is now up and running and ready for you to connect to it.

Router Setup

If your Ubuntu server is directly accessible, then you can skip this section. There is no router to configure.

However if your Ubuntu server is behind a router (such as on your home WiFi), then you will need to configure your router to permit VPN traffic. Please see our Introduction to Running an OpenVPN Server Article for more information.

Setting Up Viscosity

The final step is to setup Viscosity. Thanks to openvpn-generate, this is as easy as importing and connecting.

Importing

Copy your *.visz file you created with openvpn-generate to your Mac or Windows machine with Viscosity installed and double click the file. You should see a prompt that the config was imported successfully.

Connecting and Using Your VPN Connection

You are now ready to connect. Click on the Viscosity icon in the macOS menu bar or Windows system tray to open the Viscosity Menu, select the connection you imported, and Viscosity will connect.

To check that the VPN is up and running, you can open the Details window from the Viscosity Menu. This will allow you to view connection details, traffic and the OpenVPN log.



 

That's it, you've set up your very own OpenVPN server. Congratulations, you are now free to enjoy the benefits of operating your own OpenVPN server!

Basic DNS Server

If you are electing to run your own DNS server for clients, the following is an example setup for dnsmasq.

You first need to disable systemd-resolve. This default instance is restricted and won't allow us to listen for DNS requests over the VPN.

sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
sudo unlink /etc/resolv.conf

Now create the resolv.conf file with the DNS server the Ubuntu server should use for lookups. Here we are using 8.8.8.8 (Google's Public DNS server), however you can replace that with a different address if desired.

echo nameserver 8.8.8.8 | sudo tee /etc/resolv.conf

Now install dnsmasq with the following command:

sudo apt-get install -y dnsmasq

Next we need to modify some of the default configuration.

  1. Create a backup of the original dnsmasq configuration:
    cp /etc/dnsmasq.conf /etc/dnsmasq.conf.bak
  2. Set the DNS server to listen for requests from the Ubuntu server (127.0.0.1) and from the VPN (10.8.0.1):
    echo -e "listen-address=127.0.0.1, 10.8.0.1\nbind-interfaces" > /etc/dnsmasq.conf
  3. Prevent our DNS requests from flooding the root DNS servers with bad requests:
    echo -e "domain-needed\nbogus-priv" >> /etc/dnsmasq.conf
  4. Use the Google DNS servers to resolve requests (you are free to use your DNS resolution service of choice):
    echo -e "server=8.8.8.8\nserver=8.8.4.4" >> /etc/dnsmasq.conf
  5. Restart the dnsmasq service to activate our changes:
    service dnsmasq restart

To check that the DNS server is listening on the addresses we requested, type:

sudo apt install net-tools
netstat -anup

You should see a list of addresses, including 127.0.0.1 and 10.8.0.1:

Proto Recv-Q Send-Q Local Address         Foreign Address       State     PID/Program name
...
udp        0      0 127.0.0.1:53          0.0.0.0:*                       54892/dnsmasq   
udp        0      0 10.8.0.1:53           0.0.0.0:*                       54892/dnsmasq   
...

Lastly, we need to ensure that dnsmasq is started after OpenVPN on system startup. By default, dnsmasq runs before OpenVPN, which prevents it from setting up the DNS server for the VPN as the VPN doesn't exist yet.

  1. Edit the OpenVPN service:
    sudo systemctl edit openvpn.service
  2. Between the ### Anything between here and the comment below will become the new contents of the file and ### Lines below this comment will be discarded lines add the commands [Service] and ExecStartPost=/bin/systemctl restart dnsmasq so that it looks like:
    ### Anything between here and the comment below will become the new contents of the file

    [Service]
    ExecStartPost=/bin/systemctl restart dnsmasq

    ### Lines below this comment will be discarded
  3. Reload the service:
    sudo systemctl daemon-reload
    sudo systemctl restart openvpn.service

We are now done setting up the DNS server.