Setting Up Tailscale Health Monitoring with Uptime Kuma
A comprehensive guide to monitoring your Tailscale network health using Uptime Kuma and a custom bash script.
If you're running Tailscale in your homelab, you know how crucial it is to ensure your network stays healthy and connected. After experiencing a few unexpected disconnections that took longer than necessary to notice, I decided to build a better monitoring solution using Uptime Kuma. What started as a simple ping check evolved into a more robust monitoring process that I've been running successfully for months.
In this guide, I'll share my complete setup for monitoring Tailscale using two complementary approaches: a custom health check script that watches your Tailscale service's vital signs, and a straightforward ping monitor that ensures continuous connectivity. I hope the effort I've put into developing and refining these monitoring solutions can help others in the homelab community who want to keep a closer eye on their Tailscale networks.
Whether you're running a small home network or managing a complex homelab setup, this monitoring solution will help you catch issues early and maintain a reliable Tailscale connection. Let's dive into how it all works.
Let's Dive In
I run two complementary monitors for my Tailscale network:
- A push monitor with a custom script for detailed health checks
- A basic ping monitor for continuous connectivity verification
Let's look at both setups:
The Monitoring Stack
The system consists of three main components:
- A bash script for health checks
- An Uptime Kuma push monitor
- A cron job for automated monitoring
Let's dive into each component and how they work together.
Setting Up the Health Monitor
1. Configuring the Push Monitor
In your Uptime Kuma installation, create a new monitor with these exact settings:
Monitor Type: Push
Friendly Name: Tailscale Health
Heartbeat Interval: 60 seconds
Retries: 3
Heartbeat Retry Interval: 60 seconds
Monitor Group: Security & Access Group
Tags:
- Authentication
- Network
- Networking
After saving, you'll get a push URL that looks like:
https://your-uptime-kuma-instance/api/push/yourtoken?status=up&msg=OK&ping=
This URL should be called every 60 seconds. Remember that status
, msg
, and ping
are optional parameters that our script will use.
First, we'll create a directory for our monitoring scripts:
mkdir -p ~/tailscale
Here's the complete monitoring script:
#!/bin/bash
# Configuration
PUSH_URL="YOUR_UPTIME_KUMA_PUSH_URL"
LOG_FILE="$HOME/tailscale/health.log"
# Function to URL encode
urlencode() {
local string="${1}"
local strlen=${#string}
local encoded=""
local pos c o
for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) printf -v o '%%%02x' "'$c"
esac
encoded+="${o}"
done
echo "${encoded}"
}
# Initialize log file
exec 1> >(tee -a "$LOG_FILE") 2>&1
echo "=== Health check started at $(date) ==="
# Debug output
echo "Checking Tailscale status..."
SYSTEMCTL_STATUS=$(systemctl status tailscaled)
echo "$SYSTEMCTL_STATUS"
# Check Tailscale status
STATUS="down"
MESSAGE="Tailscale issues detected"
# Perform health checks with debug output
if systemctl is-active --quiet tailscaled; then
echo "Tailscale daemon is active"
TAILSCALE_IP=$(tailscale ip -4 2>/dev/null)
if [ ! -z "$TAILSCALE_IP" ]; then
echo "Tailscale IP found: $TAILSCALE_IP"
if echo "$SYSTEMCTL_STATUS" | grep -q "Status.*Connected"; then
echo "Tailscale shows connected status"
STATUS="up"
MESSAGE="Tailscale healthy - IP: $TAILSCALE_IP"
else
echo "Tailscale not showing connected status in systemctl"
fi
else
echo "No Tailscale IP found"
MESSAGE="Tailscale issues detected - No IP assigned"
fi
else
echo "Tailscale daemon is not active"
MESSAGE="Tailscale issues detected - Daemon not active"
fi
# URL encode the message
ENCODED_MESSAGE=$(urlencode "$MESSAGE")
# Construct and send the push request
FINAL_URL="${PUSH_URL}?status=${STATUS}&msg=${ENCODED_MESSAGE}"
echo "Sending request to: $FINAL_URL"
curl -s "$FINAL_URL"
# Log completion
echo "Status: $STATUS"
echo "Message: $MESSAGE"
echo "=== Health check completed at $(date) ==="
echo "----------------------------------------"
Save this script as check-tailscale.sh
and make it executable:
chmod +x check-tailscale.sh
The script performs several key checks:
- Verifies the Tailscale daemon is running
- Checks for a valid IP assignment
- Confirms the connection status
- Logs all activities for debugging
- Pushes status updates to Uptime Kuma
2. Configuring Uptime Kuma
In your Uptime Kuma installation:
-
Create a new monitor with these settings:
Monitor Type: Push Friendly Name: Tailscale Health Heartbeat Interval: 60 seconds Heartbeat Retry Interval: 60 seconds Retries: 3
-
After saving the monitor, Uptime Kuma will generate a unique push URL. It will look something like:
https://your-uptime-kuma-instance/api/push/xxxxxxxx
-
Copy this push URL - you'll need to update the script with it:
- Open the script in your editor
- Replace
YOUR_UPTIME_KUMA_PUSH_URL
with the URL you just copied - Save the script
This push URL is unique to this monitor and acts as an authentication token. Keep it secure, as anyone with this URL can push status updates to your monitor.
3. Setting Up the Cron Job
To run the check every minute, add this to your crontab:
crontab -e
Add the line:
* * * * * ~/tailscale/check-tailscale.sh
Monitoring Details
The script provides comprehensive monitoring of your Tailscale installation:
- Daemon Status: Ensures the Tailscale service is running
- IP Assignment: Verifies your node has a valid Tailscale IP
- Connection State: Checks if you're properly connected to the Tailscale network
- Overall Health: Combines multiple checks for a complete health status
Logging
The script maintains a detailed log file at ~/tailscale/health.log
. You can view recent logs with:
tail -f ~/tailscale/health.log
Troubleshooting Guide
If you run into issues, here's a systematic way to troubleshoot:
-
Test Script Execution:
./check-tailscale.sh
-
Verify Cron Service:
systemctl status cron
-
Check Script Permissions:
ls -l check-tailscale.sh
-
Review Recent Logs:
tail -n 50 ~/tailscale/health.log
Expected Behavior
When everything is working correctly, you'll see:
Status: up
Message: Tailscale healthy - IP: [Your Tailscale IP]
If issues are detected:
Status: down
Message: Tailscale issues detected - [specific issue]
Maintenance Tips
Regular maintenance tasks to keep in mind:
-
Monitor Log Size:
du -h ~/tailscale/health.log
-
Set Up Log Rotation: Create a logrotate configuration at
/etc/logrotate.d/tailscale-monitor
-
Regular Status Checks:
- For Tailscale:
tailscale status
- For the daemon:
systemctl status tailscaled
Setting Up the Connectivity Monitor
In addition to the health check, I run a basic ping monitor to continuously verify connectivity. This provides a simpler, more direct check of the Tailscale network.
Create a new monitor in Uptime Kuma with these settings:
Monitor Type: Ping
Friendly Name: Tailscale Basic Connectivity
Hostname: YOUR_TAILSCALE_IP # Your Tailscale IP address
Heartbeat Interval: 60 seconds
Retries: 0
Heartbeat Retry Interval: 60 seconds
Packet Size: 57
Monitor Group: Security & Access Group
Tags:
- Authentication
- Network
- Networking
- Security
This monitor provides a different perspective on your Tailscale network:
- While the health check monitors the service and daemon status
- The ping monitor verifies actual network connectivity
- Together, they provide comprehensive monitoring coverage
Notifications
I have both monitors configured to send notifications through a personal Discord bot. This setup ensures I'm immediately aware of any issues with either:
- The Tailscale service itself (from the health monitor)
- The actual network connectivity (from the ping monitor)
You can configure notifications in Uptime Kuma to use various channels:
- Discord
- Telegram
- Slack
- And many others
Getting Help
If you run into issues:
- Check Tailscale's official documentation
- Verify Uptime Kuma's push monitor settings
- Review script logs for specific errors
- Ensure all permissions are set correctly
This setup has been running in my homelab for months now, providing peace of mind that my Tailscale network is healthy and functioning as expected.
This post is part of my homelab documentation series. Check out my other posts for more networking and monitoring tips!