[Solved] Wireguard Interface killed every 10 min

HI,
I used Wireguard VPN from a year. But since i updated from OpenWrt 19 to OpenWrt 21.02.1
My Wireguard interface (wg0) is link down every 10 min.

I check and found this log :

Tue Mar  1 11:40:00 2022 cron.err crond[2679]: USER root pid 13024 cmd /usr/share/wginstaller/wg.sh cleanup_wginterfaces
Tue Mar  1 11:40:00 2022 daemon.notice netifd: Network device 'wg0' link is down

I check the script :

root@OpenWrt:/usr/share/wginstaller# cat wg.sh 
#!/bin/sh

next_port () {
	local port_start=$1
	local port_end=$2

	ports=$(wg show all listen-port | awk '{print $2}')

	for i in $(seq "$port_start" "$port_end"); do
		if ! echo "$ports" | grep -q "$i"; then
			echo "$i"
			return
		fi
	done
}

cleanup_wginterfaces() {
    check_wg_neighbors
}

delete_wg_interface() {
    ip link del dev "$1"
    [ -f "/tmp/run/wgserver/$1.key" ] && rm "/tmp/run/wgserver/$1.key"
    [ -f "/tmp/run/wgserver/$1.pub" ] && rm "/tmp/run/wgserver/$1.pub"
}

check_wg_neighbors() {
    wg_interfaces=$(ip link | grep wg | awk '{print $2}' | sed 's/://')
    for phy in $wg_interfaces; do
        linklocal=$(ip -6 addr list dev "$phy" | grep "scope link" | awk '{print $2}' | sed 's/\/64//') 2>/dev/null
        ips=$(ping ff02::1%"$phy" -w5 -W5 -c10 | awk '/from/{print($4)}' | sed 's/.$//') 2>/dev/null
        delete=1
        for ip in $ips; do
            if [ "$ip" != "$linklocal" ] && [ "$(owipcalc $ip linklocal)" -eq 1 ]; then
                delete=0
                break
            fi
        done
        if [ $delete -eq 1 ]; then
            delete_wg_interface "$phy"
        fi
    done
}

case $1 in
next_port|\
cleanup_wginterfaces)
    "$@"
    exit
    ;;
esac

I run some command manually for check

root@OpenWrt:~# ip link | grep wg | awk '{print $2}' | sed 's/://'
wg0
root@OpenWrt:~# ip -6 addr list dev "wg0"
root@OpenWrt:~# ip  addr list dev "wg0"
17: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN qlen 1000
    link/[65534] 
    inet 10.14.0.1/24 brd 10.14.0.255 scope global wg0
       valid_lft forever preferred_lft forever
root@OpenWrt:~# ping ff02::1%"wg0" -w5 -W5 -c10 | awk '/from/{print($4)}' | sed 's/.$//'
ping: sendto: Permission denied

So, that I understand is the script check by IPv6 if interface is OK but as my interface is only IPv4 it kill it ...

I have comment the line delete_wg_interface "$phy" for fix temporaly the issue. But do you have a better solution ?

Thanks

Yes, this sounds like an oversight. Our resident @PolynomialDivision is the author of the package and probably can tell more about it and why it seemingly exclusively relies on an IPv6 check.

That being said, I believe you shouldn't be using wg-installer at all. And please someone CMIIW.

From what I see, wg-installer's use case is decidedly not for one singular user to "install WireGuard", as such its package name may be a bit unfortunate. Rather it seems to be used to create WireGuard tunnels and give out credentials to multiple users on the fly. Documentation is very sparse (to not to say: nonexistent), it seems to fill the Freifunk community's specific need to provide WireGuard tunnels for the anonymous public to use. The periodic check then seems to be a "cleanup" procedure to remove the tunnels once they are not used anymore. That cleanup makes sense in this scenario, in regular use cases like yours it may be counterproductive.

However, it is not needed (or at least a much too big hammer for a much too small nail) it to create one tunnel, especially if you are a "client" on a fixed router. And it is certainly not needed to maintain that tunnel.

2 Likes

Correct, Wiregard configs are native in /etc/config/network

Yes, this is exactly the use case. The link-local ping is to ensure I have connectivity on the interface. Sadly, I was not able to use "last handshake", since wireguard tunnels can be inserted and no connection is done. That is why I use link-local ping. If you still want to use it, just remove the cronjob, or simply add link-local connectivity.

In the forum is a great description of how to install wireguard tunnels:

Thank you for confirming my conjecture. Given that the package is named "wg-install" (which, for better or worse, will probably stick now) and, as demonstrated here, leads some users to think that it is used to "install WireGuard" I feel at least the package description would benefit from a little more detail on what it is for ... and especially what it isn't.

3 Likes

I'm clearly in this situation, a better description and a more explicit name should solve this situation.

So i have remove the package and it's OK for me. Thanks for the support and the speed of answer.

2 Likes

(Slightly going off-tangent here.)

wireguard-watchdog.sh gives a few good hints: wg show [iface] latest-handshakes shows either the latest handshake or 0 when a handshake was never made. It needs persistent-keepalive turned on, maybe you missed that?

That should allow you to purge connections that didn't have a handshake in the last x seconds while leaving unused connections alone. And to expire never-initialized connections neither ping nor the latest handshake will serve as a good indicator. You could put a "created_at" option into UCI with the peer with the timestamp of the creation, and if latest-handshake was 0 calculate an expiry time against that value.

Checking for unused tunnels at regular fixed intervals whether they are active in that exact moment may lead to unintended side effects: That interval might hit directly after the tunnel was inserted before the user had any time to set up his end, or if the tunnel is in use but temporarily down. The default(?) 10 minutes interval sets the bar pretty low for that.

2 Likes

If your problem is solved, please consider marking this topic as [Solved]. See How to mark a topic as [Solved] for a short how-to.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.