WireGuard Keepalive

WireGuard Keepalive 1.0.0

Keep your WireGuard VPN connection alive in a jail

:frown: Sometimes the VPN service provider might face an issue on their end.
:frown: Sometimes your connection goes down for whatever reason.
:frown: Sometimes it's been a while since the last successful handshake.

This script, combined with a cron job that runs every 10 minutes in your jail, will automatically reactivate your WireGuard connection if something goes wrong in your absence. It should work with any WireGuard VPN provider that can be natively used in FreeBSD or Linux, such as Mullvad, Proton, Azire, Air, etc.

Prequisites:
  1. You have a working WireGuard VPN with valid config files
  2. You are only using a single active wireguard connection (this does not work with multiple simultaneous wireguard connections
  3. You have configured and enabled the wireguard service and desired interface in /etc/rc.conf
  4. You create a cron job under the root user (see example in the comments)
Everything is done in the jail. Nothing is done on the TrueNAS host.

Contents of /root/.bin/wg-keepalive.sh
Code:
#!/bin/sh

# WireGuard Keepalive, FreeBSD Jail Edition
# wg-keepalive.sh
# Version: 1.0.0
# Checks if the interface is inactive or hasn't had a successful handshake since 10 minutes
# Restarts the wireguard service if either of the above are true

# DISCLAIMER: This assumes only a *single* active wireguard connection
# It does not work for *multiple* active connections

# Events are logged under /var/log/wg-keepalive-events.log
# This script should be placed under /root/.bin/wg-keepalive.sh

# You *must* have your WireGuard VPN configured
# You *must* have the wireguard service and desired tunnel enabled in /etc/rc.conf

# A complimentary cron job must exist for the root user
# Example cron job entry that checks every 10 minutes:
# */10 * * * * /root/.bin/wg-keepalive.sh



WGINTERFACE=$(wg)

# Check if wireguard interface is active
if [ -z "$WGINTERFACE" ]
then
        # Activate wireguard interface and log it
        service wireguard restart
        echo -e "`date +%Y-%m-%d-%H-%M`: Restarting wireguard service. Interface was not active.\n" >> /var/log/wg-keepalive-events.log
        exit 1
fi

# Compare the current time (in seconds) to the latest handshake
LATESTHANDSHAKE=$(echo "`date +%s` - `wg show all latest-handshakes | cut -f3`" | bc)

# Check if latest handshake is longer than 10 minutes (600 seconds)
if [ "$LATESTHANDSHAKE" -gt 600 ]
then
        # If longer than 10 minutes, restart the wireguard service and log it
        echo -e "`date +%Y-%m-%d-%H-%M`: Restarting wireguard service. No handshake since $LATESTHANDSHAKE seconds ago.\n" >> /var/log/wg-keepalive-events.log
        service wireguard restart
        exit 1
else
        # If shorter than 10 minutes, do nothing and exit
        exit 0
fi


This is a sample of what the logfile looks like after logging some events:
Code:
2023-11-08-04-00: Restarting wireguard service. No handshake since 766 seconds ago.

2023-11-08-05-00: Restarting wireguard service. Interface was not active.

2023-11-08-06-00: Restarting wireguard service. Interface was not active.



Currently tested and used on TrueNAS Core 13.0-U5.3 in a FreeBSD 13.2-RELEASE-p5 jail, as of November 19, 2023.
Author
winnielinnie
Downloads
152
Views
1,280
First release
Last update
Rating
0.00 star(s) 0 ratings
Top