WireGuard on OpenWRT based GL.iNET: some notes on the `wireguard_watchdog` script
Posted by jpluimers on 2026/01/15
On OpenWRT GL.iNET based devices, the WireGuard client does not restart upon reboot, even if it was started before rebooting.
Hopefully the /usr/bin/wireguard_watchdog script will help with this as others indicates it should.
My first try was no succes, but since it is supposed to run from cron it does no output. The script on GL-SFT1200 firmware version 3.215, script /usr/bin/wireguard_watchdog is different from the one in the OpenWRT repository, so it needs some investigation.
Some links for checking this out:
- [Wayback/Archive] openwrt/wireguard_watchdog at master · openwrt/openwrt of which the first commit describes to to schedule it:
- [Wayback/Archive] wireguard-tools: add wireguard_watchdog script · openwrt/openwrt@e3faff9
wireguard-tools: add wireguard_watchdog scriptThis watchdog script tries to reresolve and reconnect to inactive wireguard peers. Use it for peers with a frequently changing dynamic IP. persistent_keepalive must be set, recommended value is 25 seconds. Run this script from cron every minute: echo '* * * * * /usr/bin/wireguard_watchdog' >> /etc/crontabs/root Signed-off-by: Aleksandr V. Piskunov <aleksandr.v.piskunov@gmail.com>
Via [Wayback/Archive] Wireguard problem with resolving peer – Installing and Using OpenWrt – OpenWrt Forum
History in two parts as the file got moved around:
- [Wayback/Archive] History for package/network/services/wireguard/files/wireguard_watchdog – openwrt/openwrt
- [Wayback/Archive] History for package/network/utils/wireguard-tools/files/wireguard_watchdog – openwrt/openwrt
Via [Wayback/Archive] How to install wireguard_watchdog on OpenWRT – TechOverflow
- [Wayback/Archive] wireguard-tools: add wireguard_watchdog script · openwrt/openwrt@e3faff9
- [Wayback/Archive] GL-SFT1200 firmware version 3.215, script `/usr/bin/wireguard_watchdog`
- [Wayback/Archive] List of current feature requests 2022 – Product Discussion – GL.iNet
I don’t know if this is a feature request or a bug report, but addressing the current problem with Wireguard and Dynamic DNS should be high priority. It’s the only reason I bought this device. In short, wireguard connections fail when the target’s IP address changes – they are not reresolved. Due to GL-I.net 1’s custom way of handling this, the including
wireguard_watchdogscript fails.-> [Wayback/Archive] Issue with Wireguard client and Dynamic DNS – Technical Support – GL.iNet
- [Wayback/Archive] Improvement to wireguard_watchdog script? – Installing and Using OpenWrt / Network and Wireless Configuration – OpenWrt Forum
- [Wayback/Archive] **no reconnect wireguard client** – Technical Support – GL.iNet
- [Wayback/Archive] Restart WireGuard via cli – Installing and Using OpenWrt / Network and Wireless Configuration – OpenWrt Forum
- [Wayback/Archive] OpenWRT as a wireguard client – Roo’s View
My ‘home’ site had some sort of network outage – the IP didn’t change, but the main gateway needed to be reboot. Either the outage, or the reboot resulted in the wireguard connection being broken.
Using the wireguard_watchdog script that is part of the OpenWRT wireguard package seems like the right fix here. It’ll also help when/if my home IP changes.
forum.openwrt.org/t/wireguard-problem-with-resolving-peer/40830/3
forum.openwrt.org/t/wireguard-connection-not-being-restored/62452
But in this case – the state is correctly detected (that wireguard needs a kick) but the attempt to use “wg set wginterface peer …” isn’t doing the trick
Based on forum.openwrt.org/t/restart-wireguard-via-cli/51935/10 it seems adding
ifdown wginterface
ifup wginterface
helped kick things and I’m good to go.
Queries:
- [Wayback/Archive] “wireguard_watchdog” gl.inet – Google Search
- [Wayback/Archive] “wireguard_watchdog” – Google Search
–jeroen
[Wayback/Archive] GL-SFT1200 firmware version 3.215, script `/usr/bin/wireguard_watchdog`
This file contains hidden or 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 | |
| # SPDX-License-Identifier: GPL-2.0 | |
| # | |
| # Copyright (C) 2018 Aleksandr V. Piskunov <aleksandr.v.piskunov@gmail.com>. | |
| # Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. | |
| # | |
| # This watchdog script tries to re-resolve hostnames for inactive WireGuard peers. | |
| # Use it for peers with a frequently changing dynamic IP. | |
| # persistent_keepalive must be set, recommended value is 25 seconds. | |
| # | |
| # Run this script from cron every minute: | |
| # echo '* * * * * /usr/bin/wireguard_watchdog' >> /etc/crontabs/root | |
| . /lib/functions.sh | |
| check_peer_activity() { | |
| local cfg=$1 | |
| local iface=$2 | |
| local public_key | |
| local endpoint_host | |
| local endpoint_port | |
| local persistent_keepalive | |
| local last_handshake | |
| local idle_seconds | |
| config_get public_key "${cfg}" "public_key" | |
| config_get endpoint_host "${cfg}" "endpoint_host" | |
| config_get endpoint_port "${cfg}" "endpoint_port" | |
| persistent_keepalive=`wg show ${iface} persistent-keepalive | grep ${public_key} | awk '{print $2}'` | |
| # only process peers with endpoints and keepalive set | |
| [ -z ${endpoint_host} ] && return 0; | |
| [ -z ${persistent_keepalive} -o ${persistent_keepalive} = "off" ] && return 0; | |
| # skip IP addresses | |
| # check taken from packages/net/ddns-scripts/files/dynamic_dns_functions.sh | |
| local IPV4_REGEX="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" | |
| local IPV6_REGEX="\(\([0-9A-Fa-f]\{1,4\}:\)\{1,\}\)\(\([0-9A-Fa-f]\{1,4\}\)\{0,1\}\)\(\(:[0-9A-Fa-f]\{1,4\}\)\{1,\}\)" | |
| local IPV4=$(echo ${endpoint_host} | grep -m 1 -o "$IPV4_REGEX$") # do not detect ip in 0.0.0.0.example.com | |
| local IPV6=$(echo ${endpoint_host} | grep -m 1 -o "$IPV6_REGEX") | |
| [ -n "${IPV4}" -o -n "${IPV6}" ] && return 0; | |
| # re-resolve endpoint hostname if not responding for too long | |
| last_handshake=`wg show ${iface} latest-handshakes | grep ${public_key} | awk '{print $2}'` | |
| [ -z ${last_handshake} ] && return 0; | |
| idle_seconds=$((`date +%s`-${last_handshake})) | |
| [ ${idle_seconds} -lt 150 ] && return 0; | |
| logger -t "wireguard_monitor" "${iface} endpoint ${endpoint_host}:${endpoint_port} is not responding for ${idle_seconds} seconds, trying to re-resolve hostname" | |
| wg set ${iface} peer ${public_key} endpoint "${endpoint_host}:${endpoint_port}" | |
| } | |
| # query ubus for all active wireguard interfaces | |
| wg_ifaces=`ubus -S call network.interface dump | jsonfilter -e '@.interface[@.up=true]' | jsonfilter -a -e '@[@.proto="wireguard"].interface' | tr "\n" " "` | |
| # check every peer in every active wireguard interface | |
| config_load network | |
| for iface in $wg_ifaces; do | |
| config_foreach check_peer_activity "wireguard_${iface}" "${iface}" | |
| done |






Leave a comment