Had problems connecting to wg0 interface that required re-starting wg0, so I am sharing my monit implementation.
It is equivalent to re-starting/toggling the dashboard's WG.
Monit needs to start first (3 to 4 minutes) before Monit re-starts WG.
Tested under OpnSense 26.1.10
Monit Implementation
Steps
#1 Set Opnsense Monit Service setings and Service tests settings
#2 Add wg0_monit_start.sh
#3 Service -> Monit -> Status
#1
Opnsense Services Monit
Service Settings
Name: wg0_monit_start
Type: custom
Path: /usr/local/bin/bash /usr/local/opnsense/scripts/wireguard/wg0_monit_start.sh
Start: /bin/sh -c '/usr/local/sbin/pluginctl -s wireguard restart'
Tests: ZeroStatus
Service Tests Settings
Name: ZeroStatus
Condition: status == 0
Action: Start
#2
nano /usr/local/opnsense/scripts/wireguard/wg0_monit_start.sh
======
#!/bin/bash
# RC is the connection state which defaults = 1
RC=1
# Test wg0 connection state and if no packets are received it needs to be restarted with RC=0
# RC=0 uses the ZeroStatus test to re-start wg0
[[ $(netstat -i | grep -F -- " 0 - " | \
grep "VPN Instance Tunnel IP address" | wc -l) -eq "1" ]] && RC=0 && echo !connected && exit $RC \
|| echo connected && exit 1
======
chmod + /usr/local/opnsense/scripts/wireguard/wg0_monit_start.sh
#3
Program 'wg0_monit_start'
status OK
monitoring status Monitored
monitoring mode active
on reboot start
last exit value 1
last output connected
data collected Fri, 19 Jun 2026 11:49:02
====
Updated the script with an alternatuve method
====
#!/bin/bash
#Alternative
shopt -s extglob
# Test the wg0 connection state using monit ZeroStatus test
# RC =1 is the connection state which defaults the wg0 as being connected -> exit 1
# reports as 'status =1'
RC=1
# If no wg0 packets are received, it needs to be restarted with RC =0 -> exit 0
# Important: need to report 'status =0' to the opnsense monit ZeroStatus test
# which will re-start the wg0 connection
# in-line command
#[[ $(netstat -i | grep -F -- " 0 - " | grep "100.80.224.xxx" | wc -l) -eq "1" ]] \
#&& RC=0 && echo "!connected" $(date +"%Y-%m-%d %H:%M:%S") && exit $RC \
#|| echo "connected" $(date +"%Y-%m-%d %H:%M:%S") && exit $RC
RC=`netstat -i | grep -F -- " 0 - " | grep "100.80.224.xxx" | wc -l`
#echo $RC
[$RC -eq 1 ] && RC="0" || RC="1"
case $RC in
0) printf "wg0 !connected $(date +"%Y-%m-%d %H:%M:%S") \n" && exit 0;;
1) printf "wg0 connected $(date +"%Y-%m-%d %H:%M:%S") \n" && exit 1;;
*) printf "Issue with wg0_monit_start.sh \n";;
esac
====
Cleaned up #2.
nano /usr/local/opnsense/scripts/wireguard/wg0_monit_start.sh
#!/bin/bash
# Test the wg0 connection state and if no packets are received ( a match )
# then wg0 needs to be restarted with exit 0
# which uses ZeroStatus test to re-start wg0
#==
# pulls vpn end-tunnel address from ifconfig wg0
ip_addr=$(ifconfig wg0 | awk '/inet / {print $2}')
read -ra fields <<< "$(netstat -i | grep -E '\swg0\s')"
#echo "rx_packets= ${fields[4]}"
# Test wg0 column 5 or fields[4]
# add echo protection 070726
[[ -n "${fields[4]}" && "${fields[4]}" -eq 0 ]] \
&& { echo "_wg0 !connected $(date +"%Y-%m-%d %H:%M:%S")"; exit 0; } \
|| { echo "_wg0 connected to $ip_addr $(date +"%Y-%m-%d %H:%M:%S")"; exit 1; }
#==
# equals a '0' -> match -> exit 0 -> re-starts wg0
# not equal condition -> no match -> do not restart wg0
# Verification
# netstat -i | grep wg0
# wg0 1420 <Link#9> wg0 0 0 0 4528 0 0
# wg0 - xxx.xxx.xxx.xxx/32 xxx.xxx.xxx.xxx 0 - - -
Program 'wg0_monit_start'
status OK
monitoring status Monitored
monitoring mode active
on reboot start
last exit value 1
last output _wg0 connected to xxx.xxx.xxx.xxx 2026-07-09 07:55:54
data collected Thu, 09 Jul 2026 07:57:54
Updated with a green color for a wg0 connection
#nano /usr/local/opnsense/scripts/wireguard/wg0_monit_start.sh
#!/usr/local/bin/bash
# Test the wg0 connection state and if no packets are received ( a match )
# then wg0 needs to be restarted with exit 0
# which uses ZeroStatus test to re-start wg0
#==
# pulls the vpn end-tunnel address from wg0.conf
# ip_addr=$(grep -E '^\s*#?\s*Address' /usr/local/etc/wireguard/wg0.conf \
# | awk -F'[ /]+' '{print $4}')
# colors
BOLD_RED='\033[1;31m'
BOLD_GREEN='\033[1;32m'
NC='\033[0m' # No Color (resets formatting)
# wg interface
iface="wg0"
# time and date stamp
ts=$(date +"%Y-%m-%d %H:%M:%S")
# pulls the vpn end-tunnel address from ifconfig wg0
ip_addr=$(ifconfig $iface | awk '/inet / {print $2}')
# test wg0 rx_packets received in column 5 or fields[4]
read -ra fields <<< "$(netstat -i | grep -E "\s${iface}\s")"
#echo "rx_packets= ${fields[4]}"
# 071826
# check for non-empty string and a zero packet size
# add echo protection
[[ -n "${fields[4]}" && "${fields[4]}" -eq 0 ]] \
&& { echo "$_wg0 !connected $ts"; exit 0; } \
|| { echo -e "_wg0 connected to $BOLD_GREEN$ip_addr $ts$NC"; exit 1; }
#==
# equals a '0' -> match -> exit 0 -> re-starts wg0
# not equal condition -> no match -> do not restart wg0
# Verification
# netstat -i | grep wg0
# wg0 1420 <Link#9> wg0 0 0 0 4528 0 0
# wg0 - xxx.xxx.xxx.xxx/32 xxx.xxx.xxx.xxx 0 - - -
# Program 'wg0_monit_start'
# Status OK
# monitoring status Monitored
# monitoring mode active
# on reboot start
# last exit value 1
# last output _wg0 connected to xxx.xxx.xxx.xxx 2026-07-09 07:55:54