SSH Tunnelling with Wireguard

In this blog post you will gain an understanding of what SSH Tunnelling is and what its used for, while also learning how to use Wireguard which is used to create a secure connection between two or more servers allowing us to port forward applications or create a VPN.

SSH Tunnelling with Wireguard

What is SSH Tunnelling?

SSH Tunnelling allows you to route traffic through a server hosted anywhere in the world to another server without having to port forward on your local Network exposing your public IP address, it also allows you to bypass your ISP restrictions on not allowing you to port forward. SSH Tunnelling creates a secure tunnel between both servers.

SSH Tunnelling - Diagram

Without SSH Tunnelling - Diagram

Note: This is just a basic diagram!

How is it used?

SSH Tunnelling can be used for multiple applications, one example is using it as a VPN. You can create a private secure VPN tunnel between multiple servers allowing a user to alter their location / hide their main IP address.
Another example is using SSH tunnelling to connect to a server securely, this can be used to allow certain users to connect to a server from a specific location (blocking connections from elsewhere).
The main use case for SSH Tunnelling that I personally use it for is Port Forwarding, allowing a user to open their server to be accessed anywhere without exposing their public IP address. (This is more secure because you can setup a server anywhere in the world and tunnel connections from that server to your local one, also allowing you set it up as a firewall.)

How I use it?

I have a local server on my Network that is used to host multiple application, usually to allow access to these applications I would have to port forward on my local router which is not secure because users would then be connecting into my local network, allowing the possibility to access other devices (Personal Computers, Phones, Laptops anything on the network) exposing my Public IP Address.

Diagram of basic Port Forwarding via your ISP / Router:
This is in most cases how you will port forward your applications, exposing your Public IP, using Wireguard we are able to mitigate this.

Using an SSH Tunnel I then create a secure connection from a VPS (Virtual Private Server) to my local server blocking any requests that don't go through my VPS securing any other device on my Local Network.

How does it work?

Using Wireguard to create a secure connection between multiple servers, this works by using “Cryptokey Routing” which creates Public Keys with a list of IP addresses that are allowed inside of the tunnel (This allows traffic to only be accepted if its coming through the secure tunnel). Each network interface (Wireless / Wired)  has a private key that is generated with a list of peers. Each peer has a public key which are used to authenticate the connections together. (A peer is your other server you want to setup the tunnel with).

Diagram:
In this Diagram there's a lot going on, the Public Server is the VPS which tunnels the connection to our local server. If a connection tries going straight to our local server it will be blocked, and a Peer with our public / private key will also be blocked because its IP is not trusted. In this diagram it shows a user has to connect to the VPS first in order to see the content our local server (website).

Conclusion

SSH Tunnelling is a service that is used to create a secure connection between servers / peers, the tunnel is encrypted and secure passing a private / public keys between both peers. SSH Tunnelling can be used to port forward a connection allowing access to your server publicly, a secure (VPN) connection and connecting to a server securely.

Now lets see how we can create our own SSH Tunnel!

Plan

  • Setup a VPS - Virtual Private Server
  • Install and configure Wireguard - Creates a secure connection between servers
  • Configure Port Forwarding - Allows the connection between servers publicly

Setting up a VPS

For this project I hosted a VPS from Vultr costing you $5 AUD a month for their cheapest server which is perfect for this project. Once you have created an account and created a VPS running Ubuntu Server you are ready to setup Wiregaurd! You can use my referral code to get $100 free credit on Vultr.

Installing Wireguard

Once you have setup your VPS you are able to SSH into it using the given IP address, once logged in you are ready.
On both your Local and VPS servers run the following commands:

Update:
sudo apt update
sudo apt install software-properties-common

Add Repository:
sudo add-apt-repository ppa:wireguard/wireguard
sudo apt update

Install Wiregaurd:
sudo apt install wireguard -y

Setting up Wireguard

Once Wiregaurd has installed on both servers we will need to generate a public and private key.

You can do this by running the commands below on both servers!
(umask 077 && printf "[Interface]\nPrivateKey = " | sudo tee /etc/wireguard/wg0.conf > /dev/null)
umask sets permissions for all newly created files in your current session.
wg genkey | sudo tee -a /etc/wireguard/wg0.conf | wg pubkey | sudo tee /etc/wireguard/publickey
wg is a wireguard utility for generating keys.

Note: The second command will display a public key that you will need to use copy these and keep note which server they are for.

Now you will need to edit your Wireguard config file in order setup the connection between both servers.

You can open the config file running this command:
sudo nano /etc/wireguard/wg0.conf

First lets setup our VPS, run the command above on your VPS server and add the following contents to the config file.

[Interface]
PrivateKey = (This will already be set)
ListenPort = 55107
Address = 192.168.4.1

[Peer]
PublicKey = *Paste your local server's public key here*
AllowedIPs = 192.168.4.2/32

Next lets setup our Local Server, again run the command above on your Local server and add the following contents to the config file.

[Interface]
PrivateKey = (This will already be set)
Address = 192.168.4.2

[Peer]
PublicKey = *Paste the VPS's public key here*
AllowedIPs = 192.168.4.1/32
Endpoint = *Set this to the public IP of your VPS*:55107
PersistentKeepalive = 25

The Addresses we have set are used to determine each server through the tunnel leave them as default.

Starting the connection

Once both config files have been setup you are ready to start the connection. You will need to open up port 55107 and 32 on both servers as we set them as the ports we are using to connect both servers.

You can do this by running the following commands:
ufw allow 55107
ufw allow 32

Once both ports are open we can now start the connection by running the following commands:

Starts the connection – sudo systemctl start [email protected]
Starts the connection on boot – sudo systemctl enable [email protected]

Testing the connection

Once you have successfully launched the connection you can test it by pining the IP addresses we set for each server, on your server run “ping 192.168.4.2” and on the VPS run “ping 192.168.4.1” if the pings are successful the connection is working correctly.

Setting up Port-Forwarding

We have now successfully setup Wireguard, we can now additionally expose some ports which will allow us to Port Forward our applications via our VPS server.

Before we run the IPtable commands to we need to enable ipv4 forwarding by editing our sysctl.conf, you can do this by “sudo nano /etc/sysctl.conf” remove the # before net.ipv4.ip_forward=1

Reload the config with “sudo sysctl –p” and “sudo sysctl –system”

Now we are ready to Port Forward!

Port-Forwarding

You can run the following commands to port forward your webserver, you can change this for any ports you would like to forward by replacing 80 and 443. Make sure to change eth0 with the interface that your public IP is bound to.

Allow traffic on these ports using the forward chain

sudo iptables -P FORWARD DROP
sudo iptables -A FORWARD -i eth0 -o wg0 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o wg0 -p tcp --syn --dport 443 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o wg0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A FORWARD -i wg0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Add rule that changes the destination address to the IP of our homeserver

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.4.2
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 192.168.4.2

Add some rules that allow the homeserver to send traffic back out through our VPN

sudo iptables -t nat -A POSTROUTING -o wg0 -p tcp --dport 80 -d 192.168.4.2 -j SNAT --to-source 192.168.4.1
sudo iptables -t nat -A POSTROUTING -o wg0 -p tcp --dport 443 -d 192.168.4.2 -j SNAT --to-source 192.168.4.1

Finishing up

Run the following commands to enable persistent IP table rules:

Install netfilter-persistent and iptables-persistent
sudo apt install netfilter-persistent iptables-persistent

Save firewall rules
sudo netfilter-persistent save
sudo systemctl enable netfilter-persistent

Conclusion

After all that everything should be working. You can now access your local server anywhere by going to the IP address of your VPS.

Thanks for taking the time to read through this Blog Post if you ran into any issues feel free to contact me!