lixonet-ee/wireguard/check_routes.sh
2022-12-21 22:09:38 -07:00

99 lines
2.3 KiB
Bash

#!/bin/bash
INTERFACE=wg0
METRIC=31
TIMEOUT=180
INTERVAL=2
readarray -t ROUTES < <(echo "$WG_ROUTES" | tr , '\n')
netenclose () {
local o1 o2 o3 o4 p1 p2 p3 p4 m1 m2 ip1 ip2 min
IFS=./ read o1 o2 o3 o4 m1 <<< "$1"
IFS=./ read p1 p2 p3 p4 m2 <<< "$2"
((min = m1 > m2 ? m2 : m1))
ip1=$(((o1 << 24) + (o2 << 16) + (o3 << 8) + o4))
ip2=$(((p1 << 24) + (p2 << 16) + (p3 << 8) + p4))
if (( (ip1 >> (32 - min)) == (ip2 >> (32 - min)) )); then
if ((m1 > m2)); then
echo "$2"
else
echo "$1"
fi
else
echo "0.0.0.0/0"
fi
}
while true
do
current_time=`date +%s`
readarray -t peers < <(wg show wg0 dump)
for peer in "${peers[@]}"
do
args=($(echo $peer))
public_key=${args[0]}
private_key=${args[1]}
endpoint=${args[2]}
route_list=${args[3]}
handshake=${args[4]}
bytes_recv=${args[5]}
bytes_sent=${args[6]}
keep_alive=${args[7]}
# If it's a remote peer, the private key should be '(none)'
# Otherwise, it's us
if [ "$private_key" != "(none)" ]; then
continue
fi
# The following checks ensure this peer is reachable and set the 'up'
# flag accordingly
if [ "$endpoint" == "(none)" ]; then
up=false
elif [ "$handshake" == "0" ]; then
up=false
elif [ "$bytes_recv" == "0" ]; then
# A peer we have never received data from is not available
up=false
else
delta="$((current_time - handshake))"
if [ $delta -gt $TIMEOUT ]; then
up=false
else
up=true
fi
fi
readarray -t routes < <(echo "$route_list" | tr , '\n')
for route in "${routes[@]}"
do
in_network=false
for ROUTE in "${ROUTES[@]}"
do
parent_route=`netenclose $route $ROUTE`
if [ "$parent_route" == "$ROUTE" ]; then
in_network=true
break
fi
done
# Only manipulate routes that are in the global WG_ROUTES variable
if [ $in_network == false ]; then
continue
fi
if [ "$up" == "true" ]; then
ip route add $route dev $INTERFACE metric $METRIC 2> /dev/null && echo "Added route $route from peer $public_key ($endpoint)"
else
ip route delete $route dev $INTERFACE 2> /dev/null && echo "Removed route $route from peer $public_key"
fi
done
done
sleep $INTERVAL
done