Nov 5, 2020
(C) The article was initially published at https://selfhosted.pro/hl/wireguard_vps/; the original owner retains ownership and rights. (R)SelfHostedPro
This article is now a collab between SelfHostedPro and WIckedYoda. I also assume you have some minor networking knowledge and know how to create a VM in DigitalOcean, AWS, or your preferred service.
Here is also a youtube video as I walked through the commands and verified below works. https://youtu.be/ge1bRTLFZXU
In the past, I’ve had to deal with ISPs blocking ports and, in some cases, the most usable incoming ports. I want to show you how to bypass this using Wireguard and a VPS. That way, you can start self-hosting services even if your ISP doesn’t want you to.
For this tutorial, I will use a DigitalOcean VPS (their smallest one), but you can use any provider you want. I’m going to provide referral links for some hosting services below. I don’t make money from them, but I can get free server time.
In my attached video (WickedYoda), I used AWS lightsail to spin up a small VM on the cloud and removed it after making the video. I ran through all the setups on one end of the setup; the cloud. The home end is almost duplicated of the cloud side minus a few specified changes.
Also, the start (as I am not done) of scripting this is at https://github.com/wickedyoda/VPS_tunnel_Commands on GitHub. You are welcome to contribute and work on the project as well.
Once you’ve got your VPS setup, you’ll want to ssh in and start setting up Wireguard. Keep a terminal open on your internal server that you want to forward to, as we’ll be running many of the same commands on both.
The first thing we’ll do on both servers is up to date all of our software and reboot to ensure we’ve got the latest kernel.
#both sudo apt update -y && sudo apt upgrade -y && sudo reboot
I ran the following commands to get the client and server’s OS up to date. I create a minor update.sh file, which can be run at any time.
#create the file sudo nano update.sh #paste this in the file sudo apt-get update sudo apt-get full-upgrade -y sudo apt-get dist-upgrade -y sudo apt-get autoremove -y sudo apt-get clean -y sudo apt-get purge -y #use ctl+o to save and ctl+x to exit nano #then use the chmod to enable excute perms to the file you created. sudo chmod +x ./update.sh #run the updates by sudo ./update.sh
This update file is always there and will remain on your system; you can run it manually or schedule it through crontabs.
We’ll go ahead and add the wireguard repository and install it now. First, you will want to add the required packages to their repository and then add their repository.
sudo apt install software-properties-common #Depleted and not necessary as of on Ubuntu only Debian sudo add-apt-repository ppa:wireguard/wireguard
Then we’re going to install wireguard.
#both sudo apt update # to make sure we've indexed the packages on their repo sudo apt install wireguard -y
We’ll first use the
wg utility to generate some keys so the servers can authenticate with each other.
#both (umask 077 && printf "[Interface]\nPrivateKey= " | sudo tee /etc/wireguard/wg0.conf > /dev/null) wg genkey | sudo tee -a /etc/wireguard/wg0.conf | wg pubkey | sudo tee /etc/wireguard/publickey
Save both of the public keys that show for later. We’ll use them later. Go ahead and open
/etc/wireguard/wg0.conf them with your preferred editor, and we’ll finish configuring these.
The following is an example of the wg0.conf on the VPS.
[Interface] PrivateKey = <private key should be here> ListenPort = 55107 Address = 192.168.4.1 [Peer] PublicKey = <paste the public key from your home server here> AllowedIPs = 192.168.4.2/32
The following is an example of the wg0.conf on your home server.
[Interface] PrivateKey = <private key should be here> Address = 192.168.4.2 [Peer] PublicKey = <paste the public key from your VPS here> AllowedIPs = 192.168.4.1/32 Endpoint = <paste the public ipv4 address of your VPS here>:55107 PersistentKeepalive = 25
Now we’ll need to make some changes to our sysctl.conf to allow our VPS to forward using IPtables. Open
/etc/sysctl.conf in your favorite editor.
Please find the following line and remove the
# one commenting it out. They should look like the below once done.
#VPS net.ipv4.ip_forward=1 #if you wish to IP forward via IPv6 then remove the # from: net.ipv6.conf.all.forwarding=1
Then we’ll apply that change with the following commands.
#VPS sudo sysctl -p sudo sysctl --system
Now that everything is configured, we’ll go ahead and start up our tunnel between the servers using the following command.
#both sudo systemctl start wg-quick@wg0 sudo systemctl enable wg-quick@wg0
Then we’re going to ping the servers from each other. On your VPS, try to ping your home server. On your home server, try to ping your VPS. (using the IPs in your wireguard configuration)
#VPS ping 192.168.4.2
#Home server ping 192.168.4.1
If successful, then the tunnel is working.
On our VPS, we’re going to set up some IPtables rules to forward to a reverse proxy running on our home server.
Replace eth0 with the public interface of your VPS (found using
# VPS # By default drop traffic sudo iptables -P FORWARD DROP # Allow traffic on specified ports 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 # Allow traffic between wg0 and eth0 sudo iptables -A FORWARD -i wg0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT sudo iptables -A FORWARD -i wg0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Forward traffic from eth0 to wg0 on specified ports 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 # Forward traffic back to eth0 from wg0 on specified ports 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
To have these rules persist through reboots, we’ll need to install netfilter-persistent, use it to save the current configuration, and then enable it.
# VPS sudo apt install netfilter-persistent sudo netfilter-persistent save sudo systemctl enable netfilter-persistent
Then we’ll need to use iptables persistent and configure that.
# VPS sudo apt install iptables-persistent # hit yes to save the current rules.
Now everything should be set up, and ports 80 and 443 should be forwarded to your home server.
# Forward traffic from eth0 to wg0 on specified ports 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 # Forward traffic back to eth0 from wg0 on specified ports 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 #You can also edit the above code to open additional ports into your network by replaceing the port 80/443 and exchanging tcp/udp depending on the protocol.