Wireguard VPN¶
You can further enhance the security of communications between clients and the OSGS server by configuring a Wireguard VPN. The goal here will be to tunnel all non-web based requests to the server through the VPN. This can include Postgres and Mosquitto connections, and others if they are published on a port. You can also move the actual management over SSH of the OSGS server itself into the VPN so that the only public facing ports of the server are https and the vpn service.
In this document we describe a scenario where the OSGS server is also a VPN server, but there are other potential scenarios such as using a second server and the VPN server and the OSGS as a VPN client.
Setting up the VPN Server¶
Note: There is NO public facing ssh port open on this host, you can only access ssh via the VPN. So for management when the VPN is down or you don’t have your client set up yet, use your hosting provider’s virtual console.
Note 2: Use these instructions at your own risk. Misconfiguring your server could lock you out of it permanently, so proceed with caution!
Note 3: We assume you have already carried out the server_preparation steps before following this guide.
Log in to your server¶
ssh yourhost
or use the hosting provider’s console to log in if you do not already have SSH access.
Note: When logging in take note that the keyboard layout in the console is US if you are using hetzner for your provider, so if you have a different layout e.g. Portuguese you need to type as if you are on a US keyboard.
Initial Install¶
Assuming an ubuntu based server here…
sudo su -
apt update
apt upgrade
apt install wireguard
cd /etc/wireguard/
umask 077; wg genkey | tee privatekey | wg pubkey > publickey
ls -l privatekey publickey
Should show:
-rw------- 1 root root 45 Oct 31 23:33 privatekey
-rw------- 1 root root 45 Oct 31 23:33 publickey
Make a note of the private key and public key:
cat privatekey
cat publickey
Now configure the conf file:
vim /etc/wireguard/wg-osgs.conf
Note: You can run multiple Wireguard VPN clients and servers on the same host so we include osgs in the conf file name to make it clear what this VPN is to be used for.
Add this content:
## Set Up WireGuard VPN on Ubuntu By Editing/Creating wg0.conf File ##
[Interface]
## My VPN server private IP address ##
Address = 192.168.7.1/24
## My VPN server port ##
ListenPort = 41194
## VPN server's private key i.e. /etc/wireguard/privatekey ##
PrivateKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Also enable NAT routing of all traffic through the VPN
# This is needed for VPN clients to be able to conenct to each other's services and ports
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
##
## All osgs peers (clients) should be added here
##
[Peer]
## Client VPN public key ##
PublicKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
## client VPN IP address (note the /32 subnet) ##
AllowedIPs = 192.168.7.2/32
Server Networking and Firewall Configuration¶
Note: Only do this for cases when you want to support peer to peer access in the VPN. In normal circumstances it is better to have an architecture where peers can talk to the server only and not to each other.
This section copied from https://linuxize.com/post/how-to-set-up-wireguard-vpn-on-ubuntu-20-04/#server-networking-and-firewall-configuration
IP forwarding must be enabled for NAT to work. Open the /etc/sysctl.conf file and add or uncomment the following line:
sudo vim /etc/sysctl.conf
Add this line:
net.ipv4.ip_forward=1
Save the file and apply the change:
sudo sysctl -p
Should show:
net.ipv4.ip_forward = 1
Firewall config¶
ufw allow 41194/udp
ufw status
Should show:
Status: inactive
Allow ssh connections originating from within the VPN
ufw allow from 192.168.7.0/24 to any port 22 proto tcp
For the same for each port that you want to be accessible only via the VPN e.g.
ufw allow from 192.168.7.0/24 to any port 5432 proto tcp
ufw allow from 192.168.7.0/24 to any port 8883 proto tcp
Would allow Postgres connections (5432) and Mosquitto (8883) over the VPN only.
On my test system the set of final UFW rules looks like this:
root@osgs:/etc/wireguard# ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 80 ALLOW IN Anywhere
[ 2] 443 ALLOW IN Anywhere
[ 3] 41194/udp ALLOW IN Anywhere
[ 4] 22/tcp ALLOW IN 192.168.7.0/24
[ 5] 5432/tcp ALLOW IN 192.168.7.0/24
[ 6] 8883/tcp ALLOW IN 192.168.7.0/24
i.e. only web and vpn traffic are publicly accessible and other services and ports need to be accessed from within the VPN.
Enable wireguard service in systemd¶
systemctl enable wg-quick@wg-osgs
systemctl start wg-quick@wg-osgs
systemctl status wg-quick@wg-osgs
A convenient way to do status checks is with the wg command. It will show all connected hosts.
wg
Allow incoming SSH only from the VPN¶
First make sure ssh is running and configured to run on system start:
systemctl enable ssh
systemctl start ssh
systemctl status ssh
As indicated above, do:
ufw allow from 192.168.6.0/24 to any port 22 proto tcp
Also update your sshd to listen only on the wg interface
# Changed by Tim to listen on wireguard interface only
# Change XXX to your IP
ListenAddress 192.168.7.XXX
# Disabled by Tim
PermitRootLogin no
PasswordAuthentication no
Connecting with your client¶
For each client you need to create public/private keys on the client and a [peer] entry on the server, then restart client and server wireguard instances.
Install Ubuntu¶
apt install wireguard
sudo apt install openresolv
sudo apt install resolvconf
or (for fedora):
dnf install wireguard wireguard-tools
Configure client keys¶
cd /etc/wireguard/
umask 077; wg genkey | tee privatekey | wg pubkey > publickey
ls -l privatekey publickey
cat publickey
cat privatekey
Add client to the server¶
Log in to the server:
ssh vpn
sudo vim /etc/wireguard/wg-osgs.conf
Note: Steps below already partly done for the first host if you have followed the server setup notes above. You need to repeat this process for each host that needs to connect to the server via VPN.
Now add a new peer, using your public key from your client machine. Make sure to allocate a unique IP for it:
[Peer]
## Desktop/client VPN public key ##
PublicKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
## client VPN IP address (note the /32 subnet) ##
AllowedIPs = 192.168.7.2/32
Configure on the client¶
sudo vim /etc/wireguard/wg-osgs.conf
[Interface]
## This Desktop/client's private key ##
PrivateKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
## Client ip address ##
# Replace .2 with your allocated ip address!
Address = 192.168.7.2/24
[Peer]
## Server public key ##
PublicKey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
## set ACL ##
AllowedIPs = 192.168.7.0/24
## Server's public IPv4/IPv6 address and port ##
Endpoint = XX.YY.ZZ.AA:41194
## Key connection alive ##
PersistentKeepalive = 15
Enable and start wireguard¶
sudo systemctl enable wg-quick@wg-osgs
sudo systemctl start wg-quick@wg-osgs
sudo systemctl status wg-quick@wg-osgs
To bring it down again in the future you can do:
sudo wg-quick down wg-osgs
Or to restart:
sudo systemctl restart wg-quick@wg-osgs
And to check status:
sudo wg
Which should show something like this:
interface: wg-osgs
public key: Kimironw1r21/RH3jbd97HTwtXjlUJFJAOXmBKuB+hg=
private key: (hidden)
listening port: 58616
peer: IdLyVLa0htZ82EKYWM9sXjB5ST15O3U5yYbNW+3XOQY=
endpoint: XX.YY.ZZ.AA:41194
allowed ips: 192.168.7.0/24
transfer: 0 B received, 296 B sent
persistent keepalive: every 15 seconds
Further configuration notes¶
Note: Only once you have verified that you can connect with a client.
Stopping Wireguard¶
systemctl stop wg-quick@wg-osgs
Configure ssh¶
For additional security you can set the SSH listenaddress to your VPN network so that it will not even respond to conneciton attempts from the wider internet.
vim /etc/ssh/sshd_config
Changed these (add them to the end of the file):
# Changed by Tim to listen on wireguard interface only
ListenAddress 192.168.7.1
# Disabled by Tim (should already be done in server_preparation step)
PermitRootLogin no
PasswordAuthentication no
Again, check carefully at the end of the file, some providers add a PasswordAuthentication yes
to the bottom of the file which you want to override.
Enable the VPN¶
systemctl enable wg-quick@wg-osgs
Enable the firewall¶
Now enable the firewall (you probably want to be logged in at the service provider’s virtual console here as your WAN connection will be dropped until you access via VPN).
ufw enable
ufw status
systemctl restart sshd
Should show:
Status: active
To Action From
-- ------ ----
41194/udp ALLOW Anywhere
22/tcp ALLOW 192.168.7.0/24
41194/udp (v6) ALLOW Anywhere (v6)
Now go to https://github.com/kartoza/kartoza/wiki/WireGuard-Client-Configuration for client configs….