top of page

Secure Your VPS Services with WireGuard: A Complete Guide to Site-to-Site VPN with Uptime Kuma Monitoring

Updated: Jan 18

I joined last year the Xandeum Crypto Community and became overnight a pNode-Owner. Xandeum's goal is to provide a storage layer on top of the Solana blockchain




The Problem


As an owner of a tiny fraction of this ecosystem, I am responsible to make sure my pNodes are up and running. Instead of constantly logging into the different servers via SSH i was looking for a way to make sure that the servers are up and running. So on a long weekend i was looking into how to connect my local network with the different VPS Servers and to monitor them not only from a technical connectivity (e.g ping the server) but to ensure that the services running on the VPS are actually responding correctly when they are called.


One service in the Xandeum Stack (aka pod.service) has an RPC endpoint that's bound to 127.0.0.1:6000. This is a common security practice—services listening only on localhost can't be accessed from the internet. But what if you need to access these services from your home network?


The traditional solutions have drawbacks:

  • Opening ports to the internet — Security nightmare

  • SSH tunnels — Manual setup every time, not persistent

  • Exposing services on public IPs — Increases attack surface


The better solution? A site-to-site WireGuard VPN between my home router and the VPS. This creates an encrypted tunnel where my entire home network can securely access VPS services as if they were local.


Architecture Overview

Key components:

  • Home Router acts as WireGuard server (192.168.40.1)

  • Contabo VPS acts as WireGuard client (192.168.40.11)

  • socat relays traffic from the VPN interface to localhost services

  • Uptime Kuma monitors the RPC endpoint through the VPN tunnel

  • Firewall installed on the VPS - i use ufw in this example


Prerequisites:

  • A VPS (I'm using Contabo, but any provider works)

  • A home router that supports WireGuard (or a dedicated Linux box) - i use a Unifi Dream Machine SE

  • Root/sudo access on the VPS side as well admin rights on your router

  • Basic familiarity with Linux command line

  • A internet provider who does not use CGNAT (if so you need a static IP)


Part 1: Setting up the Wireguard on your home router



On the Home Router (Server) - for Unifi


On your Unifi Console go to System Settings > VPN > VPN Server and select "Create New"


  1. Make sure you to select your WAN IP

  2. Select Manual so you can define your own Subnet for the VPN

  3. Define the VPN IP Subnet - 192.168.10.255

  4. Select "Add Client" to add your first client


  1. 5. Enter a name for your new client e.g. Pnode Test

  2. If you want to select your the IP you want to use for this client, if not, Unifi will pick the first available

  1. Enter the custom IP for your VPS Client (192.168.40.11)

  2. Download the client configuration file for your new client to your desktop

Congrats you configured the Server side for your wireguard VPN!

The file should look like this - please do not share you public IP and the keys in this files with anyone, in order to prevent a security breach


Part 2: Installing WireGuard on your VPS

Log into your VPS via SSH


On the VPS (Ubuntu/Debian)

sudo apt update
sudo apt install wireguard


Part 3: Configuring the VPS (WireGuard Client)

  1. Create a new configuration file for your Wireguard client:

sudo nano /etc/wireguard/wg0.conf
  1. Paste the configuration file into the created conf file:


[Interface]
PrivateKey = <VPS_PRIVATE_KEY>
Address = 192.168.40.11/24

[Peer]
# Home Router
PublicKey = <HOME_ROUTER_PUBLIC_KEY>
AllowedIPs = 192.168.40.1/32, 192.168.10.0/24
Endpoint = <HOME_ROUTER_PUBLIC_IP>:51821
PersistentKeepalive = 25

Please make sure you append the line

PersistentKeepalive = 25

to the config file and also adjust the line AllowedIPs to your specific setup

AllowedIPs = 192.168.40.1/32, 192.168.1.0/24

Configuration breakdown:

  • AllowedIPs includes both the router's VPN IP AND your home LAN subnet (192.168.1.0/24)—this allows return traffic to reach your home devices

  • Endpoint — Your home router's public IP address

  • PersistentKeepalive — Sends a packet every 25 seconds to keep the connection alive through NAT

Enable and Start

sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

Verify the Connection

# Check interface status
sudo wg show
# Test connectivity from VPS to home router
ping 192.168.40.1

Part 4: The socat Relay — Exposing Localhost Services

Here's the clever part. The Xandeum pod RPC service only listens on 127.0.0.1:6000 and I can't change that. But I can use socat to relay traffic from the VPN interface to localhost.


Install socat

sudo apt install socat

Test It Manually

socat TCP-LISTEN:6000,bind=192.168.40.11,fork,reuseaddr TCP:127.0.0.1:6000

This tells socat to:

  • Listen on the VPN IP (192.168.40.11) port 6000

  • Forward all traffic to localhost:6000

  • Fork for multiple connections

  • Reuse the address if restarted


Make It Permanent with systemd

Create /etc/systemd/system/rpc-relay.service:

[Unit]
Description=RPC Relay via socat
After=network.target wg-quick@wg0.service

[Service]
Type=simple
ExecStart=/usr/bin/socat TCP-LISTEN:6000,bind=192.168.40.11,fork,reuseaddr TCP:127.0.0.1:6000
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl daemon-reload
sudo systemctl enable --now rpc-relay

Verify It's Running

ss -tlnp | grep 6000

You should see:

LISTEN  0  1024  127.0.0.1:6000    *:*  users:(("pod",...))
LISTEN  0  5     192.168.40.11:6000  *:*  users:(("socat",...))

Part 5: Configuring UFW Firewall

Don't forget the firewall! UFW needs to allow traffic from the VPN subnet.

# Allow WireGuard traffic
sudo ufw allow 51820/udp

# Allow RPC access from VPN subnet only
sudo ufw allow from 192.168.40.0/24 to any port 6000 proto tcp
# Verify
sudo ufw status

The beauty of this setup is that port 6000 is only accessible from the VPN subnet—it's not exposed to the public internet.


Part 6: Testing from local network

From any device on your home network, you should now be able to access the VPS service - Attention this is specific to the Xandeum Pod software - if you have a different use case you need to adjust the following commands:


curl -X POST http://192.168.40.11:6000/rpc \
	-H "Content-Type: application/json" \
	-d '{
    "jsonrpc": "2.0",
    "method": "get-version",
    "id": 1
  }' | jq

Common Pitfalls - if it times out, check:

  1. Ping the VPS from the local network (ping 192.168.40.11)

  2. Ping the Wireguard server from the VPS (ping 192.168.40.1)

  3. WireGuard is running on both ends (sudo wg show)

  4. socat is listening (ss -tlnp | grep 6000)

  5. UFW rules are in place (sudo ufw status)

Part 7: Monitoring with Uptime Kuma

Now that the RPC is accessible over the VPN, let's monitor it with Uptime Kuma..


Deploy Uptime Kuma (Docker Compose)

services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    container_name: uptime-kuma
	restart: unless-stopped
	ports:
	  - "3001:3001"
  volumes:
    - uptime-kuma-data:/app/data
	- /var/run/docker.sock:/var/run/docker.sock:ro

volumes:
  uptime-kuma-data:

Start it:

docker compose up -d

Access the web UI at http://your-server:3001 and create an admin account.


Configure the RPC Monitor

  1. Click Add New Monitor

  2. Monitor Type: HTTP(s) - JSON Query

  3. URL: http://192.168.40.11:6000/rpc

  4. Method: POST

  5. Body:

{
  "jsonrpc": "2.0",
  "method": "get-version",
  "id": 1
} 
  1. Headers: Add Content-Type: application/json

  2. JSON Query: $.jsonrpc (or $.result to check the actual response)

  3. Expected Value: 2.0


Uptime Kuma will now POST to your RPC endpoint every minute (configurable) and alert you if it goes down.


Congratulations you can now monitor your pNode remotely and create dashboards like this:


Next Steps for me

I will continue to further build out my Monitoring network - uptime-kuma is awesome for simple heartbeat monitoring. But i am also keen on monitoring CPU, Memory Utilization as well Diskspace.

Stuff for a future Blog.


Comments


bottom of page