WireGuard Simple Watchdog Script

Why do you need a WireGuard watchdog script?

When running WireGuard VPN tunnels, especially for services like GetPublicIP that provide static IP addresses through VPN connections, maintaining a stable connection is crucial. However, your internet service provider may change network conditions such as your public IP address, which can cause the WireGuard connection to hang or become unresponsive.

In these situations, the WireGuard interface may appear to be up and running, but the connection has actually stopped working because the underlying network conditions have changed. Without active monitoring, you might not notice until external services can no longer reach your server, potentially causing downtime for your hosted services.

This simple watchdog script monitors WireGuard connections by checking the last handshake time between your server and the VPN endpoint. If the last handshake is more than 5 minutes old, the script automatically restarts the WireGuard interface to re-establish the connection. This ensures your VPN tunnel remains active and your services stay online even when your ISP changes network conditions.

Easy Install

Run this one-liner command as root to install the watchdog script:

curl -s https://getpublicip.com/scripts/wireguard-watch-install.sh | bash -s e576faaf43203ed71257c31da12b21f1b77cce4fdce655da88d3022e55a2d6f6

The Install Script

Or if you prefer to download and run the install script manually:

#!/bin/bash

set -e

# Configuration
SCRIPT_URL="https://getpublicip.com/scripts/wireguard-watch"
SCRIPT_PATH="/usr/bin/wireguard-watch"
CRON_ENTRY="*/5 * * * * /usr/bin/wireguard-watch"

# Check if SHA256 hash argument is provided
if [ -z "$1" ]; then
    echo "Usage: $0 <sha256_hash>"
    echo "Example: $0 e576faaf43203ed71257c31da12b21f1b77cce4fdce655da88d3022e55a2d6f6"
    exit 1
fi

EXPECTED_SHA256="$1"

# Check if running as root
if [ "$EUID" -ne 0 ]; then 
    echo "Please run as root"
    exit 1
fi

# Download the script
echo "Downloading wireguard-watch script..."
curl -o "$SCRIPT_PATH" "$SCRIPT_URL"

# Verify SHA256 checksum
echo "Verifying SHA256 checksum..."
ACTUAL_SHA256=$(sha256sum "$SCRIPT_PATH" | awk '{print $1}')

if [ "$ACTUAL_SHA256" != "$EXPECTED_SHA256" ]; then
    echo "ERROR: SHA256 checksum mismatch!"
    echo "Expected: $EXPECTED_SHA256"
    echo "Got:      $ACTUAL_SHA256"
    rm -f "$SCRIPT_PATH"
    exit 1
fi

echo "SHA256 checksum verified successfully."

# Make script executable
chmod +x "$SCRIPT_PATH"
echo "Made script executable."

# Check if cron entry already exists
if crontab -l 2>/dev/null | grep -q "$SCRIPT_PATH"; then
    echo "Cron entry already exists. Skipping cron setup."
else
    # Add cron entry
    (crontab -l 2>/dev/null; echo "$CRON_ENTRY") | crontab -
    echo "Added cron entry to run every 5 minutes."
fi

echo "Installation complete!"
echo "The watchdog script will run every 5 minutes."

The Watchdog Script

Copy the following script to your server and configure it to run periodically using cron or systemd timers:

#!/bin/bash

# Configuration
INTERFACE="pi0"  # This is your wireguard interface
MAX_HANDSHAKE_AGE=300  # 5 minutes in seconds

# Get the latest handshake time from wg show
handshake_line=$(wg show "$INTERFACE" latest-handshakes | head -n 1)

# Check if we got any output
if [ -z "$handshake_line" ]; then
    echo "No handshake information found for interface $INTERFACE"
    exit 1
fi

# Extract the timestamp (second field)
last_handshake=$(echo "$handshake_line" | awk '{print $2}')

# Get current time in seconds since epoch
current_time=$(date +%s)

# Calculate time since last handshake
time_diff=$((current_time - last_handshake))

echo "Interface: $INTERFACE"
echo "Last handshake: $time_diff seconds ago"

# Check if handshake is older than 5 minutes
if [ "$time_diff" -gt "$MAX_HANDSHAKE_AGE" ]; then
    echo "Handshake older than 5 minutes. Restarting WireGuard..."
    
    # Restart WireGuard
    wg-quick down "$INTERFACE"
    sleep 2
    wg-quick up "$INTERFACE"
    
    echo "WireGuard restarted successfully"
    exit 0
else
    echo "Handshake is recent. No restart needed."
    exit 0
fi

Crontab Configuration

The watchdog script needs to run periodically to check the WireGuard connection status. A crontab entry is added to automatically execute the script every 5 minutes. This ensures continuous monitoring of your VPN connection without requiring manual intervention.

The crontab entry runs the watchdog script as root, allowing it to restart the WireGuard interface if needed. The script checks the handshake time and only restarts the connection if it detects a problem, so it won't interfere with healthy connections.

If you need to manually add the crontab entry or the automatic installation didn't work, use the following crontab configuration:

*/5 * * * * /usr/bin/wireguard-watch

To add this manually, run crontab -e as root and add the line above. The cron expression */5 * * * * means the script will run every 5 minutes.

Check out our other guides

Explore Guides & Categories