diff --git a/wireguard/check_routes.sh b/wireguard/check_routes.sh new file mode 100644 index 0000000..46daa4f --- /dev/null +++ b/wireguard/check_routes.sh @@ -0,0 +1,95 @@ +#!/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 + 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