Monitor Private Services with Uptime Kuma via WireGuard
Learn how to monitor private services with Uptime Kuma by establishing a secure WireGuard VPN tunnel between your monitoring instance and internal networks.
Disclosure: this article contains an affiliate link. DotExe may earn a commission if you purchase through it, at no extra cost to you. Any discount is subject to Hostinger's current offers (20% OFF) and eligibility terms.
Monitoring infrastructure that lives behind a firewall or within a private network presents a unique challenge for centralized observability tools. When you need to monitor private services with Uptime Kuma, you cannot simply point your public-facing monitoring instance at a private IP address. Instead, you must bridge the gap between your monitoring server and the target network. WireGuard provides a lightweight, performant, and secure way to create this bridge, allowing your Uptime Kuma instance to reach internal services as if they were local.
Understanding the Architecture
In a typical self-hosted environment, your Uptime Kuma instance might reside on a VPS or a public-facing server, while your critical internal services (like databases, internal APIs, or management dashboards) sit inside a home or office network. To monitor these, you need a secure tunnel that allows the Uptime Kuma container to route traffic into the private subnet.
By deploying WireGuard on both the monitoring host and a gateway node within the target network, you create a virtual private network. Because WireGuard operates at the kernel level, it is exceptionally fast and has a small footprint, making it ideal for containerized environments. Once the tunnel is established, you can assign static internal IPs to your containers, allowing Uptime Kuma to perform HTTP, TCP, or ICMP checks against services that are otherwise unreachable.
Unlike traditional VPNs like OpenVPN or IPsec, WireGuard is designed to be lean. It uses modern cryptography and is integrated directly into the Linux kernel, which reduces context switching and CPU overhead. For a monitoring tool like Uptime Kuma, which performs constant, small-packet polling, this efficiency is critical to ensure that the monitoring overhead itself does not impact the performance of the services being monitored.
Prerequisites and Assumptions
To follow this guide, you will need:
- A server running Uptime Kuma (see our guide on setting up Uptime Kuma with Docker Compose).
- A gateway device in your private network (a Raspberry Pi, a dedicated VM, or a router that supports WireGuard).
- Docker and Docker Compose installed on both ends.
- Basic knowledge of IP routing and subnetting.
We assume your monitoring server has a public IP and your target network uses a private IP range (e.g., 192.168.1.0/24). We also assume you have root or sudo access on both the monitoring host and the gateway device, as WireGuard requires kernel-level configuration.
Step 1: Configuring the WireGuard Gateway
First, set up the WireGuard interface on the device within your private network. This device will act as the peer that allows the monitoring server to enter the local subnet. We will use the linuxserver/wireguard Docker image for consistency, as it handles the complex iptables and kernel module loading automatically.
Create a docker-compose.yml on the gateway device:
version: '3.8'
services:
wireguard:
image: lscr.io/linuxserver/wireguard:latest
container_name: wireguard
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- PUID=1000
- PGID=1000
- PEERS=1
- SERVERURL=your.public.ip.or.domain
- SERVERPORT=51820
- INTERNAL_SUBNET=10.13.13.0/24
volumes:
- ./config:/config
- /lib/modules:/lib/modules
ports:
- 51820:51820/udp
restart: unless-stopped
After starting this container with docker-compose up -d, the configuration files will be generated in the ./config directory. You will need the peer1 configuration to connect your Uptime Kuma instance. This directory will contain a wg0.conf file and a peer1 folder containing the client configuration. The PEERS=1 environment variable tells the container to generate one client configuration file automatically.
Step 2: Connecting Uptime Kuma to the VPN
On your Uptime Kuma host, you have two primary options: install WireGuard directly on the host OS or run a WireGuard sidecar container. Running it as a container is generally cleaner for maintenance and keeps your host OS clean from networking configuration drift.
If you use a sidecar, you can configure Uptime Kuma to use the network namespace of the WireGuard container. This ensures all traffic from Uptime Kuma destined for the private network flows through the tunnel. This is a powerful pattern in Docker networking because it isolates the VPN traffic to only the containers that need it.
Update your docker-compose.yml for Uptime Kuma:
version: '3.8'
services:
uptime-kuma:
image: louislam/uptime-kuma:latest
container_name: uptime-kuma
network_mode: service:wireguard
depends_on:
- wireguard
wireguard:
image: lscr.io/linuxserver/wireguard:latest
container_name: wireguard
cap_add:
- NET_ADMIN
volumes:
- ./wg-config:/config
restart: unless-stopped
By setting network_mode: service:wireguard, the Uptime Kuma container shares the network stack of the WireGuard container. Any request Uptime Kuma makes to an IP within the 10.13.13.0/24 range will be routed through the tunnel. Note that when using network_mode: service:wireguard, you must move the port mapping from the uptime-kuma service to the wireguard service if you want to access the Uptime Kuma dashboard from your browser.
Step 3: Routing Traffic to the Private Subnet
Simply connecting the two nodes is not enough; the WireGuard gateway needs to know how to route traffic to your local network. You must modify the wg0.conf on your gateway device to include the local subnet in the AllowedIPs and ensure IP forwarding is enabled on the host. This is a common point of failure for beginners; without IP forwarding, the gateway will drop packets intended for the internal network.
On the gateway host, enable forwarding permanently:
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
In your wg0.conf on the gateway, ensure the PostUp and PostDown rules handle the NAT (Network Address Translation) so that requests from the VPN tunnel appear to originate from the gateway device itself. This makes the internal services think the traffic is coming from the gateway, which is usually already trusted:
[Interface]
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
This configuration ensures that when Uptime Kuma sends a request to 192.168.1.50 (a private service), the gateway receives it, translates the source, and forwards it to the target service. You should also ensure that the AllowedIPs for the peer in wg0.conf includes the private subnet, such as 10.13.13.0/24, 192.168.1.0/24.
Operational Considerations and Security
When you monitor private services with Uptime Kuma via a VPN, you are essentially extending your attack surface. Ensure that your WireGuard configuration uses strong keys and that the Uptime Kuma instance is protected with a robust password and, if possible, restricted behind a reverse proxy like Nginx or Caddy.
If you are looking for reliable hosting for your monitoring instance, check out Hostinger Web Hosting to get started with a stable environment. Disclosure: this article contains an affiliate link. DotExe may earn a commission if you purchase through it, at no extra cost to you. Any discount is subject to Hostinger's current offers (20% OFF) and eligibility terms.
Security-wise, treat your WireGuard interface as an untrusted network. Even though it is encrypted, the services you are monitoring might not expect traffic from the VPN subnet. You may need to update your internal firewall rules on the target services to allow traffic from the VPN IP range (e.g., 10.13.13.0/24).
Diagnostics and Troubleshooting
If your monitors are failing, start by checking the connectivity between the containers. Use docker exec -it wireguard ping <target-ip> to verify that the tunnel is passing traffic. If the ping fails, verify that the AllowedIPs in your peer configuration includes the subnet of your private network.
Common failure modes include:
- MTU Mismatches: WireGuard packets can be large. If you experience intermittent connection drops, try lowering the MTU in your
wg0.confto1380. This is especially common when the path between the VPS and your home network passes through multiple ISPs that might have different MTU settings. - Firewall Rules: Ensure the local firewall (UFW or iptables) on your gateway device allows traffic from the WireGuard interface. Sometimes, the default policy for the
FORWARDchain isDROP. - Routing Loops: Ensure that the IP range of your VPN tunnel does not overlap with your existing local network subnets. If your VPN is
192.168.1.0/24and your home network is192.168.1.0/24, the routing table will be ambiguous, and traffic will likely fail to reach the intended destination. - DNS Resolution: If you are monitoring by hostname, ensure that the Uptime Kuma container can resolve the internal DNS names. You may need to configure a custom DNS server in your Docker container or use the IP address directly.
Advanced Networking: Split Tunneling
For more complex setups, you might want to perform split tunneling. This ensures that only traffic destined for your private network goes through the WireGuard tunnel, while all other traffic (like updates or external API checks) goes through the default internet gateway. This reduces the load on your home connection and improves latency for public-facing monitors. To achieve this, you need to configure specific static routes on the Uptime Kuma host instead of routing all traffic through the WireGuard interface.
Conclusion
Monitoring private services with Uptime Kuma via WireGuard is a robust solution for maintaining visibility into isolated environments. By leveraging the security and performance of WireGuard, you can treat your private infrastructure as a first-class citizen in your monitoring stack. This setup provides a reliable, encrypted path that avoids the risks of exposing internal services to the public internet. By following the steps outlined here, you can ensure that your monitoring is not just functional, but also secure and resilient against common network failures.
Frequently Asked Questions
Why use WireGuard instead of a standard reverse proxy for monitoring?
WireGuard operates at the network layer, allowing you to monitor internal services using their native private IP addresses without needing to expose each individual service through a reverse proxy or public domain. This approach is more secure as it keeps your internal services completely off the public internet, requiring a VPN connection to even reach the network layer.
Can I monitor multiple private networks with one Uptime Kuma instance?
Yes, you can configure multiple WireGuard peers within your Uptime Kuma gateway container to connect to different private networks simultaneously. Each network can be assigned a unique static IP range, allowing Uptime Kuma to route traffic to the appropriate gateway based on the destination IP.
Is this setup resilient to network reboots?
Yes, by using Docker Compose with restart: unless-stopped policies, the WireGuard tunnel will automatically re-establish its connection whenever the host or the container restarts. This ensures that your monitoring remains consistent even after power cycles or network interruptions, provided the underlying host maintains internet connectivity.
What are the performance impacts of using a VPN for monitoring?
WireGuard is highly efficient and introduces negligible latency, making it ideal for monitoring tasks that require frequent polling. The overhead is significantly lower than traditional VPN solutions like OpenVPN, ensuring that your Uptime Kuma checks remain accurate and are not delayed by the encryption process.