Skip to content

Instantly share code, notes, and snippets.

@0x5e
Created September 4, 2022 06:51
Show Gist options
  • Save 0x5e/351d438dfd9c1f621a37b169fa7e1cb8 to your computer and use it in GitHub Desktop.
Save 0x5e/351d438dfd9c1f621a37b169fa7e1cb8 to your computer and use it in GitHub Desktop.
openwrt-wireguard-watchdog
#!/bin/sh
# Description:
# A WireGuard watchdog for OpenWrt.
# If peer has an endpoint_host, disconnected 2 minutes ago, and remote ip has changed, we will trigger an force reconnect for this interface.
#
# Usage:
# Add "*/10 * * * * sh /path/to/openwrt-wireguard-watchdog.sh" in crontab.
#
# Dependency: busybox, resolveip, uci, wireguard-tools
. /lib/functions.sh
ifaces=""
config_cb() {
local type="$1"
local name="$2"
if [[ "$type" =~ ^wireguard_.* ]]; then
local iface="${type/wireguard_/}"
# local public_key
# local endpoint_host
# config_get public_key "$name" public_key
# config_get endpoint_host "$name" endpoint_host
local public_key=`uci get network.$name.public_key 2> /dev/null`
local endpoint_host=`uci get network.$name.endpoint_host 2> /dev/null`
if [[ -z "$endpoint_host" ]]; then
# endpoint_host is empty
[[ "$DEBUG" != 0 ]] && echo "[openwrt-wg-watchdog] iface = $iface, name = $name, public_key = $public_key, endpoint_host is empty, skip."
return
fi
latest_handshake=`wg show $iface latest-handshakes | grep "$public_key" | sed -E "s/(.*)\s(.*)/\2/g"`
now=`date '+%s'`
delta=$((now - latest_handshake))
if [[ $delta -lt 140 ]]; then
# latest_handshake in 120s
[[ "$DEBUG" != 0 ]] && echo "[openwrt-wg-watchdog] iface = $iface, endpoint_host = $endpoint_host, latest_handshake < 120s, skip."
return
fi
endpoint_ip=`wg show $iface endpoints | grep "$public_key" | sed -E "s/(.*)\s(.*):(.*)/\2/g" | sed -E "s/[][]//g"`
if (resolveip $endpoint_host | grep $endpoint_ip &> /dev/null); then
# endpoint_ip has not changed
[[ "$DEBUG" != 0 ]] && echo "[openwrt-wg-watchdog] iface = $iface, endpoint_host = $endpoint_host, endpoint_ip = $endpoint_ip, latest_handshake > 120s, ip not changed, skip."
return
fi
# mark $iface to be update after config load complete
echo "[openwrt-wg-watchdog] iface = $iface, endpoint_host = $endpoint_host, endpoint_ip = $endpoint_ip, latest_handshake > 120s, ip changed to `resolveip $endpoint_host | head -1`, force reconnect..."
ifaces="$ifaces $iface"
elif [[ -z "$type" ]]; then
ifaces=`echo $ifaces | sed -E "s/\s+/\n/g" | uniq`
echo $ifaces |
while IFS= read -r iface; do
if [[ -z "$iface" ]]; then
continue
fi
echo "[openwrt-wg-watchdog] ifconfig $iface down && ifconfig $iface up"
ifconfig $iface down && ifconfig $iface up
done
fi
}
config_load network
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment