# 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](server_preparation.md) 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....