99 lines
2.3 KiB
Bash
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
|