These are the steps I’ve used to set up a VPN connection to RunCloud managed VPS server, with OpenVPN running on Ubuntu 16.04.
I’ve added brief explanations of each step for a quick copy/paste job.
Setting up VPN on the Server Side
First install the basic OpenVPN package and “easy-rsa”, a simple shell based CA (Certificate Authority) utility, with related dependencies.
sudo apt-get update
sudo apt-get install openvpn easy-rsa
Set up directory, and configure variables for the CA;
make-cadir ~/openvpn-ca
cd ~/openvpn-ca
nano vars
Edit these variables as desired;
# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY="HK"
export KEY_PROVINCE="HK"
export KEY_CITY="Hong Kong"
export KEY_ORG="HostVirtual"
export KEY_EMAIL="postmaster@domain.com"
export KEY_OU="Community"
# X509 Subject Field
export KEY_NAME="Server"
Continue with building the CA and hit enter for all questions;
source vars
./clean-all
./build-ca
The following command creates the server certificate, hit enter for all questions, including the ‘challenge password’ & ‘optional company name’. Except, answer ‘y’ twice in the end, when it asks to sign and commit requests for the certificate.
You can change the server key name to whatever;
./build-key-server server
Generate a strong Diffie-Hellman keys (recommended);
./build-dh
Generate an HMAC signature (recommended);
openvpn --genkey --secret keys/ta.key
This is how you can create the Client Certificate and Key Pair files directly on the server which you can then copy over to the VPN client host.
Change the key name as desired, and again hit enter for all the questions except the last two ‘y’ answers;
./build-key client
Next copy the files to the OpenVPN directory (including an OpenVPN configuration file), and correct the server file name if needed;
cd ~/openvpn-ca/keys
sudo cp ca.crt server.crt server.key ta.key dh2048.pem /etc/openvpn
gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf
Then start editing the server.conf file;
sudo nano /etc/openvpn/server.conf
These are recommended settings to route all traffic;
local 111.111.111.111 #change ip here if needed
tls-auth ta.key 0
key-direction 0 #add this line
cipher AES-128-CBC # AES
auth SHA256
user nobody
group nogroup
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
port 8420 #select random port
cert server.crt #change if needed
key server.key #change if needed
Either uncomment or add this as a new line to allow traffic forwarding, and the last command will adjust the values for your session;
sudo nano /etc/sysctl.conf
net.ipv4.ip_forward=1
sudo sysctl -p
RunCloud uses Firewalld as it’s Firewall, here’s how configure it;
sudo firewall-cmd --zone=runcloud --add-service openvpn
sudo firewall-cmd --zone=runcloud --add-service openvpn --permanent
sudo firewall-cmd --add-masquerade
sudo firewall-cmd --permanent --add-masquerade
SHARK=$(ip route get 8.8.8.8 | awk 'NR==1 {print $(NF-2)}')
sudo firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s 10.8.0.0/24 -o $SHARK -j MASQUERADE
sudo firewall-cmd --reload
Optional;
sudo firewall-cmd --zone=public --change-interface=eth0
Start the OpenVPN service, and check it’s running;
sudo systemctl start openvpn@server
sudo systemctl status openvpn@server
ip addr show tun0
Enable OpenVPN to start at boot;
sudo systemctl enable openvpn@server
Create a directory structure and client config files;
mkdir -p ~/openvpn-ca/client/files/
chmod 700 ~/openvpn-ca/client/files/
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/openvpn-ca/client/base.conf
nano ~/openvpn-ca/client/base.conf
Edit, comment out or add lines;
remote my-server-1 8420
proto udp
user nobody
group nogroup
#ca ca.crt
#cert client.crt
#key client.key
;cipher x
cipher AES-128-CBC
auth SHA256
key-direction 1
Add these commented out lines to base.conf, if your Linux distribution comes with the ‘/etc/openvpn/update-resolv-conf’ file (like on RunCloud Ubuntu 16.04);
# script-security 2
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
Create script for generating the files;
nano ~/openvpn-ca/client/make_config.sh
#!/bin/bash
# First argument: Client identifier
KEY_DIR=~/openvpn-ca/keys
OUTPUT_DIR=~/openvpn-ca/client/files
BASE_CONFIG=~/openvpn-ca/client/base.conf
cat ${BASE_CONFIG} \
<(echo -e '<ca>') \
${KEY_DIR}/ca.crt \
<(echo -e '</ca>\n<cert>') \
${KEY_DIR}/${1}.crt \
<(echo -e '</cert>\n<key>') \
${KEY_DIR}/${1}.key \
<(echo -e '</key>\n<tls-auth>') \
${KEY_DIR}/ta.key \
<(echo -e '</tls-auth>') \
> ${OUTPUT_DIR}/${1}.ovpn
Make the file executable, and generate client configurations;
chmod 700 ~/openvpn-ca/client/make_config.sh
cd ~/openvpn-ca/client/
./make_config.sh client
If everything went file you have the client.ovpn file ready;
ls ~/openvpn-ca/client/files/client.ovpn
In RunCloud management (manage.runcloud.io), you can open the port in your firewall easily. Navigate to –> Servers, “server name”, Security and select “Add rule”.
Define a globally open port, for the UDP protocol (or TCP is you are using that), or use a rich rule to restrict port connections to an IP or IP range.
Setting up VPN on the Client Side
In this example, I’m using Tunnelblick on macOS as my VPN connection client to connect to the newly set up Ubuntu VPN server.
Download a copy of the “client.ovpn” file to your client machine and open it with Tunnelblick. Answer yes, to use the openvpn-down-root.so’ plugin for OpenVPN.
If you want to use OpenVPN 2.5 or later, you need to remove ‘comp-lzo’ from both server.conf & base.conf (deprecated in OpenVPN 2.4).
Troubleshooting VPN
If a connection gets stuck at the “waiting for server response” stage. Usually flushing the routing table has fixed the problem (on macOS);
sudo ifconfig en0 down
sudo ifconfig en1 down
sudo route flush
sudo ifconfig en0 up
sudo ifconfig en1 up
Useful FirewallD commands when in trouble;
firewall-cmd --get-default-zone
firewall-cmd --get-active-zones
sudo firewall-cmd --list-all
Find out more about RunCloud VPS manager here.
Comments are welcome in the box below.
Thanks for your visit! David.