How to solve the problem that wireguard does not automatically reconnect under openwrt

Record the processing ideas for not automatically reconnecting WireGuard after disconnection in OpenWrt, including practical configuration methods in interface restart, timing detection and network recovery scenarios.

How to solve the problem that wireguard does not automatically reconnect under openwrt

In the past two days, I have been struggling with the Wireguard interconnection under OpenWrt, and I discovered a problem after using it for a day. It was originally connected using dynamic DNS, and the IP will be automatically changed after 48 hours. At this time, Wireguard will not automatically reconnect, and it needs to be connected manually to normalize.

Use the following script

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/bin/sh

if ! ping -c 3 对方wgIP 3 > /dev/null 2>&1 ;then

echo "The Wireguard is down! Now try restarting wg0!\n" >> ./ddns-wg0.log

ifdown wg0 #wg0是你的wg接口名称
sleep 3
ifup wg0
fi

Use the script that comes with openwrt

The script is located at /usr/bin/wireguard_watchdog

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
. /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}'):1/128 Scope:Host

  # 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,\}\)"80:b91d/128 Scope:Link
  local IPV4=$(echo ${endpoint_host} | grep -m 1 -o "$IPV4_REGEX$")    # do not detect ip in 0.0.0.0.example.comrors:0 dropped:3224 overruns:0 frame:0
  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}')6 addr: fe80::ded8:7cff:fe40:7c82/64 Scope:Link
  [ -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}"00  
}

# 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

Add the above script to crontab

You can use any of the above scripts

Add via interface

  1. Open System –> Scheduled Tasks
  2. Enter the following content and save
1
   * * * * * /usr/bin/wireguard_watchdog

Add via command line

  1. ssh to openwrt
  2. crontab -e
  3. Add * * * * * /usr/bin/wireguard_watchdog
  4. Save
记录并分享
Built with Hugo
Theme Stack designed by Jimmy