---
slug: wireguard-tunnel-from-ubuntu-vps-to-homelab-through-unifi-vpn-server
title: "WireGuard tunnel from Ubuntu VPS to HomeLab through UniFi VPN server"
tags: [self-hosting, homelab, WireGuard, VPN]
image: /img/blog/2025/02/tunnel.jpg
---
I'm not surprised people prefer Tailscale over WireGuard. Did you see the WireGuard [quick start guide](https://www.wireguard.com/quickstart/)? Did you try to connect using this guide? Anyway, I have a VPS on Hetzner I wanted to connect to my local network through a secure tunnel. Tailscale is nice, but why set up a new infrastructure when I have one inside my UniFi Cloud Gateway Ultra?

<!-- truncate -->

:::warning

This guide will work for you only if you have a static WAN IP

:::

So first of all I went to _Settings -> VPN_ on my UniFi Cloud Gateway Ultra, switched to a _VPN Server_ tab, and added a new Wireguard VPN server. I let UniFi decide on the client's IP range.

Then I added a client, which will be my VPS. And downloaded a WireGuard interface config file there:

![](001.png)

Then I connected to my VPS through SSH to make some Linux command line magic.

:::note

I need to mention here that I'm writing this guide a long time after the actual setup. So unfortunately I can't remember the sources I found tips and tricks to make this work. But it works now for me and can help to make it work for you, my dear reader.

:::

On my VPS I have Ubuntu 24.04 installed.

So, to the command line. Install WireGuard:

```bash
sudo apt install wireguard
```

Create a config file:

```bash
sudo nano /etc/wireguard/wg0.conf
```

Insert the configuration downloaded from the UniFi VPN client creation step:

```
[Interface]
PrivateKey = ***************************************
Address = 192.168.4.2/32
DNS = 192.168.4.1

[Peer]
PublicKey = ***************************************
AllowedIPs = 0.0.0.0/0
Endpoint = ***.***.**.**:51821
```

Now edit it to look like this:

```
[Interface]
PrivateKey = ***************************************
Address = 192.168.4.2/32
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
ListenPort = 51820

[Peer]
PublicKey = ***************************************
AllowedIPs = 192.168.4.0/24,192.168.50.0/24,192.168.1.0/24
Endpoint = ***.***.**.**:51821
PersistentKeepalive = 10
```

`PostUp` and `PostDown` are commands to be executed when the WireGuard network interface connects or disconnects. In my case, this is to add and remove `iptables` rules for WireGuard traffic routing through the default network interface.

`AllowedIPs` should be edited to your needs. Here is my needs:

- `192.168.4.0/24` allows access to any IP address on the same subnet as the VPS would be placed after connecting
- `192.168.50.0/24` allows access to any IP on my other subnet
- `192.168.1.0/24` allows access to any IP on my main subnet (I'm not sure about this, but anyway the access is blocked on the UniFi Firewall level)

These rules are loose because the Firewall on my UniFi Gateway blocks any cross-subnet traffic anyway allowing only limited communications.

This should be enough to bring the connection up with `wg-quick`:

```bash
sudo wg-quick up wg0
```

To see the status:
```bash
sudo wg show
```

And now to make it work through server reboots we need to down the interface:

```bash
sudo wg-quick down wg0
```

And up it back with a system service, also enabling it:
```bash
sudo systemctl start wg-quick@wg0 && sudo systemctl enable wg-quick@wg0
```

Further interface control should be performed through `systemctl` as well like `systemctrl stop`, `systemctl restart` or `systemctl status`.