Some of my OpenWRT routers depend on using a rather unstable wireless connection to reach my OpenVPN server. Although they reconnect very reliably for the most part, sometimes something goes wrong. This is where the watchdog script comes in. It pings the WLAN access point and VPN server every minute. If either one doesn’t respond for a few (configurable) minutes, the watchdog will restart the service. Here’s how it works:


Obsolete!

A new and improved watchping script is available, click here!

Configuration

config watchping 'wifi'
	option enabled '1'
	option host 'wifi.accesspoint'
	option timeout '3'

config watchping 'openvpn'
	option enabled '1'
	option host 'my.vpn.server.de'
	option timeout '5'

First create a new configuration file /etc/config/watchping. This tells the watchdog which hosts to ping and configures the timeout for each service.

The scripts

Create the /usr/lib/watchping folder and upload these scripts:

#!/bin/sh 
#
# Pings a remote host and restarts WiFi/OpenVPN if the connection is down
# Requires "fping" -> opkg install fping
#
# Copyright (C) 2020 luani.de

. /lib/functions.sh

# check prerequisites
if [ ! -x "$(command -v fping)" ]; then
  echo 'watchping error: fping is not installed, exiting' >&2
  exit 1
fi

# read configuration
config_load watchping
config_get_bool check_wifi wifi enabled "false"
config_get_bool check_openvpn openvpn enabled "false"

if [ "$check_wifi" -eq "1" ]; then
	config_get wifi_host wifi host "localhost"
	config_get wifi_timeout wifi timeout "5"
	if [ $wifi_timeout -le 0 ]; then
		wifi_timeout=5
	fi

	wifi_failcount=0
	logger -t "watchping" "start wifi watchdog: host '$wifi_host', timeout $wifi_timeout min"
fi
if [ "$check_openvpn" -eq "1" ]; then
	config_get openvpn_host openvpn host "localhost"
	config_get openvpn_timeout openvpn timeout "5"
	if [ $openvpn_timeout -le 0 ]; then
		openvpn_timeout=5
	fi

	openvpn_failcount=0
	logger -t "watchping" "start openvpn watchdog: host '$openvpn_host', timeout $openvpn_timeout min"
fi

# check loop
while sleep 60; do
	if [ "$check_wifi" -eq "1" ]; then
		fping --ipv4 --quiet --count 1 --random ${wifi_host} &> /dev/null
		if [ $? -ne 0 ]; then let "wifi_failcount++"; else wifi_failcount=0; fi

		if [ $wifi_failcount -ge $wifi_timeout ]; then
			wifi_failcount=0
			logger -t "watchping" "wifi ($wifi_host) is down for $wifi_timeout min, restarting!"

			# restart service
			# "If wifi is already up when you run "wifi" with no parameters, the wifi system will be stopped and restarted."
			/sbin/wifi
		fi
	fi
	if [ "$check_openvpn" -eq "1" ]; then
		fping --ipv4 --quiet --count 1 --random ${openvpn_host} &> /dev/null
		if [ $? -ne 0 ]; then let "openvpn_failcount++"; else openvpn_failcount=0; fi

		if [ $openvpn_failcount -ge $openvpn_timeout ]; then
			openvpn_failcount=0
			logger -t "watchping" "openvpn ($openvpn_host) is down for $openvpn_timeout min, restarting!"

			# restart service
			/etc/init.d/openvpn restart
		fi
	fi
done

exit 0
#!/bin/sh /etc/rc.common
# 
# start watchdog
#
# https://openwrt.org/docs/guide-developer/procd-init-script-example
# Copyright (C) 2020 luani.de

# Init sequence
START=99
STOP=10

# PROCD
USE_PROCD=1

start_service() {
	procd_open_instance watchping
	procd_set_param command /bin/sh "/usr/lib/watchping/watchping.sh"

	procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}

	procd_set_param stdout 1 # forward stdout of the command to logd
	procd_set_param stderr 1 # same for stderr

	procd_set_param pidfile /var/run/watchping.pid

	procd_close_instance
}

stop_service() {
	logger -t "watchping" "watchdog stopped!"
}

service_triggers()
{
	procd_add_reload_trigger "watchping"
}

reload_service()
{
	stop
	start
}

Final touches

The watchdog script requires „fping“ to be installed on the router:

# install dependencies
opkg update
opkg install fping

# make executable
chmod +x /usr/lib/watchping/watchping.sh
chmod +x /etc/init.d/watchping

# enable & start service
# you can also do this from LuCI, system -> startup
/etc/init.d/watchping enable
/etc/init.d/watchping start

Check your system log and verify the watchdog started correctly:

user.notice watchping: start wifi watchdog: host 'wifi.accesspoint', timeout 3 min
user.notice watchping: start openvpn watchdog: host 'my.vpn.server.de', timeout 5 min

Tested with OpenWRT 19.07

6 Comments

  1. Is it possible to watch an usb device, and reset it with „usbreset“ if it has connection problems?

    or maybe the better version:
    a custom watchdog provider, where I could check for an Exit code, and if it doesn’t match run an other command

    Christian
  2. Pingback: OpenWRT: Improved Network/OpenVPN/WiFi watchdog – LUANI

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.