The recommended way of running OpenVPN is incredibly verbose. See here:
https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-18-04
That’s a lot of work, with a lot of places to make mistakes. That said, this is still the correct way to run OpenVPN.
An easier way is to do it via the easy-openvpn
snap.
1. Setting up Easy OpenVPN
Installing easy-openvpn
is … well, easy. The thing to understand though is Installing openvpn is only half the battle. Your machine still needs to be configured properly to forward packets.
Reference: https://docs.ubuntu.com/core/en/stacks/network/easy-openvpn/docs/
Installing
Very easy.
snap install easy-openvpn
We’ll have more configurations to do later.
2. IP forwarding
IP forwarding is typically disabled by default. You can check if its enabled a few ways:
# The sysctl way (0 = disabled, 1 = enabled)
sysctl net.ipv4.ip_forward
# The proc way (0 = disabled, 1 = enabled)
cat /proc/sys/net/ipv4/ip_forward
Whether you use a firewall or not will dictate how you do this next step. Below you can find instructions for no firewall (manual iptables), and for UFW.
Enable forwarding with no firewall (iptables)
Edit /etc/sysctl.conf
, and change/uncomment this line:
net.ipv4.ip_forward=1
You can can force the system to reload the config file like so:
sudo sysctl -p
Now when you check the forwarding state (see above) it should be enabled (i.e. 1).
You probably don’t want this, but if you want to temporarily enable IP forwarding (until next reboot or firewall change), you could do the following:
sudo sysctl -w net.ipv4.ip_forward=1
This is what the easy-openvpn docs suggest, but again, this is temporary. You’re going to want a permanent change.
Enable forward with the UFW firewall
UFW uses its own config files under the /etc/ufw/
folder.
Edit /etc/ufw/sysctl.conf
, and change/uncomment this line:
net/ipv4/ip_forward=1
If you restart the firewall, forwarding will now be enabled;
sudo ufw disable
sudo ufw enable
3. Configuring the Easy OpenVPN NAT device
Before Easy OpenVPN can do anything for us, we need to know what network interface we’re going to bind to it. Do the following:
ip addr
This will give you a list of network interfaces. Historically your network card would be named eth0
or wlan0
, but at some point network interfaces started getting wilder names like ens3
, enp0s25
, or wlp3s0
to name a few (the VPN itself will be named something like tun0
). Figure out which network interface you want to use from the output of ip addr
.
Once you know what you want, you can configure the snap variables. Set the interface like so:
sudo snap set easy-openvpn natdevice=eth0
Where eth0
is whatever your network interface is called.
You can confirm it’s set like so:
sudo snap get easy-openvpn
There’s also a file /var/snap/easy-openvpn/current/easy-openvpn.profile
that you can set nat device on. I don’t believe you need to set it here, but just in case I forget this is something else I’ve set.
4. Configuring the NAT masquerade
Now here is where the Easy OpenVPN docs fail: they neglect to mention you actually need to set up the NAT to masquerade the client IPs through it. Like before, the process of doing this is different depending on whether you use a firewall or not.
Configuring NAT masquerade with no filewall (iptables)
On Ubuntu by default a shell script /etc/rc.local
doesn’t exist. If it ever does, this script will be run on system startup. This is the typical place to put your iptables configuration.
#!/bin/bash
iptables -t nat -A POSTROUTING -s 192.168.255.0/24 -o eth0 -j MASQUERADE
Where eth0
is the network interface we want to route traffic through, and 192.168.255.0/24
is the IP block and subnet that VPN addresses will be pulled from.
Make the script executable (chmod +x /etc/rc.local
) and you can run it to get the effect right away.
Configuring NAT masquerade with UFW
This is a bit more involved (Reference: https://gist.github.com/kimus/9315140).
Edit /etc/default/ufw
and change the DEFAULT_FORWARD_POLICY.
DEFAULT_FORWARD_POLICY="ACCEPT"
Edit /etc/ufw/before.rules
, and before the filter rules, add this:
# OpenVPN NAT rules
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 192.168.255.0/24 -o eth0 -j MASQUERADE
COMMIT
Where eth0
is the network interface we want to route traffic through, and 192.168.255.0/24
is the IP block and subnet that VPN addresses will be pulled from.
So yes, there will be two COMMIT
's in the file. You’ll also notice this looks alot like the iptables configuration above.
Restart the firewall.
sudo ufw disable
sudo ufw enable
5. Final setup of Easy OpenVPN
Phew! We’re almost done!
Determine your public address (IP or domain)
The last thing we need is to know either our public facing IP address, or some domain that will correctly resolve to the IP of the VPN server. If you don’t have a domain, you can use a dynamic DNS service. If you have a static IP or just want to test things out, you can use any online IP checker, such as this:
A better option is to use a DNS resolver, but that’s a bit more complicated (may also return an ipv6, which we don’t necessarly want).
Run the EasyVPN setup script
Once you’ve decided, the final setup step is this:
sudo easy-openvpn.setup -u udp://12.45.56.78 -N -C AES-256-CBC
Where 12.34.56.78
is our public facing IP address, or a domain.
The reason you probably want a domain here, especially if you have a dynamic DNS, is because later one when we start generating keys for our users, the keys will make reference to this address. If the address in the configuration is always correct, then we don’t need to worry about editing our VPN configuration every time it changes.
Notably the line above is a bit different from what’s mentioned in the Easy OpenVPN docs. AES-256-CBC
is just better than the default, and the keys generated with it will trigger less errors in the logs.
Starting the service
Do this:
sudo service snap.easy-openvpn.easy-openvpn start
There might be a bettery way, but this at least correctly installs the systemctl service (TODO: see if you can just do sudo systemctl enable snap.easy-openvpn.easy-openvpn
).
From here on the systemctl service/unit is available. It can be enabled/disabled as follows:
# Disable
systemctl disable snap.easy-openvpn.easy-openvpn.service
# Enable
systemctl enable snap.easy-openvpn.easy-openvpn.service
(TODO: I’m not 100% sure if the service start line above properly enabled the service. To be safe I’ve always been doing a disable then enable as shown above, and then the service was good)
Your OpenVPN server is now ready.
6. Adding Users
Easy OpenVPN has a suite of commands you can now use, but there’s really one one we care about now that setup is finished.
sudo easy-openvpn.add-client myuser-device >myuser-device.ovpn
This will generate a key file for this specific user/device. myuser-device
are names you pick.
TIP: Often the filename (myuser-device.ovpn
) will be used by the OpenVPN client software as the name of the connection. It would be wise to include something in the name that identifies which VPN you are connecting to. Example: myvpn-user-phone.ovpn
.
7. Installing .ovpn keys
This is pretty straightforward, so I’m not going to say much. Download the OpenVPN client for your platform, and import the .ovpn
file. Done.
Android
Copy the .ovpn
file to the device somehow (USB cable works good). Browse to it in the openvpn app, select it, and install it. Easy.
Ubuntu 18.04
For me at least, Ubuntu 18.04 doesn’t want to import the key in the GUI. Fortunately this can be done easily from a terminal:
sudo nmcli connection import type openvpn file mykey.ovpn
Where mykey.ovpn
is the .ovpn
file.
Reference: https://www.cyberciti.biz/faq/linux-import-openvpn-ovpn-file-with-networkmanager-commandline/
Done
Yep, that’s it.
You can make a more advanced configuration by changing settings in these files:
/var/snap/easy-openvpn/current/openvpn/openvpn.conf
/var/snap/easy-openvpn/current/openvpn/ovpn_env.sh
End.