Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 198 lines (152 sloc) 3.92 KB
#!/bin/bash
##
## WireGuard Monitor script
##
## Update DNS endpoints when WIREGUARD_DNS_UPDATE="yes"
##
. /etc/rc.conf
LOCKFILE="/var/lock/wireguard-monitor.lock"
PIDFILE="/var/run/wireguard-monitor.pid"
INTERFACE="${WIREGUARD_IF:-wg0}"
INTERVAL="${WIREGUARD_MONITOR_INTERVAL:-200}"
VERBOSITY="${WIREGUARD_MONITOR_VERBOSITY:-6}"
CONFIG_FILE="/etc/wireguard/$INTERFACE.conf"
INACTIVE_PEER_SECS=135
PEER_CONFIG_DATA=""
RELOAD_CONFIG=0
log()
{
local TYPE="$1" MESG="$2"
case $TYPE in
ERROR)
log2syslog "$TYPE" "$TYPE $MESG"
;;
DEBUG)
if [ "$VERBOSITY" = "9" ]; then
log2syslog "$TYPE" "$TYPE $MESG"
fi
;;
INFO)
if [ "$VERBOSITY" != "3" ]; then
log2syslog "$TYPE" "$TYPE $MESG"
fi
;;
esac
}
log2syslog()
{
local TYPE="$1" MESG="$2"
TYPE="$(echo "$TYPE" | tr '[:upper:]' '[:lower:]')"
logger -t wireguard-monitor -p "daemon.$TYPE" "$MESG"
}
idle_wait()
{
local time="$1" cnt=0
while [ -f "$PIDFILE" -a $cnt -lt $time ]; do
cnt=$((cnt+1))
sleep 1
done
}
gen_peer_config_data()
{
if [ -f "$CONFIG_FILE" ]; then
PEER_CONFIG_DATA="$(sed -n '/^\[[Pp]eer/,$ s/^[^#].*$/&/p' "$CONFIG_FILE" | sed 's/[[:space:]]//g')"
fi
}
update_dns_endpoint()
{
local pubkey="$1" endpoint="$2"
log DEBUG "Updating peer: $pubkey endpoint: $endpoint"
wg set $INTERFACE peer "$pubkey" endpoint "$endpoint"
}
match_dns_endpoint()
{
local matchpubkey="$1" pubkey="$2" endpoint="$3"
if [ "$WIREGUARD_DNS_UPDATE" != "yes" ]; then
return
fi
if [ -z "$pubkey" -o -z "$endpoint" -o "$matchpubkey" != "$pubkey" ]; then
return
fi
case ${endpoint%:*} in
\[*) ;; # IPv6 Endpoint
[0-9][0-9.][0-9.][0-9.][0-9.]*.*[0-9]) ;; # IPv4 Endpoint
*) update_dns_endpoint "$pubkey" "$endpoint" # DNS Endpoint
;;
esac
}
inactive_peer()
{
local matchpubkey="$1" publickey="" endpoint="" line IFS
unset IFS
for line in $PEER_CONFIG_DATA [Peer]; do
case $line in
[Pp]ublic[Kk]ey=*) publickey="${line#*=}" ;;
[Ee]ndpoint=*) endpoint="${line#*=}" ;;
\[[Pp]eer*) match_dns_endpoint "$matchpubkey" "$publickey" "$endpoint"
publickey=""
endpoint=""
;;
esac
done
}
monitor_wg_status()
{
local line pubkey time IFS
if [ $RELOAD_CONFIG -eq 1 ]; then
RELOAD_CONFIG=0
gen_peer_config_data
fi
IFS=$'\n'
for line in $(wg show $INTERFACE latest-handshakes); do
time="$(echo "$line" | awk '{ print $2; }')"
if [ -n "$time" ]; then
if [ $(( $(date +%s) - $time )) -gt $INACTIVE_PEER_SECS ]; then
pubkey="$(echo "$line" | awk '{ print $1; }')"
inactive_peer "$pubkey"
fi
fi
done
idle_wait $INTERVAL
}
reload_config()
{
if [ $RELOAD_CONFIG -eq 0 ]; then
log INFO "Reloading peer config data."
RELOAD_CONFIG=1
fi
}
start_monitor()
{
# Robust 'bash' method of creating/testing for a lockfile
if ! ( set -o noclobber; echo "$$" > "$LOCKFILE" ) 2>/dev/null; then
log ERROR "wireguard-monitor: already running, lockfile \"$LOCKFILE\" exists, process id: $(cat "$LOCKFILE")."
return 9
fi
# Load 'sleep' builtin if it exists
if [ -f /usr/lib/bash/sleep ]; then
enable -f /usr/lib/bash/sleep sleep
fi
trap 'reload_config' HUP
trap 'rm -f "$LOCKFILE" "$PIDFILE"; exit $?' INT TERM EXIT
echo "$BASHPID" > "$PIDFILE"
log INFO "Starting monitoring of '$INTERFACE' interface."
idle_wait 60
while [ -f "$PIDFILE" ]; do
monitor_wg_status
done
log INFO "Stopping monitoring of '$INTERFACE' interface."
rm -f "$LOCKFILE" "$PIDFILE"
trap - HUP INT TERM EXIT
return 0
}
if [ ! -f /var/lock/wireguard.lock ]; then
echo "wireguard-monitor: WireGuard VPN is not running." >&2
exit 1
fi
gen_peer_config_data
if [ -z "$PEER_CONFIG_DATA" ]; then
echo "wireguard-monitor: WireGuard VPN config not found." >&2
exit 1
fi
start_monitor >/dev/null 2>&1 &
You can’t perform that action at this time.