Created
September 4, 2022 06:51
-
-
Save 0x5e/351d438dfd9c1f621a37b169fa7e1cb8 to your computer and use it in GitHub Desktop.
openwrt-wireguard-watchdog
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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