108 lines
3.6 KiB
Markdown
108 lines
3.6 KiB
Markdown
---
|
|
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:
|
|
|
|

|
|
|
|
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`. |