Need to be able to log in to all your homelab / server stuff on the go? Need a VPN for private browsing at work or on public wifi? Need to have access to all your Street Sharks episodes 24/7 instead of carrying a VHS player and a TV in your backpack? Want all of that simultaneously? Wireguard is for you.
After a whole lot of troubleshooting, copy and pasting random crap from every tutorial on Google, and seeing the “This subreddit is private” message a few thousand times — I’ve finally got a fully working wireguard tunnel to my homelab. I’d like to cement that knowledge here for my (or your) future reference.
TLDR: If you can connect and ping devices inside your network, but you cannot ping external websites — check the firewall rules on the Wireguard server first. If you can ping everything but are still having major issues — try adjusting (reducing) the MTU.
First, create your container or VM. For this example, I’m using Ubuntu Server 22.10.
Wireguard can run on very minimal resources, so the default cpu/mem values are fine:
Do be sure to set a static IP address, x.x.x.x/32 —
Then start the container/vm, log into it, and get it patched up to date:
apt update && apt upgrade -y
And also install curl and wireguard:
apt install curl wireguard
Now you’re ready to install PiVPN, a set of helper scripts that make adding Wireguard clients super easy:
curl -L https://install.pivpn.io | bash
Now you will be greeted with a nice graphical installer. Select a username and password to continue (not root).
If you received an error here, make sure you have installed wireguard / wireguard-tools from the previous step. The script will fail if you try to let it auto-install.
If you are running a pi-hole, unbound, Merlin firmware scripts, or some other form of DNS server, make sure to select it here in the next step. Otherwise, choose Google or whatever.
This step is where you tell the clients where to locate the server. This could be your IP address if you have a static IP, or a domain name if you own one. Otherwise, use a dynamic DNS provider like https://duckdns.org to get a free domain that points to your server:
Reboot one more time after the installation is complete.
Now you need to set up packet forwarding from the virtual wireguard interface, wg0, to the real network interface, usually eth0. Without this step, you will be able to access all of the devices on the same network as the wireguard server, but you will not be able to reach any external sites (e.g. use the VPN for private browsing). The way to complete this step is different for each linux distribution, but for Ubuntu it is very simple:
Uncomment this single line shown in white below:
Save the file, and run this command to make sure it worked:
sudo sysctl -p
If you see “net.ipv4.ip_forward = 1”, you’re good to go.
And finally, add nat and forwarding to iptables with the following command:
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
That should do it. Now you can create your first tunnel:
After selecting the name for your new tunnel, pivpn will automatically generate the config file and drop it in both /home/the_username_you_chose/configs as well as /etc/wireguard/configs.
Using any method, copy that config file to the client device manually or scan the QR code that pivpn generates for you:
Once the config is on your client device, make sure the correct port (default 51820) is opened on your router for the IP address you selected earlier. Then, launch Wireguard and try it out!!
Here is my test-thinkpad config file, moved to my thinkpad in /etc/wireguard — and fired up:
wg-quick up test-thinkpad
Notice that now I can ping both google.com and my home router, 192.168.1.1!! (I am away from home).
However, I still cannot actually make it to any websites. I also can’t use ssh or anything. Ping is the only thing that works!
For me, the solution to this final problem is to lower the MTU.
This needs to be done on both the server and the client.
Change the MTU to 1280.
and in the client config as well. (Remember, you put it in /etc/wireguard — change the name to YOUR config file)
Add the MTU = 1280 line in under the [Interface] section:
Now restart both interfaces and test it again:
Heck yea! I even have access to all my samba drives as if I was at the house:
I can pull up the proxmox console for my server cluster directly from the private IP address 192.168.1.x:
I’m also enjoying the benefit of private browsing through my home internet connection instead of this public wifi.
Hope this tutorial was helpful and easy to follow. Enjoy!