#!/bin/sh
# VPNMON-R3 v1.8.2 (VPNMON-R3.SH) is an all-in-one script that is optimized to maintain multiple VPN connections and is
# able to provide for the capabilities to randomly reconnect using a specified server list containing the servers of your
# choice. Special care has been taken to ensure that only the VPN connections you want to have monitored are tended to.
# This script will check the health of up to 5 VPN connections on a regular interval to see if monitored VPN conenctions
# are connected, and sends a ping to a host of your choice through each active connection. If it finds that a connection
# has been lost, it will execute a series of commands that will kill that single VPN client, and randomly picks one of
# your specified servers to reconnect to for each VPN client.
# Last Modified: 2025-Nov-16
##########################################################################################
#Preferred standard router binaries path
export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH"
#Static Variables - please do not change
version="1.8.2" # Version tracker
beta=0 # Beta switch
screenshotmode=0 # Switch to present bogus info for screenshots
apppath="/jffs/scripts/vpnmon-r3.sh" # Static path to the app
logfile="/jffs/addons/vpnmon-r3.d/vpnmon-r3.log" # Static path to the log
dlverpath="/jffs/addons/vpnmon-r3.d/version.txt" # Static path to the version file
config="/jffs/addons/vpnmon-r3.d/vpnmon-r3.cfg" # Static path to the config file
lockfile="/jffs/addons/vpnmon-r3.d/resetlock.txt" # Static path to the reset lock file
vr3emails="/jffs/addons/vpnmon-r3.d/vr3emails.txt" # Static path to email rate limit file
availableslots="1 2 3 4 5" # Available slots tracker
logsize=2000 # Log file size in rows
timerloop=60 # Timer loop in sec
recover=3 # Number of loops to allow for connection recovery
schedule=0 # Scheduler enable y/n
schedulehrs=1 # Scheduler hours
schedulemin=0 # Scheduler mins
autostart=0 # Auto start on router reboot y/n
unboundclient=0 # Unbound bound to VPN client slot#
unboundwgclient=0 # Unbound bound to WG client slot#
unboundshowip=0 # Show expanded Unbound VPN IP on UI
ResolverTimer=1 # Timer to give DNS resolver time to settle
vpnping=0 # Tracking VPN Tunnel Pings
refreshserverlists=0 # Tracking Automated Custom VPN Server List Reset
monitorwan=0 # Tracking WAN/Dual WAN Monitoring
useovpn=1 # Tracking OVPN Display/Monitoring
usewg=1 # Tracking WG Display/Monitoring
lockactive=0 # Check for active locks
bypassscreentimer=0 # Check to see if screen timer can be bypassed
pingreset=500 # Maximum ping in ms before reset
updateskynet=0 # Check for VPN IP whitelisting in Skynet
amtmemailsuccess=0 # AMTM Email Success Message Option
amtmemailfailure=0 # AMTM Email Failure Message Option
rstspdmerlin=0 # Reset spdMerlin Interfaces Option
timeoutcmd="" # For "timeout" cmd for "nvram" calls
timeoutsec="" # For "timeout" cmd for "nvram" calls
timeoutlng="" # For "timeout" cmd for "nvram" calls
hideoptions=1 # Hide/Show menu options flag
ratelimit=0 # Rate limiting number of emails/houre
vrcnt=0 # Counter for VPN connection recovery
wrcnt=0 # Counter for WG connection recovery
problemvpnslot=0 # Temporary holder for problem VPN slot
problemwgslot=0 # Temporary holder for problem WG slot
selectionmethod=0 # 0=Random vs 1=sequential slot selection
lowutilspd=100 # Upper limit of Low / Lower Limit of Med RX Utilization Range
medutilspd=250 # Upper Limit of Med / Lower Limit of High RX Utilization Range
lowutilspdup=15 # Upper limit of Low / Lower Limit of Med TX Utilization Range
medutilspdup=25 # Upper Limit of Med / Lower Limit of High TX Utilization Range
bwdisp=1 # Display value for bandwidth/throughput - 1=Average, 2=Total
##-------------------------------------##
## Added by Martinski W. [2024-Oct-05] ##
##-------------------------------------##
readonly PING_HOST_Deflt="8.8.8.8"
readonly IPv4octet_RegEx="([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"
readonly IPv4addrs_RegEx="(${IPv4octet_RegEx}\.){3}${IPv4octet_RegEx}"
LAN_HostName=""
prevHideOpts=X # Avoid redisplaying the menu options unnecessarily too often #
PINGHOST="$PING_HOST_Deflt" # Ping host
## Custom Email Library Notification Variables ##
readonly scriptFileName="${0##*/}"
readonly scriptFileNTag="${scriptFileName%.*}"
readonly CEM_LIB_TAG="master"
readonly CEM_LIB_URL="https://raw.githubusercontent.com/Martinski4GitHub/CustomMiscUtils/${CEM_LIB_TAG}/EMail"
readonly CUSTOM_EMAIL_LIBDir="/jffs/addons/shared-libs"
readonly CUSTOM_EMAIL_LIBName="CustomEMailFunctions.lib.sh"
readonly CUSTOM_EMAIL_LIBFile="${CUSTOM_EMAIL_LIBDir}/$CUSTOM_EMAIL_LIBName"
# Color variables
CBlack="\e[1;30m"
InvBlack="\e[1;40m"
CRed="\e[1;31m"
InvRed="\e[1;41m"
CGreen="\e[1;32m"
InvGreen="\e[1;42m"
CDkGray="\e[1;90m"
InvDkGray="\e[1;100m"
InvLtGray="\e[1;47m"
CYellow="\e[1;33m"
InvYellow="\e[1;43m"
CBlue="\e[1;34m"
InvBlue="\e[1;44m"
CMagenta="\e[1;35m"
CCyan="\e[1;36m"
InvCyan="\e[1;46m"
CWhite="\e[1;37m"
InvWhite="\e[1;107m"
CClear="\e[0m"
# -------------------------------------------------------------------------------------------------------------------------
# blackwhite is a simple function that removes all color attributes
blackwhite()
{
CBlack=""
InvBlack=""
CRed=""
InvRed=""
CGreen=""
InvGreen=""
CDkGray=""
InvDkGray=""
InvLtGray=""
CYellow=""
InvYellow=""
CBlue=""
InvBlue=""
CMagenta=""
CCyan=""
InvCyan=""
CWhite=""
InvWhite=""
CClear=""
}
# -------------------------------------------------------------------------------------------------------------------------
# LogoNM is a function that displays the VPNMON-R3 script name in a cool ASCII font without menu options
logoNM () {
clear
echo ""
echo ""
echo ""
echo -e "${CDkGray} _ ______ _ ____ _______ _ __ ____ _____"
echo -e " | | / / __ \/ | / / |/ / __ \/ | / / / __ \__ /"
echo -e " | | / / /_/ / |/ / /|_/ / / / / |/ /_____/ /_/ //_ < "
echo -e " | |/ / ____/ /| / / / / /_/ / /| /_____/ _, _/__/ / "
echo -e " |___/_/ /_/ |_/_/ /_/\____/_/ |_/ /_/ |_/____/ v$version"
echo ""
echo ""
printf "\r ${CGreen} [ INITIALIZING ] ${CClear}"
sleep 2
clear
echo ""
echo ""
echo ""
echo -e "${CYellow} _ ______ _ ____ _______ _ __ ____ _____"
echo -e " | | / / __ \/ | / / |/ / __ \/ | / / / __ \__ /"
echo -e " | | / / /_/ / |/ / /|_/ / / / / |/ /_____/ /_/ //_ < "
echo -e " | |/ / ____/ /| / / / / /_/ / /| /_____/ _, _/__/ / "
echo -e " |___/_/ /_/ |_/_/ /_/\____/_/ |_/ /_/ |_/____/ v$version"
echo ""
echo ""
printf "\r ${CGreen}[ INITIALIZING ... DONE ]${CClear}"
sleep 1
printf "\r ${CGreen} [ LOADING... ] ${CClear}"
sleep 2
}
logoNMexit () {
clear
echo ""
echo ""
echo ""
echo -e "${CYellow} _ ______ _ ____ _______ _ __ ____ _____"
echo -e " | | / / __ \/ | / / |/ / __ \/ | / / / __ \__ /"
echo -e " | | / / /_/ / |/ / /|_/ / / / / |/ /_____/ /_/ //_ < "
echo -e " | |/ / ____/ /| / / / / /_/ / /| /_____/ _, _/__/ / "
echo -e " |___/_/ /_/ |_/_/ /_/\____/_/ |_/ /_/ |_/____/ v$version"
echo ""
echo ""
printf "\r ${CGreen} [ SHUTTING DOWN ] ${CClear}"
sleep 2
clear
echo ""
echo ""
echo ""
echo -e "${CDkGray} _ ______ _ ____ _______ _ __ ____ _____"
echo -e " | | / / __ \/ | / / |/ / __ \/ | / / / __ \__ /"
echo -e " | | / / /_/ / |/ / /|_/ / / / / |/ /_____/ /_/ //_ < "
echo -e " | |/ / ____/ /| / / / / /_/ / /| /_____/ _, _/__/ / "
echo -e " |___/_/ /_/ |_/_/ /_/\____/_/ |_/ /_/ |_/____/ v$version"
echo ""
echo ""
printf "\r ${CGreen} [ SHUTTING DOWN ] ${CClear}"
sleep 1
printf "\r ${CDkGray} [ GOODBYE... ] ${CClear}\n\n"
sleep 2
}
# -------------------------------------------------------------------------------------------------------------------------
# Promptyn is a simple function that accepts y/n input
promptyn () { # No defaults, just y or n
while true; do
read -p '[y/n]? ' YESNO
case "$YESNO" in
[Yy]* ) return 0 ;;
[Nn]* ) return 1 ;;
* ) echo -e "\nPlease answer y or n.";;
esac
done
}
# -------------------------------------------------------------------------------------------------------------------------
# Spinner is a script that provides a small indicator on the screen to show script activity
spinner()
{
spins=$1
spin=0
charspin=0
totalspins=$((spins / 4))
while [ $spin -le $totalspins ]; do
for spinchar in / - \\ \|; do
printf "\r$spinchar ${CGreen}[${CWhite}$charspin${CGreen}]"
charspin=$((charspin + 1))
sleep 1
done
spin=$((spin+1))
done
printf "\r"
}
# -------------------------------------------------------------------------------------------------------------------------
# Preparebar and Progressbar is a script that provides a nice progressbar to show script activity
##----------------------------------------##
## Modified by Martinski W. [2024-Nov-01] ##
##----------------------------------------##
preparebar()
{
barlen="$1"
barspaces="$(printf "%*s" "$1" ' ')"
barchars="$(printf "%*s" "$1" ' ' | tr ' ' "$2")"
}
##----------------------------------------##
## Modified by Martinski W. [2024-Nov-02] ##
##----------------------------------------##
progressbaroverride()
{
insertspc=" "
bypasswancheck=0
_GetPercent_() { printf "%.1f" "$(echo "$1" | awk "{print $1}")" ; }
if [ "$1" -eq -1 ]
then
printf "\r $barspaces\r"
else
if [ $# -gt 6 ] && [ -n "$7" ] && [ "$1" -ge "$7" ]
then
barch="$(($7*barlen/$2))"
barsp="$((barlen-barch))"
percnt="$(_GetPercent_ "(100*$1/$2)")"
else
barch="$(($1*barlen/$2))"
barsp="$((barlen-barch))"
percnt="$(_GetPercent_ "(100*$1/$2)")"
fi
if [ $# -gt 5 ] && [ -n "$6" ]; then AltNum="$6" ; else AltNum="$1" ; fi
if [ "$5" = "Standard" ]
then
printf " ${CWhite}${InvDkGray}%3d${4} /%5.1f%%${CClear} [${CGreen}e${CClear}=Exit] [Selection? ${InvGreen} ${CClear}${CGreen}]\r${CClear}" "$AltNum" "$percnt"
fi
fi
# Borrowed this wonderful keypress capturing mechanism from @Eibgrad... thank you! :)
key_press=''; read -rsn1 -t 1 key_press < "$(tty 0>&2)"
if [ "$key_press" ]
then
case "$key_press" in
[1]) echo ""; restartvpn 1; sendmessage 0 "VPN Reset" 1; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[2]) echo ""; restartvpn 2; sendmessage 0 "VPN Reset" 2; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[3]) echo ""; restartvpn 3; sendmessage 0 "VPN Reset" 3; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[4]) echo ""; restartvpn 4; sendmessage 0 "VPN Reset" 4; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[5]) echo ""; restartvpn 5; sendmessage 0 "VPN Reset" 5; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[6]) echo ""; restartwg 1; sendmessage 0 "WG Reset" 1; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[7]) echo ""; restartwg 2; sendmessage 0 "WG Reset" 2; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[8]) echo ""; restartwg 3; sendmessage 0 "WG Reset" 3; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[9]) echo ""; restartwg 4; sendmessage 0 "WG Reset" 4; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[0]) echo ""; restartwg 5; sendmessage 0 "WG Reset" 5; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\!]) echo ""; killunmonvpn 1; sendmessage 0 "VPN Killed" 1; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\@]) echo ""; killunmonvpn 2; sendmessage 0 "VPN Killed" 2; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\#]) echo ""; killunmonvpn 3; sendmessage 0 "VPN Killed" 3; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\$]) echo ""; killunmonvpn 4; sendmessage 0 "VPN Killed" 4; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\%]) echo ""; killunmonvpn 5; sendmessage 0 "VPN Killed" 5; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\^]) echo ""; killunmonwg 1; sendmessage 0 "WG Killed" 1; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\&]) echo ""; killunmonwg 2; sendmessage 0 "WG Killed" 2; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\-]) echo ""; killunmonwg 3; sendmessage 0 "WG Killed" 3; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\+]) echo ""; killunmonwg 4; sendmessage 0 "WG Killed" 4; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\=]) echo ""; killunmonwg 5; sendmessage 0 "WG Killed" 5; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[Aa]) autostart; resetifacestats;;
[Cc]) vsetup; resetifacestats;;
[Dd]) wgserverlistautomation; resetifacestats;;
[Ee]) logoNMexit; echo -e "${CClear}\n"; exit 0;;
[Hh]) hideoptions=1 ; [ "$hideoptions" != "$prevHideOpts" ] && timerreset=1 ;;
[Ii]) amtmevents; resetifacestats;;
[Ll]) vlogs; resetifacestats;;
[Mm]) vpnslots; resetifacestats;;
[Pp]) maxping; resetifacestats;;
[Rr]) schedulevpnreset; resetifacestats;;
[Ss]) hideoptions=0 ; [ "$hideoptions" != "$prevHideOpts" ] && timerreset=1 ;;
[Tt]) timerloopconfig; resetifacestats;;
[Uu]) vpnserverlistautomation; resetifacestats;;
[Vv]) vpnserverlistmaint; resetifacestats;;
[Ww]) wgserverlistmaint; resetifacestats;;
[Xx]) uninstallr2; resetifacestats;;
*) ;; ##IGNORE INVALID key presses ##
esac
bypasswancheck=1
fi
}
progressbarpause()
{
insertspc=" "
bypasswancheck=0
if [ "$1" -eq -1 ]
then
printf "\r $barspaces\r"
else
if [ $# -gt 6 ] && [ -n "$7" ] && [ "$1" -ge "$7" ]
then
barch="$(($7*barlen/$2))"
barsp="$((barlen-barch))"
progr="$((100*$1/$2))"
else
barch="$(($1*barlen/$2))"
barsp="$((barlen-barch))"
progr="$((100*$1/$2))"
fi
if [ $# -gt 5 ] && [ -n "$6" ]; then AltNum="$6" ; else AltNum="$1" ; fi
if [ "$5" = "Standard" ]
then
printf " ${CWhite}${InvDkGray}Continuing Reset in $AltNum/5...${CClear} [${CGreen}p${CClear}=Pause] [${CGreen}e${CClear}=Exit] [Selection? ${InvGreen} ${CClear}${CGreen}]\r${CClear}" "$barchars" "$barspaces"
fi
fi
# Borrowed this wonderful keypress capturing mechanism from @Eibgrad... thank you! :)
key_press=''; read -rsn1 -t 1 key_press < "$(tty 0>&2)"
if [ $key_press ]
then
case $key_press in
[Pp]) vpause;;
[Ee]) logoNMexit; echo -e "${CClear}\n"; exit 0;;
esac
bypasswancheck=1
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# This function optionally uninstalls VPNMON-R2 if still found present on local router
uninstallr2()
{
if [ -f /jffs/scripts/vpnmon-r2.sh ]
then
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} VPNMON-R2 Uninstall Utility ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} This utility allows you to uninstall VPNMON-R2. NOTE: Please know that VPNMON-R2"
echo -e "${InvGreen} ${CClear} development is ceasing, and product support will be sunset in the very near future."
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} VPNMON-R2 was still found installed on your router. This menu gives you the option"
echo -e "${InvGreen} ${CClear} to launch (if needed) or uninstall the old legacy VPNMON-R2. Thank you!"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo ""
printf "${CClear}Please select? (${CGreen}u${CClear}=UNinstall R2, ${CGreen}r${CClear}=Run R2, ${CGreen}e${CClear}=Exit)"
read -p ": " SelectR2
case $SelectR2 in
[Uu])
echo -e "\n${CClear}Please type 'Y' to validate you wish to proceed with the uninstall of VPNMON-R2.${CClear}"
if promptyn "(y/n): "
then
echo -e "\n${CClear}Uninstalling VPNMON-R2 components...${CClear}"
if [ "$(cat /jffs/addons/vpnmon-r2.d/vpnmon-r2.cfg | grep "UpdateUnbound" | cut -d '=' -f 2-)" = "1" ]
then
# Delete all additions made to files to enable Unbound over VPN functionality
echo ""
echo -e "\n${CClear}Unbinding Unbound from VPN..."
# Disable vpn functionality with Unbound
sh /jffs/addons/unbound/unbound_manager.sh vpn=disable >/dev/null 2>&1
# Remove Unbound failsafe in post-mount
if [ -f /jffs/scripts/post-mount ]; then
sed -i -e '/vpn=disable/d' /jffs/scripts/post-mount >/dev/null 2>&1
fi
# Remove Unbound VPN helper script in openvpn-event
if [ -f /jffs/scripts/openvpn-event ]; then
sed -i -e '/unbound_DNS_via_OVPN.sh/d' /jffs/scripts/openvpn-event >/dev/null 2>&1
fi
# Remove RPDB Rules added to nat-start
if [ -f /jffs/scripts/nat-start ]; then
sed -i -e '/Added by vpnmon-r2/d' /jffs/scripts/nat-start >/dev/null 2>&1
fi
# Remove the unbound_DNS_via_OVPN.sh file
if [ -f /jffs/addons/unbound/unbound_DNS_via_OVPN.sh ]; then
rm /jffs/addons/unbound/unbound_DNS_via_OVPN.sh
fi
echo -e "\n${CClear}If Unbound-over-VPN is enabled on VPNMON-R3, you may need to disable/re-enable"
echo -e "this feature under the setup/configuration menu again. Conflicts may have"
echo -e "arisen with both products having this feature enabled."
fi
echo -e "\n${CClear}Removing VPNMON-R2 Files..."
# Remove R2 Files
rm -f -r /jffs/addons/vpnmon-r2.d
rm -f /jffs/scripts/vpnmon-r2.sh
if [ -f /jffs/scripts/post-mount ]; then
sed -i -e '/vpnmon-r2.sh/d' /jffs/scripts/post-mount >/dev/null 2>&1
fi
echo -e "\n${CClear}VPNMON-R2 has been uninstalled...${CClear}"
echo ""
read -rsp $'Press any key to continue...\n' -n1 key
timer="$timerloop"
echo -e "${CClear}\n"
return
else
timer="$timerloop"
echo -e "${CClear}\n"
return
fi
;;
[Rr]) exec sh /jffs/scripts/vpnmon-r2.sh -setup; exit 0;;
[Ee]) timer="$timerloop" ; echo -e "${CClear}\n"; return;;
esac
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# This function presents an Operational Menu in a Pause state, usually during VPN slot errors which give you a 5 second
# opportunity to pause in order to make any particular changes that might help your situation
vpause()
{
while true
do
if [ "$availableslots" = "1 2" ]
then
clear
displayopsmenu
printf "${CClear}Please select? (${CGreen}n${CClear}=UNpause, ${CGreen}e${CClear}=Exit)"
read -p ": " SelectSlot
case $SelectSlot in
[1]) echo ""; restartvpn 1; sendmessage 0 "VPN Reset" 1; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[2]) echo ""; restartvpn 2; sendmessage 0 "VPN Reset" 2; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\!]) echo ""; killunmonvpn 1; sendmessage 0 "VPN Killed" 1; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\@]) echo ""; killunmonvpn 2; sendmessage 0 "VPN Killed" 2; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[Aa]) autostart; resetifacestats;;
[Cc]) vsetup; resetifacestats;;
[Ee]) echo -e "${CClear}\n"; exit 0;;
[Ii]) amtmevents; resetifacestats;;
[Ll]) vlogs; resetifacestats;;
[Mm]) vpnslots; resetifacestats;;
[Pp]) maxping; resetifacestats;;
[Rr]) schedulevpnreset; resetifacestats;;
[Tt]) timerloopconfig; resetifacestats;;
[Uu]) vpnserverlistautomation; resetifacestats;;
[Vv]) vpnserverlistmaint; resetifacestats;;
[Nn]) exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
*) exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
esac
elif [ "$availableslots" = "1 2 3 4 5" ]
then
clear
displayopsmenu
printf "${CClear}Please select? (${CGreen}n${CClear}=UNpause, ${CGreen}e${CClear}=Exit)"
read -p ": " SelectSlot
case $SelectSlot in
[1]) echo ""; restartvpn 1; sendmessage 0 "VPN Reset" 1; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[2]) echo ""; restartvpn 2; sendmessage 0 "VPN Reset" 2; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[3]) echo ""; restartvpn 3; sendmessage 0 "VPN Reset" 3; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[4]) echo ""; restartvpn 4; sendmessage 0 "VPN Reset" 4; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[5]) echo ""; restartvpn 5; sendmessage 0 "VPN Reset" 5; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[6]) echo ""; restartwg 1; sendmessage 0 "WG Reset" 1; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[7]) echo ""; restartwg 2; sendmessage 0 "WG Reset" 2; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[8]) echo ""; restartwg 3; sendmessage 0 "WG Reset" 3; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[9]) echo ""; restartwg 4; sendmessage 0 "WG Reset" 4; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[0]) echo ""; restartwg 5; sendmessage 0 "WG Reset" 5; restartrouting; resetspdmerlin; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\!]) echo ""; killunmonvpn 1; sendmessage 0 "VPN Killed" 1; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\@]) echo ""; killunmonvpn 2; sendmessage 0 "VPN Killed" 2; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\#]) echo ""; killunmonvpn 3; sendmessage 0 "VPN Killed" 3; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\$]) echo ""; killunmonvpn 4; sendmessage 0 "VPN Killed" 4; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\%]) echo ""; killunmonvpn 5; sendmessage 0 "VPN Killed" 5; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\^]) echo ""; killunmonwg 1; sendmessage 0 "WG Killed" 1; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\&]) echo ""; killunmonwg 2; sendmessage 0 "WG Killed" 2; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\-]) echo ""; killunmonwg 3; sendmessage 0 "WG Killed" 3; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\+]) echo ""; killunmonwg 4; sendmessage 0 "WG Killed" 4; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[\=]) echo ""; killunmonwg 5; sendmessage 0 "WG Killed" 5; exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
[Aa]) autostart; resetifacestats;;
[Cc]) vsetup; resetifacestats;;
[Ee]) echo -e "${CClear}\n"; exit 0;;
[Ii]) amtmevents; resetifacestats;;
[Ll]) vlogs; resetifacestats;;
[Mm]) vpnslots; resetifacestats;;
[Pp]) maxping; resetifacestats;;
[Rr]) schedulevpnreset; resetifacestats;;
[Tt]) timerloopconfig; resetifacestats;;
[Uu]) vpnserverlistautomation; resetifacestats;;
[Vv]) vpnserverlistmaint; resetifacestats;;
[Ww]) wgserverlistmaint; resetifacestats;;
[Nn]) exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
*) exec sh /jffs/scripts/vpnmon-r3.sh -noswitch;;
esac
fi
done
}
# -------------------------------------------------------------------------------------------------------------------------
# creates needed config files if they don't exist
createconfigs()
{
# Fix older versions using incorrect client slots
if [ "$availableslots" = "1 2 3" ]
then
availableslots="1 2"
rm -f /jffs/addons/vpnmon-r3.d/vr3clients.txt
rm -f /jffs/addons/vpnmon-r3.d/vr3timers.txt
saveconfig
fi
# Create initial vr3clients.txt & vr3timers.txt file
if [ ! -f /jffs/addons/vpnmon-r3.d/vr3clients.txt ]
then
if [ "$availableslots" = "1 2" ]
then
{ echo 'VPN1=0'
echo 'VPN2=0'
} > /jffs/addons/vpnmon-r3.d/vr3clients.txt
elif [ "$availableslots" = "1 2 3 4 5" ]
then
{ echo 'VPN1=0'
echo 'VPN2=0'
echo 'VPN3=0'
echo 'VPN4=0'
echo 'VPN5=0'
echo 'WG1=0'
echo 'WG2=0'
echo 'WG3=0'
echo 'WG4=0'
echo 'WG5=0'
} > /jffs/addons/vpnmon-r3.d/vr3clients.txt
fi
fi
if [ ! -f /jffs/addons/vpnmon-r3.d/vr3timers.txt ]
then
if [ "$availableslots" = "1 2" ]
then
{ echo 'VPNTIMER1=0'
echo 'VPNTIMER2=0'
} > /jffs/addons/vpnmon-r3.d/vr3timers.txt
elif [ "$availableslots" = "1 2 3 4 5" ]
then
{ echo 'VPNTIMER1=0'
echo 'VPNTIMER2=0'
echo 'VPNTIMER3=0'
echo 'VPNTIMER4=0'
echo 'VPNTIMER5=0'
echo 'WGTIMER1=0'
echo 'WGTIMER2=0'
echo 'WGTIMER3=0'
echo 'WGTIMER4=0'
echo 'WGTIMER5=0'
} > /jffs/addons/vpnmon-r3.d/vr3timers.txt
fi
fi
if [ "$availableslots" = "1 2 3 4 5" ]
then
# Determine if the new Wireguard client values are present, if not, add them
if ! grep -q "WG" "/jffs/addons/vpnmon-r3.d/vr3clients.txt"
then
# Check for and remove empty lines after the last entry before the EOF
awk 'NF > 0 {for (i=1; i<=b; i++) print ""; b=0; print} NF==0 {b++}' "/jffs/addons/vpnmon-r3.d/vr3clients.txt" > "/jffs/addons/vpnmon-r3.d/vr3clients.tmp"
# Overwrite the original file with the cleaned-up version.
mv "/jffs/addons/vpnmon-r3.d/vr3clients.tmp" "/jffs/addons/vpnmon-r3.d/vr3clients.txt"
# Write the new Wireguard timer values
cat << EOF >> "/jffs/addons/vpnmon-r3.d/vr3clients.txt"
WG1=0
WG2=0
WG3=0
WG4=0
WG5=0
EOF
fi
# Determine if the new Wireguard timer values are present, if not, add them
if ! grep -q "WGTIMER" "/jffs/addons/vpnmon-r3.d/vr3timers.txt"
then
# Check for and remove empty lines after the last entry before the EOF
awk 'NF > 0 {for (i=1; i<=b; i++) print ""; b=0; print} NF==0 {b++}' "/jffs/addons/vpnmon-r3.d/vr3timers.txt" > "/jffs/addons/vpnmon-r3.d/vr3timers.tmp"
# Overwrite the original file with the cleaned-up version.
mv "/jffs/addons/vpnmon-r3.d/vr3timers.tmp" "/jffs/addons/vpnmon-r3.d/vr3timers.txt"
# Write the new Wireguard timer values
cat << EOF >> "/jffs/addons/vpnmon-r3.d/vr3timers.txt"
WGTIMER1=0
WGTIMER2=0
WGTIMER3=0
WGTIMER4=0
WGTIMER5=0
EOF
fi
fi
}
##-------------------------------------##
## Added by Martinski W. [2024-Oct-05] ##
##-------------------------------------##
_SetUpTimeoutCmdVars_()
{
# If the timeout utility is available then use it #
if [ -z "${timeoutcmd:+xSETx}" ] && [ -f "/opt/bin/timeout" ]
then
timeoutcmd="timeout "
timeoutsec="10"
timeoutlng="60"
fi
}
##-------------------------------------##
## Added by Martinski W. [2024-Oct-05] ##
##-------------------------------------##
_SetLAN_HostName_()
{
[ -z "${LAN_HostName:+xSETx}" ] && \
LAN_HostName="$($timeoutcmd$timeoutsec nvram get lan_hostname)"
}
_GetLAN_HostName_()
{ _SetLAN_HostName_ ; echo "$LAN_HostName" ; }
# -------------------------------------------------------------------------------------------------------------------------
# vsetup provide a menu interface to allow for initial component installs, uninstall, etc.
##----------------------------------------##
## Modified by Martinski W. [2024-Oct-05] ##
##----------------------------------------##
vsetup()
{
_SetUpTimeoutCmdVars_
while true
do
clear # Initial Setup
if [ ! -f "$config" ]; then # Write /jffs/addons/vpnmon-r3.d/vpnmon-r3.cfg
saveconfig
fi
createconfigs
echo -e "${InvGreen} ${InvDkGray}${CWhite} VPNMON-R3 Main Setup and Configuration Menu ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please choose from the various options below, which allow you to perform high level${CClear}"
echo -e "${InvGreen} ${CClear} actions in the management of the VPNMON-R3 script.${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(1)${CClear} : Custom configuration options for VPNMON-R3${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(2)${CClear} : Force reinstall Entware dependencies${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(3)${CClear} : Check for latest updates${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(4)${CClear} : Uninstall VPNMON-R3${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} | ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(e)${CClear} : Exit${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo ""
read -p "Please select? (1-4, e=Exit): " SelectSlot
case $SelectSlot in
1) # Check for existence of entware, and if so proceed and install the timeout package, then run vpnmon-r3 -config
clear
if [ -f "/opt/bin/timeout" ] && [ -f "/opt/sbin/screen" ] && [ -f "/opt/bin/jq" ]
then
vconfig
else
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Install Dependencies ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Missing dependencies required by VPNMON-R3 will be installed during this process."
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo ""
echo -e "VPNMON-R3 has some dependencies in order to function correctly, namely, CoreUtils-Timeout"
echo -e "JQ, and the Screen utility. These utilities require you to have Entware already installed"
echo -e "using the AMTM tool. If Entware is present, the Timeout, JQ and Screen utilities will"
echo -e "automatically be downloaded and installed during this process."
echo ""
echo -e "${CGreen}CoreUtils-Timeout${CClear} is a utility that provides more stability for certain routers (like"
echo -e "the RT-AC86U) which has a tendency to randomly hang scripts running on this router model."
echo ""
echo -e "${CGreen}JQuery${CClear} is a utility for querying data across the internet through the the means of"
echo -e "APIs for the purposes of interacting with the various VPN providers to get a list"
echo -e "of available VPN hosts in the selected location(s)."
echo ""
echo -e "${CGreen}Screen${CClear} is a utility that allows you to run SSH scripts in a standalone environment"
echo -e "directly on the router itself, instead of running your commands or a script from a network-"
echo -e "attached SSH client. This can provide greater stability due to it running on the router"
echo -e "itself."
echo ""
echo -e "Your router model is: ${CGreen}$ROUTERMODEL${CClear}"
echo ""
echo -e "Ready to install?"
if promptyn " (y/n): "
then
if [ -d "/opt" ]; then # Does entware exist? If yes proceed, if no error out.
echo ""
echo -e "\n${CClear}Updating Entware Packages..."
echo ""
opkg update
echo ""
echo -e "Installing Entware ${CGreen}CoreUtils-Timeout${CClear} Package...${CClear}"
echo ""
opkg install coreutils-timeout
echo ""
echo -e "Installing Entware ${CGreen}JQuery${CClear} Package...${CClear}"
echo ""
opkg install jq
echo ""
echo -e "Installing Entware ${CGreen}Screen${CClear} Package...${CClear}"
echo ""
opkg install screen
echo ""
echo -e "Install completed..."
echo ""
read -rsp $'Press any key to continue...\n' -n1 key
echo ""
echo -e "Executing Configuration Utility..."
sleep 2
vconfig
else
clear
echo -e "${CRed}ERROR: Entware was not found on this router...${CClear}"
echo -e "Please install Entware using the AMTM utility before proceeding..."
echo ""
read -rsp $'Press any key to continue...\n' -n1 key
fi
else
echo ""
echo -e "\nExecuting Configuration Utility..."
sleep 2
vconfig
fi
fi
;;
2) # Force re-install the CoreUtils timeout/screen package
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Re-install Dependencies ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Missing dependencies required by VPNMON-R3 will be re-installed during this process."
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo ""
echo -e "Would you like to re-install the CoreUtils-Timeout, JQ and the Screen utility? These"
echo -e "utilities require you to have Entware already installed using the AMTM tool. If Entware"
echo -e "is present, the Timeout and Screen utilities will be uninstalled, downloaded and re-"
echo -e "installed during this setup process..."
echo ""
echo -e "${CGreen}CoreUtils-Timeout${CClear} is a utility that provides more stability for certain routers (like"
echo -e "the RT-AC86U) which has a tendency to randomly hang scripts running on this router"
echo -e "model."
echo ""
echo -e "${CGreen}JQuery${CClear} is a utility for querying data across the internet through the the means of"
echo -e "APIs for the purposes of interacting with the various VPN providers to get a list"
echo -e "of available VPN hosts in the selected location(s)."
echo ""
echo -e "${CGreen}Screen${CClear} is a utility that allows you to run SSH scripts in a standalone environment"
echo -e "directly on the router itself, instead of running your commands or a script from a"
echo -e "network-attached SSH client. This can provide greater stability due to it running on"
echo -e "the router itself."
echo ""
echo -e "Your router model is: ${CGreen}$ROUTERMODEL${CClear}"
echo ""
echo -e "Force Re-install?"
if promptyn "[y/n]: "
then
if [ -d "/opt" ]; then # Does entware exist? If yes proceed, if no error out.
echo ""
echo -e "\nUpdating Entware Packages..."
echo ""
opkg update
echo ""
echo -e "Force Re-installing Entware ${CGreen}CoreUtils-Timeout${CClear} Package..."
echo ""
opkg install --force-reinstall coreutils-timeout
echo ""
echo -e "Force Re-installing Entware ${CGreen}JQuery${CClear} Package..."
echo ""
opkg install --force-reinstall . jq
echo ""
echo -e "Force Re-installing Entware ${CGreen}Screen${CClear} Package..."
echo ""
opkg install --force-reinstall screen
echo ""
echo -e "Re-install completed..."
echo ""
read -rsp $'Press any key to continue...\n' -n1 key
else
clear
echo -e "${CRed}ERROR: Entware was not found on this router...${CClear}"
echo -e "Please install Entware using the AMTM utility before proceeding..."
echo ""
read -rsp $'Press any key to continue...\n' -n1 key
fi
fi
;;
3) vupdate;;
4) vuninstall;;
[Ee])
echo ""
timer="$timerloop"
break;;
esac
done
}
# -------------------------------------------------------------------------------------------------------------------------
# vconfig is a function that provides a UI to choose various options for vpnmon-r3
##----------------------------------------##
## Modified by Martinski W. [2024-Oct-05] ##
##----------------------------------------##
vconfig()
{
_SetUpTimeoutCmdVars_
# Grab the VPNMON-R3 config file and read it in
if [ -f "$config" ]
then
source "$config"
else
clear
echo -e "${CRed}ERROR: VPNMON-R3 is not configured. Please run 'vpnmon-r3.sh -setup' first."
echo ""
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: VPNMON-R3 config file not found. Please run the setup/configuration utility" >> $logfile
echo -e "${CClear}"
exit 1
fi
while true
do
if [ "$availableslots" = "1 2" ]; then
availableslotsdisp="2 x OVPN"
elif [ "$availableslots" = "1 2 3 4 5" ]; then
availableslotsdisp="5 x OVPN | 5 x WG"
fi
if [ "$unboundclient" -eq 0 ]; then
unboundclientexp="${CDkGray}Disabled"
else
unboundclientexp="Enabled, VPN$unboundclient"
fi
if [ "$unboundwgclient" -eq 0 ]; then
unboundwgclientexp="${CDkGray}Disabled"
else
unboundwgclientexp="Enabled, WGC$unboundwgclient"
fi
if [ "$unboundclient" -eq 0 ] && [ "$unboundwgclient" -eq 0 ]; then
unboundshowip=0
saveconfig
fi
if [ "$unboundshowip" -eq 0 ]; then
unboundshowipdisp="${CDkGray}Disabled"
else
unboundshowipdisp="Enabled"
fi
if [ "$refreshserverlists" -eq 0 ]; then
refreshserverlistsdisp="${CDkGray}Disabled"
else
refreshserverlistsdisp="Enabled"
fi
if [ "$monitorwan" -eq 0 ]; then
monitorwandisp="${CDkGray}Disabled"
else
monitorwandisp="Enabled"
fi
if [ "$useovpn" -eq 0 ] && [ "$usewg" -eq 0 ]; then
useovpnwgDisp="${CDkGray}OVPN/WG Disabled"
elif
[ "$useovpn" -eq 1 ] && [ "$usewg" -eq 0 ]; then
useovpnwgDisp="${CGreen}OVPN Only"
elif
[ "$useovpn" -eq 0 ] && [ "$usewg" -eq 1 ]; then
useovpnwgDisp="${CGreen}WG Only"
elif
[ "$useovpn" -eq 1 ] && [ "$usewg" -eq 1 ]; then
useovpnwgDisp="${CGreen}OVPN/WG Enabled"
fi
if [ "$updateskynet" -eq 0 ]; then
updateskynetdisp="${CDkGray}Disabled"
else
updateskynetdisp="Enabled"
fi
if [ "$amtmemailsuccess" = "0" ] && [ "$amtmemailfailure" = "0" ]; then
amtmemailsuccfaildisp="${CDkGray}Disabled"
elif [ "$amtmemailsuccess" = "1" ] && [ "$amtmemailfailure" = "0" ]; then
amtmemailsuccfaildisp="Success"
elif [ "$amtmemailsuccess" = "0" ] && [ "$amtmemailfailure" = "1" ]; then
amtmemailsuccfaildisp="Failure"
elif [ "$amtmemailsuccess" = "1" ] && [ "$amtmemailfailure" = "1" ]; then
amtmemailsuccfaildisp="Success, Failure"
else
amtmemailsuccfaildisp="Disabled"
fi
rldisp=""
if [ "$amtmemailsuccess" = "1" ] || [ "$amtmemailfailure" = "1" ]
then
if [ "$ratelimit" = "0" ]; then
rldisp="| ${CDkGray}RL"
else
rldisp="| ${CGreen}RL:$ratelimit/h"
fi
fi
if [ "$rstspdmerlin" -eq 0 ]; then
rstspdmerlindisp="${CDkGray}Disabled"
else
rstspdmerlindisp="Enabled"
fi
if [ "$selectionmethod" -eq 0 ]; then
selectionmethoddisp="Random"
elif [ "$selectionmethod" -eq 1 ]; then
selectionmethoddisp="Sequential"
fi
if [ "$bwdisp" -eq 1 ]; then
throughputmethoddisp="Average Throughput (in Mbps)"
elif [ "$bwdisp" -eq 2 ]; then
throughputmethoddisp="Total Throughput (in MB)"
fi
utilspddisp="${CGreen}RX: 0-->$lowutilspd${CGreen}|${CYellow}$lowutilspd-->$medutilspd${CGreen}|${CRed}$medutilspd-->Max${CClear}"
utilspdupdisp="${CGreen}TX: 0-->$lowutilspdup${CGreen}|${CYellow}$lowutilspdup-->$medutilspdup${CGreen}|${CRed}$medutilspdup-->Max${CClear}"
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} VPNMON-R3 Configuration Options ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please choose from the various options below, which allow you to modify certain${CClear}"
echo -e "${InvGreen} ${CClear} customizable parameters that affect the operation of this script.${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 1)${CClear} : Number of VPN/WG Client Slots available : ${CGreen}$availableslotsdisp"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 2)${CClear} : Custom PING host to determine VPN health : ${CGreen}$PINGHOST"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 3)${CClear} : Custom Event Log size (rows) : ${CGreen}$logsize"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 4)${CClear} : Unbound DNS Lookups over VPN Integration : ${CGreen}$unboundclientexp"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 5)${CClear} : Unbound DNS Lookups over WG Integration : ${CGreen}$unboundwgclientexp"
if [ "$unboundclient" -ge 1 ] || [ "$unboundwgclient" -ge 1 ]; then
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 6)${CClear} -- Show Expanded Unbound IP Info? : ${CGreen}$unboundshowipdisp"
else
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 6)${CClear} -- ${CDkGray}Show Expanded Unbound IP Info? : $unboundshowipdisp"
fi
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 7)${CClear} : Refresh Custom Server Lists on -RESET Switch : ${CGreen}$refreshserverlistsdisp"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 8)${CClear} : Provide additional WAN/Dual WAN monitoring : ${CGreen}$monitorwandisp"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( 9)${CClear} : Enable/Disable VPN/WG Slot Monitoring : $useovpnwgDisp"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(10)${CClear} : Whitelist VPN Server IP Lists in Skynet : ${CGreen}$updateskynetdisp"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(11)${CClear} : AMTM Email Notifications / Rate Limiting : ${CGreen}$amtmemailsuccfaildisp $rldisp"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(12)${CClear} : Reset spdMerlin Interfaces on VPN Reset : ${CGreen}$rstspdmerlindisp"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(13)${CClear} : Server List Item Selection Method : ${CGreen}$selectionmethoddisp"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(14)${CClear} : Connection Throughput Threshold Selections : $utilspddisp"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} |-${CClear}--- : $utilspdupdisp"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}(15)${CClear} : Connection Throughput Display Method : ${CGreen}$throughputmethoddisp"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} | ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}( e)${CClear} : Exit${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo ""
read -p "Please select? (1-15, e=Exit): " SelectSlot
case $SelectSlot in
1)
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Number of VPN/WG Client Slots Available on Router ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate how many VPN/WG client slots your router is configured with. Certain${CClear}"
echo -e "${InvGreen} ${CClear} older model routers (RT-AC68U) can only handle a maximum of 2 VPN client slots, and${CClear}"
echo -e "${InvGreen} ${CClear} natively can't handle WG without some effort using 3rd party scripts, while the vast${CClear}"
echo -e "${InvGreen} ${CClear} majority of newer models can handle 5 VPN and 5 WG slots. Easiest way to tell is by${CClear}"
echo -e "${InvGreen} ${CClear} looking at your VPN settings within the Merlin Web UI. Please choose below:"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${CGreen}(2)${CClear} = 2 x VPN slots (Older router models)"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${CGreen}(5)${CClear} = 5 x VPN | 5 x WG slots (Newer router models)"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} (Default = 5 VPN/WG client slots)${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo
echo -e "${CClear}Current: ${CGreen}$availableslotsdisp${CClear}" ; echo
read -p "Please enter value (2 or 5)? (e=Exit): " newAvailableSlots
if [ "$newAvailableSlots" = "2" ]
then
availableslots="1 2"
availableslotsdisp="2 x VPN"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Available VPN Client Slot Configuration saved as: $availableslotsdisp" >> $logfile
rm -f /jffs/addons/vpnmon-r3.d/vr3clients.txt
rm -f /jffs/addons/vpnmon-r3.d/vr3timers.txt
saveconfig
createconfigs
elif [ "$newAvailableSlots" = "5" ]
then
availableslots="1 2 3 4 5"
availableslotsdisp="5 x VPN | 5 x WG"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Available VPN Client Slot Configuration saved as: $availableslotsdisp" >> $logfile
rm -f /jffs/addons/vpnmon-r3.d/vr3clients.txt
rm -f /jffs/addons/vpnmon-r3.d/vr3timers.txt
saveconfig
createconfigs
elif [ "$newAvailableSlots" = "e" ]
then
echo -e "\n[Exiting]"; sleep 2
else
previousValue="$availableslots"
availableslots="${availableslots:=1 2 3 4 5}"
availableslotsdisp="5 x VPN | 5 x WG"
[ "$availableslots" != "$previousValue" ] && \
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Available VPN Client Slot Configuration saved as: $availableslotsdisp" >> $logfile
rm -f /jffs/addons/vpnmon-r3.d/vr3clients.txt
rm -f /jffs/addons/vpnmon-r3.d/vr3timers.txt
saveconfig
createconfigs
fi
;;
2)
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Custom PING Host (to determine VPN health) ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate which host you want to PING in order to determine VPN Client health.${CClear}"
echo -e "${InvGreen} ${CClear} By default, the script will ping $PING_HOST_Deflt (Google DNS) as it's reliable, fairly${CClear}"
echo -e "${InvGreen} ${CClear} standard, and typically available globally. You can change this depending on your"
echo -e "${InvGreen} ${CClear} local access and connectivity situation."
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} (Default = ${PING_HOST_Deflt})${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo
echo -e "${CClear}Current: ${CGreen}${PINGHOST}${CClear}" ; echo
read -p "Please enter valid IPv4 address? (e=Exit): " newPingHost
if [ "$newPingHost" = "e" ]
then
echo -e "\n[Exiting]"; sleep 2
elif [ -n "$newPingHost" ] && echo "$newPingHost" | grep -qE "^${IPv4addrs_RegEx}$"
then
PINGHOST="$newPingHost"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New custom PING host entered: $PINGHOST" >> $logfile
saveconfig
else
previousValue="$PINGHOST"
PINGHOST="${PINGHOST:=$PING_HOST_Deflt}"
[ "$PINGHOST" != "$previousValue" ] && \
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New custom PING host entered: $PINGHOST" >> $logfile
saveconfig
fi
;;
3)
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Custom Event Log Size ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate below how large you would like your Event Log to grow. I'm a poet${CClear}"
echo -e "${InvGreen} ${CClear} and didn't even know it. By default, with 2000 rows, you will have many months of${CClear}"
echo -e "${InvGreen} ${CClear} Event Log data."
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Use 0 to Disable, max number of rows is 9999. (Default = 2000)"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo
echo -e "${CClear}Current: ${CGreen}$logsize${CClear}" ; echo
read -p "Please enter Log Size (in rows)? (0-9999, e=Exit): " newLogSize
if [ "$newLogSize" = "e" ]
then
echo -e "\n[Exiting]"; sleep 2
elif echo "$newLogSize" | grep -qE "^(0|[1-9][0-9]{0,3})$" && \
[ "$newLogSize" -ge 0 ] && [ "$newLogSize" -le 9999 ]
then
logsize="$newLogSize"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New custom Event Log Size entered (in rows): $logsize" >> $logfile
saveconfig
else
previousValue="$logsize"
logsize="${logsize:=2000}"
[ "$logsize" != "$previousValue" ] && \
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New custom Event Log Size entered (in rows): $logsize" >> $logfile
saveconfig
fi
;;
4)
if [ "$unboundwgclient" -ge 1 ]; then
echo ""
echo -e "${CRed}Unbound-over-WG is currently enabled. If you want to enable Unbound-over-VPN, please proceed to 'Disable'"
echo -e "the Unbound-over-WG option first, then choose to enable Unbound-over-VPN.${CClear}"
echo ""
sleep 3
read -rsp $'Press any key to continue...\n' -n1 key
continue
fi
while true; do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Unbound DNS Lookups over VPN Integration ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate if you would like to enable an integration with Unbound which allows${CClear}"
echo -e "${InvGreen} ${CClear} you to force any DNS lookups that Unbound would normally handle, but over your VPN${CClear}"
echo -e "${InvGreen} ${CClear} connection, essentially allowing you to appear as your own DNS resolver. DNS resolver${CClear}"
echo -e "${InvGreen} ${CClear} traffic generated by Unbound is unencrypted as it queries DNS Root Servers by default.${CClear}"
echo -e "${InvGreen} ${CClear} This integration encrypts your DNS Resolver traffic up to your Public VPN IP address,${CClear}"
echo -e "${InvGreen} ${CClear} after which it goes unencrypted to the DNS Root Servers, preventing any ISP or other${CClear}"
echo -e "${InvGreen} ${CClear} traffic inspection snooping when sending this across your WAN connection.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} IMPORTANT: This integration will only work with 1 primary VPN connection that is${CClear}"
echo -e "${InvGreen} ${CClear} designated as the connection that will carry DNS resolution traffic. This integration${CClear}"
echo -e "${InvGreen} ${CClear} will work when multiple VPN connections are running, but the other VPN connections may${CClear}"
echo -e "${InvGreen} ${CClear} not be able to utilize the Unbound functionality, and considered standalone. You will${CClear}"
echo -e "${InvGreen} ${CClear} need to identify one VPN Client Slot that will remain on at all times. This integration${CClear}"
echo -e "${InvGreen} ${CClear} requires additional scripts and configurations to get it working correctly. Please know${CClear}"
echo -e "${InvGreen} ${CClear} that multiple files will either be downloaded or modified, and may increase the${CClear}"
echo -e "${InvGreen} ${CClear} complexity in troubleshooting DNS lookup issues.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${CRed}WARNING: As of around March 1 2024, the Unbound integration no longer works with the${CClear}"
echo -e "${InvGreen} ${CClear} ${CRed}NordVPN Service due to possible blocking on their end. This service continues to work${CClear}"
echo -e "${InvGreen} ${CClear} ${CRed}as advertised with other VPN Providers, like AirVPN. Use at your own risk.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${CGreen}Requirements:"
echo -e "${InvGreen} ${CClear} ${CGreen}1. Unbound must already be installed and functioning (AMTM)"
echo -e "${InvGreen} ${CClear} ${CGreen}2. One static VPN Slot must be designated for Unbound-over-VPN use"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${CGreen}These files will be downloaded or modified:"
echo -e "${InvGreen} ${CClear} ${CGreen}1. /jffs/scripts/nat-start (modified)"
echo -e "${InvGreen} ${CClear} ${CGreen}2. /jffs/scripts/openvpn-event (modified)"
echo -e "${InvGreen} ${CClear} ${CGreen}3. /jffs/scripts/post-mount (modified)"
echo -e "${InvGreen} ${CClear} ${CGreen}4. /jffs/addons/unbound/unbound_DNS_via_OVPN.sh (downloaded)"
echo -e "${InvGreen} ${CClear} ${CGreen}5. Required router reboot - please don't forget to do so!${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} (Default = 0 / Disabled)${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo ""
if [ $unboundclient -eq 0 ]; then
unboundclientexp="Disabled"
else
unboundclientexp="Enabled, VPN$unboundclient"
fi
echo -e "${CClear}Current: ${CGreen}$unboundclientexp${CClear}"
echo ""
read -p "Please enter value (Disabled=0, VPN Client=1-5)? (e=Exit): " unboundovervpn
if [ ! -d "/jffs/addons/unbound" ]; then
echo ""
echo -e "${CRed}[Unbound was not detected on this system. Exiting...]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: Unbound was not detected on this system." >> $logfile
unboundclient=0
saveconfig
sleep 3
continue
fi
if [ "$unboundovervpn" = "0" ] || [ "$unboundovervpn" = "1" ] || [ "$unboundovervpn" = "2" ] || [ "$unboundovervpn" = "3" ] || [ "$unboundovervpn" = "4" ] || [ "$unboundovervpn" = "5" ] || [ "$unboundovervpn" = "e" ]; then
if [ "$unboundovervpn" = "0" ]; then
# Delete all additions made to files to enable Unbound over VPN functionality
echo ""
echo -e "${CGreen}[Disabling Unbound over VPN]...${CClear}"
# Disable vpn functionality with Unbound
sh /jffs/addons/unbound/unbound_manager.sh vpn=disable >/dev/null 2>&1
# Remove Unbound failsafe in post-mount
if [ -f /jffs/scripts/post-mount ]; then
sed -i -e '/vpn=disable/d' /jffs/scripts/post-mount
fi
# Remove Unbound VPN helper script in openvpn-event
if [ -f /jffs/scripts/openvpn-event ]; then
sed -i -e '/unbound_DNS_via_OVPN.sh/d' /jffs/scripts/openvpn-event
fi
# Remove RPDB Rules added to nat-start
if [ -f /jffs/scripts/nat-start ]; then
sed -i -e '/Added by vpnmon/d' /jffs/scripts/nat-start
fi
# Remove the unbound_DNS_via_OVPN.sh file
if [ -f /jffs/addons/unbound/unbound_DNS_via_OVPN.sh ]; then
rm -f /jffs/addons/unbound/unbound_DNS_via_OVPN.sh
fi
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Unbound-over-VPN was removed from VPNMON-R3" >> $logfile
unboundclient=0
saveconfig
sleep 3
continue
elif [ "$unboundovervpn" = "1" ] || [ "$unboundovervpn" = "2" ] || [ "$unboundovervpn" = "3" ] || [ "$unboundovervpn" = "4" ] || [ "$unboundovervpn" = "5" ]; then
if [ "$unboundovervpn" = "$unboundclient" ]; then
echo -e "${CClear}\n[Unbound over VPN$unboundovervpn Already Active]"; sleep 2; break
fi
if [ "$unboundovervpn" = "1" ] || [ "$unboundovervpn" = "2" ] || [ "$unboundovervpn" = "3" ] || [ "$unboundovervpn" = "4" ] || [ "$unboundovervpn" = "5" ] && [ $unboundclient -ge 1 ]; then
echo ""
echo -e "${CRed}When changing a VPN Client Slot (from Slot #$unboundclient to Slot #$unboundovervpn), please proceed to 'Disable'"
echo -e "first (option 0), then choose a new VPN Slot."
sleep 5; continue
fi
# Modify or create post-mount
if [ -f /jffs/scripts/post-mount ]; then
if ! grep -q -F "[ -n "'"$(which unbound_manager)"'" ] && { sh /jffs/addons/unbound/unbound_manager.sh vpn=disable; }" /jffs/scripts/post-mount; then
echo "[ -n "'"$(which unbound_manager)"'" ] && { sh /jffs/addons/unbound/unbound_manager.sh vpn=disable; } # Added by vpnmon-r3" >> /jffs/scripts/post-mount
fi
else
echo "#!/bin/sh" > /jffs/scripts/post-mount
echo "" >> /jffs/scripts/post-mount
echo "[ -n "'"$(which unbound_manager)"'" ] && { sh /jffs/addons/unbound/unbound_manager.sh vpn=disable; } # Added by vpnmon-r3" >> /jffs/scripts/post-mount
chmod 755 /jffs/scripts/post-mount
fi
# Modify or create nat-start
if [ -f /jffs/scripts/nat-start ]; then
if ! grep -q -F "sleep 10 # During the boot process nat-start may run multiple times so this is required" /jffs/scripts/nat-start; then
echo "" >> /jffs/scripts/nat-start
echo "sleep 10 # During the boot process nat-start may run multiple times so this is required - Added by vpnmon-r3" >> /jffs/scripts/nat-start
echo "" >> /jffs/scripts/nat-start
echo "# Ensure duplicate rules are not created - Added by vpnmon-r3" >> /jffs/scripts/nat-start
echo "for VPN_ID in 0 1 2 3 4 5 # Added by vpnmon-r3" >> /jffs/scripts/nat-start
echo " do # Added by vpnmon-r3" >> /jffs/scripts/nat-start
echo " ip rule del prio 999$VPN_ID 2>/dev/null # Added by vpnmon-r3" >> /jffs/scripts/nat-start
echo " done # Added by vpnmon-r3" >> /jffs/scripts/nat-start
echo "" >> /jffs/scripts/nat-start
echo "# Create the RPDB rules - Added by vpnmon-r3" >> /jffs/scripts/nat-start
echo "ip rule add from 0/0 fwmark \"0x8000/0x8000\" table main prio 9990 # WAN fwmark - Added by vpnmon-r3" >> /jffs/scripts/nat-start
echo "ip rule add from 0/0 fwmark \"0x7000/0x7000\" table ovpnc4 prio 9991 # VPN 4 fwmark - Added by vpnmon-r3" >> /jffs/scripts/nat-start
echo "ip rule add from 0/0 fwmark \"0x3000/0x3000\" table ovpnc5 prio 9992 # VPN 5 fwmark - Added by vpnmon-r3" >> /jffs/scripts/nat-start
echo "ip rule add from 0/0 fwmark \"0x1000/0x1000\" table ovpnc1 prio 9993 # VPN 1 fwmark - Added by vpnmon-r3" >> /jffs/scripts/nat-start
echo "ip rule add from 0/0 fwmark \"0x2000/0x2000\" table ovpnc2 prio 9994 # VPN 2 fwmark - Added by vpnmon-r3" >> /jffs/scripts/nat-start
echo "ip rule add from 0/0 fwmark \"0x4000/0x4000\" table ovpnc3 prio 9995 # VPN 3 fwmark - Added by vpnmon-r3" >> /jffs/scripts/nat-start
fi
else
curl --silent --retry 3 --connect-timeout 3 --max-time 6 --retry-delay 2 --retry-all-errors "https://raw.githubusercontent.com/ViktorJp/VPNMON-R2/main/Unbound/nat-start" -o "/jffs/scripts/nat-start" && chmod 755 "/jffs/scripts/nat-start"
fi
# Modify or create openvpn-event
if [ -f /jffs/scripts/openvpn-event ]; then
if ! grep -q -F "[ "'"${dev:0:4}"'" = 'tun1' ] && vpn_id" /jffs/scripts/openvpn-event; then
echo "[ "'"${dev:0:4}"'" = 'tun1' ] && vpn_id=$unboundovervpn && [ "'"$script_type"'" = 'route-up' ] && /jffs/addons/unbound/unbound_DNS_via_OVPN.sh \$vpn_id start &" >> /jffs/scripts/openvpn-event
echo "[ "'"${dev:0:4}"'" = 'tun1' ] && vpn_id=$unboundovervpn && [ "'"$script_type"'" = 'route-pre-down' ] && /jffs/addons/unbound/unbound_DNS_via_OVPN.sh \$vpn_id stop &" >> /jffs/scripts/openvpn-event
fi
else
echo "#!/bin/sh" > /jffs/scripts/openvpn-event
echo "" >> /jffs/scripts/openvpn-event
echo "[ "'"${dev:0:4}"'" = 'tun1' ] && vpn_id=$unboundovervpn && [ "'"$script_type"'" = 'route-up' ] && /jffs/addons/unbound/unbound_DNS_via_OVPN.sh \$vpn_id start &" >> /jffs/scripts/openvpn-event
echo "[ "'"${dev:0:4}"'" = 'tun1' ] && vpn_id=$unboundovervpn && [ "'"$script_type"'" = 'route-pre-down' ] && /jffs/addons/unbound/unbound_DNS_via_OVPN.sh \$vpn_id stop &" >> /jffs/scripts/openvpn-event
chmod 755 /jffs/scripts/openvpn-event
# backup - curl --silent --retry 3 --connect-timeout 3 --max-time 6 --retry-delay 2 --retry-all-errors "https://raw.githubusercontent.com/ViktorJp/VPNMON-R2/main/Unbound/openvpn-event" -o "/jffs/scripts/openvpn-event" && chmod 755 "/jffs/scripts/openvpn-event"
fi
# Download and create the unbound_DNS_via_OVPN.sh file - many thanks to @Martineau and @Swinson
if [ ! -f /jffs/addons/unbound/unbound_DNS_via_OVPN.sh ]; then
curl --silent --retry 3 --connect-timeout 3 --max-time 6 --retry-delay 2 --retry-all-errors "https://raw.githubusercontent.com/MartineauUK/Unbound-Asuswrt-Merlin/dev/unbound_DNS_via_OVPN.sh" -o "/jffs/addons/unbound/unbound_DNS_via_OVPN.sh" && chmod 755 "/jffs/addons/unbound/unbound_DNS_via_OVPN.sh"
# backup - curl --silent --retry 3 "https://raw.githubusercontent.com/ViktorJp/VPNMON-R2/main/Unbound/unbound_DNS_via_OVPN.sh" -o "/jffs/addons/unbound/unbound_DNS_via_OVPN.sh" && chmod 755 "/jffs/addons/unbound/unbound_DNS_via_OVPN.sh"
fi
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Unbound-over-VPN was enabled for VPNMON-R3" >> $logfile
echo -e "${CClear}"
unboundclient=$unboundovervpn
saveconfig
echo "Please reboot your router now if this is your first time or re-enabled Unbound over VPN"
read -rsp $'Press any key to continue...\n' -n1 key
continue
elif [ "$unboundovervpn" = "e" ]; then
echo -e "${CClear}\n[Exiting]"; sleep 2; break
fi
else
echo -e "${CClear}\n[Exiting]"; sleep 2; break
fi
done
;;
5)
if [ "$unboundclient" -ge 1 ]; then
echo ""
echo -e "${CRed}Unbound-over-VPN is currently enabled. If you want to enable Unbound-over-WG, please proceed to 'Disable'"
echo -e "the Unbound-over-VPN option first, then choose to enable Unbound-over-WG.${CClear}"
echo ""
sleep 3
read -rsp $'Press any key to continue...\n' -n1 key
continue
fi
while true; do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Unbound DNS Lookups over WG Integration ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate if you would like to enable an integration with Unbound which allows${CClear}"
echo -e "${InvGreen} ${CClear} you to force any DNS lookups that Unbound would normally handle, but over your WG${CClear}"
echo -e "${InvGreen} ${CClear} connection, essentially allowing you to appear as your own DNS resolver. DNS resolver${CClear}"
echo -e "${InvGreen} ${CClear} traffic generated by Unbound is unencrypted as it queries DNS Root Servers by default.${CClear}"
echo -e "${InvGreen} ${CClear} This integration encrypts your DNS Resolver traffic up to your Public WG IP address,${CClear}"
echo -e "${InvGreen} ${CClear} after which it goes unencrypted to the DNS Root Servers, preventing any ISP or other${CClear}"
echo -e "${InvGreen} ${CClear} traffic inspection snooping when sending this across your WAN connection.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} IMPORTANT: This integration will only work with 1 primary WG connection that is${CClear}"
echo -e "${InvGreen} ${CClear} designated as the connection that will carry DNS resolution traffic. This integration${CClear}"
echo -e "${InvGreen} ${CClear} will work when multiple WG connections are running, but the other WG connections may${CClear}"
echo -e "${InvGreen} ${CClear} not be able to utilize the Unbound functionality, and considered standalone. You will${CClear}"
echo -e "${InvGreen} ${CClear} need to identify one WG Client Slot that will remain on at all times. This integration${CClear}"
echo -e "${InvGreen} ${CClear} is much more elegant and simple when it compares to the Unbound over VPN integration.${CClear}"
echo -e "${InvGreen} ${CClear} Should your WG connection go down, browsing/DNS resolution will continue to function${CClear}"
echo -e "${InvGreen} ${CClear} by traversing directly out over the WAN.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${CRed}WARNING: As of around March 1 2024, the Unbound integration no longer works with the${CClear}"
echo -e "${InvGreen} ${CClear} ${CRed}NordVPN Service due to possible blocking on their end. This service continues to work${CClear}"
echo -e "${InvGreen} ${CClear} ${CRed}as advertised with other VPN Providers, like AirVPN. Use at your own risk.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${CGreen}Requirements:"
echo -e "${InvGreen} ${CClear} ${CGreen}1. Unbound must already be installed and functioning (AMTM)"
echo -e "${InvGreen} ${CClear} ${CGreen}2. One static WG Slot must be designated for Unbound-over-WG use"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${CGreen}The following will be added/modified:"
echo -e "${InvGreen} ${CClear} ${CGreen}1. A new virtual br0 interface will be created on 10.99.88.77 (added)"
echo -e "${InvGreen} ${CClear} ${CGreen}2. A new ip rule will be added to point your WG Slot to this new br0 interface (added)"
echo -e "${InvGreen} ${CClear} ${CGreen}3. The unbound.conf will have its outgoing-interface modified to 10.99.88.77 (modified)"
echo -e "${InvGreen} ${CClear} ${CGreen}4. Unbound service will be restarted.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} (Default = 0 / Disabled)${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo ""
if [ $unboundwgclient -eq 0 ]; then
unboundwgclientexp="Disabled"
else
unboundwgclientexp="Enabled, WGC$unboundwgclient"
fi
echo -e "${CClear}Current: ${CGreen}$unboundwgclientexp${CClear}"
echo ""
read -p "Please enter value (Disabled=0, WG Client=1-5)? (e=Exit): " unboundoverwg
if [ ! -d "/jffs/addons/unbound" ]; then
echo ""
echo -e "${CRed}[Unbound was not detected on this system. Exiting...]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: Unbound was not detected on this system." >> $logfile
unboundwgclient=0
saveconfig
sleep 3
continue
fi
if [ "$unboundoverwg" = "0" ] || [ "$unboundoverwg" = "1" ] || [ "$unboundoverwg" = "2" ] || [ "$unboundoverwg" = "3" ] || [ "$unboundoverwg" = "4" ] || [ "$unboundoverwg" = "5" ] || [ "$unboundoverwg" = "e" ]; then
if [ "$unboundoverwg" = "0" ]; then
# Delete all additions made to files to enable Unbound over VPN functionality
echo ""
echo -e "${CGreen}[Disabling Unbound over WG]...${CClear}"
sleep 2
# ===============================================
# === Disable Unbound-over-WG Integration ===
# === Methodology engineered by @ZebMcKayhan ===
# ===============================================
# Modify unbound.conf file - set major variables
UNBOUND_CONF="/opt/var/lib/unbound/unbound.conf"
DISABLED_LINE="#outgoing-interface: 10.0.20.1 # v1.08 Martineau Use VPN tunnel to hide Root server queries from ISP (or force WAN ONLY)"
# Check if the unbound.conf file exists and is readable.
if [ ! -r "${UNBOUND_CONF}" ]; then
echo ""
echo -e "${CRed}Error: Unbound Configuration file not found or not readable at ${UNBOUND_CONF}${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Unbound Configuration file not found or not readable at ${UNBOUND_CONF}" >> $logfile
sleep 3
continue
fi
# Create a temp file to move unbound.conf contents into
TMP_FILE="${UNBOUND_CONF}.$$"
# Remove outgoing-interface contents and replace with a dummy line
sed "s/^[[:space:]]*#*[[:space:]]*outgoing-interface:.*/${DISABLED_LINE}/g" "${UNBOUND_CONF}" > "${TMP_FILE}"
echo ""
echo -e "${CGreen}[Disabled 'outgoing-interface' and set back to default]...${CClear}"
sleep 1
# Ensure the temporary file was created and is not empty before overwriting the original
if [ ! -s "${TMP_FILE}" ]; then
echo -e "${CRed}Error: Failed to modify configuration. The temporary file is empty or was not created.${CClear}"
echo -e "${CRed}No changes have been made to ${UNBOUND_CONF}.${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Failed to modify configuration. The temporary file is empty or was not created." >> $logfile
sleep 3
continue
fi
# Move the temp file into the unbound.conf file
mv "${TMP_FILE}" "${UNBOUND_CONF}" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Modified unbound.conf file back to defaults]...${CClear}"
sleep 1
# Restart unbound service
if [ -f "/jffs/addons/unbound/unbound_manager.sh" ]; then
unbound_manager restart >/dev/null 2>&1
RESTART_STATUS=$?
if [ ${RESTART_STATUS} -eq 0 ]; then
echo ""
echo -e "${CGreen}[Unbound service restarted successfully]...${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Unbound service restarted successfully" >> $logfile
sleep 1
else
echo ""
echo -e "${CRed}[Warning: 'unbound_manager restart' command failed with status ${RESTART_STATUS}]...${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: 'unbound_manager restart' command failed with status ${RESTART_STATUS}" >> $logfile
sleep 3
fi
else
echo ""
echo -e "${CRed}[Warning: 'unbound_manager.sh' script not found. Could not restart service]...${CClear}"
echo -e "${CRed}[Please restart the unbound service manually]...${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: 'unbound_manager.sh' script not found. Could not restart service" >> $logfile
sleep 3
fi
# Remove the IP rule from VPN Director
ip rule del prio 11 >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Removed IP rule for virtual br0 interface at 10.99.88.77]...${CClear}"
sleep 1
# Remove added virtual br0 interface
ifconfig br0:UnboundWG down >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Removed virtual br0 interface at 10.99.88.77]...${CClear}"
sleep 1
# Remove Unbound failsafe in init-start
if [ -f /jffs/scripts/init-start ]; then
sed -i -e '/vpnmon-r3/d' /jffs/scripts/init-start
fi
echo ""
echo -e "${CGreen}[Unbound failsafe removed from init-start file]...${CClear}"
sleep 1
# Remove Unbound failsafe in nat-start
if [ -f /jffs/scripts/nat-start ]; then
sed -i -e '/vpnmon-r3/d' /jffs/scripts/nat-start
fi
echo ""
echo -e "${CGreen}[Unbound failsafe removed from nat-start file]...${CClear}"
sleep 1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Unbound-over-WG was removed from VPNMON-R3" >> $logfile
unboundwgclient=0
saveconfig
echo ""
echo "Please consider rebooting your router now after major Unbound and system file changes."
echo ""
sleep 3
read -rsp $'Press any key to continue...\n' -n1 key
continue
elif [ "$unboundoverwg" = "1" ] || [ "$unboundoverwg" = "2" ] || [ "$unboundoverwg" = "3" ] || [ "$unboundoverwg" = "4" ] || [ "$unboundoverwg" = "5" ]; then
if [ "$unboundoverwg" = "$unboundwgclient" ]; then
echo -e "${CClear}\n[Unbound over WGC$unboundoverwg Already Active]"; sleep 3; break
fi
if [ "$unboundoverwg" = "1" ] || [ "$unboundoverwg" = "2" ] || [ "$unboundoverwg" = "3" ] || [ "$unboundoverwg" = "4" ] || [ "$unboundoverwg" = "5" ] && [ $unboundwgclient -ge 1 ]; then
echo ""
echo -e "${CRed}When changing a WG Client Slot (from WGC #$unboundwgclient to WGC #$unboundoverwg), please proceed to 'Disable'"
echo -e "first (option 0), then choose a new WG Slot.${CClear}"
echo ""
sleep 3
read -rsp $'Press any key to continue...\n' -n1 key
continue
fi
# ===============================================
# === Create Unbound-over-WG Integration ===
# === Methodology engineered by @ZebMcKayhan ===
# ===============================================
echo ""
echo -e "${CGreen}[Enabling Unbound over WG]...${CClear}"
sleep 2
# Create new virtual br0 interface
ifconfig br0:UnboundWG 10.99.88.77 netmask 255.255.255.255 up >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Added virtual br0 interface at 10.99.88.77]...${CClear}"
sleep 1
# Point WG slot to new br0 interface for VPN Director
ip rule add from 10.99.88.77 lookup wgc$unboundoverwg prio 11 >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Pointed wgc$unboundoverwg to virtual br0 interface at 10.99.88.77]...${CClear}"
sleep 1
# Modify unbound.conf file - set major variables
UNBOUND_CONF="/opt/var/lib/unbound/unbound.conf"
ENABLED_IP="10.99.88.77"
COMMENT="# v1.08 Martineau Use VPN tunnel to hide Root server queries from ISP (or force WAN ONLY)"
# Check if the unbound.conf file exists and is readable.
if [ ! -r "${UNBOUND_CONF}" ]; then
echo ""
echo -e "${CRed}Error: Unbound Configuration file not found or not readable at ${UNBOUND_CONF}${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Unbound Configuration file not found or not readable at ${UNBOUND_CONF}" >> $logfile
sleep 3
continue
fi
# Create a temp file to move unbound.conf contents into
TMP_FILE="${UNBOUND_CONF}.$$"
# Create new outgoing-interface contents
ENABLED_LINE="outgoing-interface: ${ENABLED_IP} ${COMMENT}"
sed "s/^[[:space:]]*#*[[:space:]]*outgoing-interface:.*/${ENABLED_LINE}/g" "${UNBOUND_CONF}" > "${TMP_FILE}"
# Ensure the temporary file was created and is not empty before overwriting the original
if [ ! -s "${TMP_FILE}" ]; then
echo -e "${CRed}Error: Failed to modify configuration. The temporary file is empty or was not created.${CClear}"
echo -e "${CRed}No changes have been made to ${UNBOUND_CONF}.${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Failed to modify configuration. The temporary file is empty or was not created." >> $logfile
sleep 3
continue
fi
# Move the temp file into the unbound.conf file
mv "${TMP_FILE}" "${UNBOUND_CONF}" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Modified unbound.conf file 'outgoing-interface: 10.99.88.77']...${CClear}"
sleep 1
# Restart unbound service
if [ -f "/jffs/addons/unbound/unbound_manager.sh" ]; then
unbound_manager restart >/dev/null 2>&1
RESTART_STATUS=$?
if [ ${RESTART_STATUS} -eq 0 ]; then
echo ""
echo -e "${CGreen}[Unbound service restarted successfully]...${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Unbound service restarted successfully" >> $logfile
sleep 1
else
echo ""
echo -e "${CRed}[Warning: 'unbound_manager restart' command failed with status ${RESTART_STATUS}]...${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: 'unbound_manager restart' command failed with status ${RESTART_STATUS}" >> $logfile
sleep 3
fi
else
echo ""
echo -e "${CRed}[Warning: 'unbound_manager.sh' script not found. Could not restart service]...${CClear}"
echo -e "${CRed}[Please restart the unbound service manually]...${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: 'unbound_manager.sh' script not found. Could not restart service" >> $logfile
sleep 3
fi
echo ""
echo -e "${CGreen}[Adding Unbound Failsafe... Modifying init-start file]...${CClear}"
sleep 1
# Modify or create init-start to ensure survivability after a router reboot
if [ -f /jffs/scripts/init-start ]; then
if ! grep -q -F "sh /jffs/scripts/vpnmon-r3.sh -uowginitstart" /jffs/scripts/init-start; then
echo "sh /jffs/scripts/vpnmon-r3.sh -uowginitstart # Added by vpnmon-r3" >> /jffs/scripts/init-start
fi
else
echo "#!/bin/sh" > /jffs/scripts/init-start
echo "" >> /jffs/scripts/init-start
echo "sh /jffs/scripts/vpnmon-r3.sh -uowginitstart # Added by vpnmon-r3" >> /jffs/scripts/init-start
chmod 755 /jffs/scripts/init-start
fi
echo ""
echo -e "${CGreen}[Adding Unbound Failsafe... Modifying nat-start file]...${CClear}"
sleep 1
# Modify or create nat-start to ensure survivability after a router reboot
if [ -f /jffs/scripts/nat-start ]; then
if ! grep -q -F "sh /jffs/scripts/vpnmon-r3.sh -uowgnatstart" /jffs/scripts/nat-start; then
echo "sh /jffs/scripts/vpnmon-r3.sh -uowgnatstart # Added by vpnmon-r3" >> /jffs/scripts/nat-start
fi
else
echo "#!/bin/sh" > /jffs/scripts/nat-start
echo "" >> /jffs/scripts/nat-start
echo "sh /jffs/scripts/vpnmon-r3.sh -uowgnatstart # Added by vpnmon-r3" >> /jffs/scripts/nat-start
chmod 755 /jffs/scripts/nat-start
fi
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Unbound-over-WG was enabled for VPNMON-R3" >> $logfile
echo -e "${CClear}"
unboundwgclient=$unboundoverwg
saveconfig
echo ""
echo "Please consider rebooting your router now if this is your first time or have re-enabled Unbound-over-WG"
echo ""
sleep 3
read -rsp $'Press any key to continue...\n' -n1 key
continue
elif [ "$unboundoverwg" = "e" ]; then
echo -e "${CClear}\n[Exiting]"; sleep 2; break
fi
else
echo -e "${CClear}\n[Exiting]"; sleep 2; break
fi
done
;;
6)
if [ "$unboundclient" != "0" ] || [ "$unboundwgclient" != "0" ]; then
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Show Expanded Unbound IP Information ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate below if you would like to show your full Unbound DNS Resolver IP on-${CClear}"
echo -e "${InvGreen} ${CClear} screen, or just an abbreviated color-coded indicator. Showing a full IP may in some${CClear}"
echo -e "${InvGreen} ${CClear} cases help with troubleshooting.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Use 0 to Disable, 1 to Enable. (Default = 0)"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo
echo -e "${CClear}Current: ${CGreen}$unboundshowipdisp${CClear}" ; echo
read -p "Please Choose? (Disable = 0, Enable = 1, e=Exit): " newunboundshowip
if [ "$newunboundshowip" = "0" ]
then
unboundshowip=0
unboundshowipdisp="Disabled"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Expanded Unbound IP Information Disabled" >> $logfile
saveconfig
elif [ "$newunboundshowip" = "1" ]
then
unboundshowip=1
unboundshowipdisp="Enabled"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Expanded Unbound IP Information Enabled" >> $logfile
saveconfig
elif [ "$newunboundshowip" = "e" ]
then
echo -e "\n[Exiting]"; sleep 2
else
previousValue="$unboundshowip"
unboundshowip="${unboundshowip:=0}"
unboundshowipdisp="$([ "$unboundshowip" = "0" ] && echo "Disabled" || echo "Enabled")"
[ "$unboundshowip" != "$previousValue" ] && \
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Expanded Unbound IP Information Disabled" >> $logfile
saveconfig
fi
fi
;;
7)
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Refresh Custom Server Lists on -RESET Switch ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate below if you would like to automatically refresh your custom Server${CClear}"
echo -e "${InvGreen} ${CClear} Lists specified under the Edit/Run Server List Automation menu. This function will${CClear}"
echo -e "${InvGreen} ${CClear} run any defined CURL+JQ statements you have configured and save them back to your${CClear}"
echo -e "${InvGreen} ${CClear} Client Slot Server List files that will be used for VPN connections.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Use 0 to Disable, 1 to Enable. (Default = 0)"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo
echo -e "${CClear}Current: ${CGreen}$refreshserverlistsdisp${CClear}" ; echo
read -p "Please Choose? (Disable = 0, Enable = 1, e=Exit): " newRefreshServerList
if [ "$newRefreshServerList" = "0" ]
then
refreshserverlists=0
refreshserverlistsdisp="Disabled"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom Server Lists Disabled on -RESET Switch" >> $logfile
saveconfig
elif [ "$newRefreshServerList" = "1" ]
then
refreshserverlists=1
refreshserverlistsdisp="Enabled"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom Server Lists Enabled on -RESET Switch" >> $logfile
saveconfig
elif [ "$newRefreshServerList" = "e" ]
then
echo -e "\n[Exiting]"; sleep 2
else
previousValue="$refreshserverlists"
refreshserverlists="${refreshserverlists:=0}"
refreshserverlistsdisp="$([ "$refreshserverlists" = "0" ] && echo "Disabled" || echo "Enabled")"
[ "$refreshserverlists" != "$previousValue" ] && \
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom Server Lists $refreshserverlistsdisp on -RESET Switch" >> $logfile
saveconfig
fi
;;
8)
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Provide WAN/Dual WAN Monitoring Functionality ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate below if you would like to monitor your WAN/Dual WAN connection for${CClear}"
echo -e "${InvGreen} ${CClear} connectivity issues that may impact your VPN connection. This functionality will${CClear}"
echo -e "${InvGreen} ${CClear} determine if your WAN connection is viable, and upon determining that the WAN is${CClear}"
echo -e "${InvGreen} ${CClear} down, VPNMON-R3 will kill all VPN connections and continue testing for a valid WAN${CClear}"
echo -e "${InvGreen} ${CClear} connection until it can restore your VPN connections.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Use 0 to Disable, 1 to Enable. (Default = 0)"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo
echo -e "${CClear}Current: ${CGreen}$monitorwandisp${CClear}" ; echo
read -p "Please Choose? (Disable = 0, Enable = 1, e=Exit): " newMonitorWAN
if [ "$newMonitorWAN" = "0" ]
then
monitorwan=0
monitorwandisp="Disabled"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: WAN Monitoring Disabled" >> $logfile
saveconfig
elif [ "$newMonitorWAN" = "1" ]
then
monitorwan=1
monitorwandisp="Enabled"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: WAN Monitoring Enabled" >> $logfile
saveconfig
elif [ "$newMonitorWAN" = "e" ]
then
echo -e "\n[Exiting]"; sleep 2
else
previousValue="$monitorwan"
monitorwan="${monitorwan:=0}"
monitorwandisp="$([ "$monitorwan" = "0" ] && echo "Disabled" || echo "Enabled")"
[ "$monitorwan" != "$previousValue" ] && \
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: WAN Monitoring $monitorwandisp" >> $logfile
saveconfig
fi
;;
9)
while true
do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Enable/Disable VPN/WG Slot Monitoring and Display ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate whether you want to enable or disable VPN/WG Slots from being${CClear}"
echo -e "${InvGreen} ${CClear} monitored and shown on the main VPNMON-R3 UI. This setting is meant for those${CClear}"
echo -e "${InvGreen} ${CClear} who are only running VPN or only WG on their router, and do not want to display${CClear}"
echo -e "${InvGreen} ${CClear} one or the other to only show relevant info.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Use the corresponding ${CGreen}()${CClear} key to enable/disable monitoring for each.${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
if [ "$useovpn" = "1" ]; then useovpnDisp="${CGreen}Y${CCyan}"; else useovpn=0; useovpnDisp="${CRed}N${CCyan}"; fi
if [ "$usewg" = "1" ]; then usewgDisp="${CGreen}Y${CCyan}"; else usewg=0; usewgDisp="${CRed}N${CCyan}"; fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} OpenVPN${CClear} ${CGreen}(1) -${CClear} $useovpnDisp${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}Wireguard${CClear} ${CGreen}(2) -${CClear} $usewgDisp${CClear}"
echo ""
read -p "Please select? (1-2, e=Exit): " SelectSlot
case $SelectSlot in
1)
if [ "$unboundclient" = "0" ]; then
if [ "$useovpn" = "0" ]; then
useovpn=1
useovpnDisp="${CGreen}Y${CCyan}"
elif [ "$useovpn" = "1" ]; then
useovpn=0; useovpnDisp="${CRed}N${CCyan}"
fi
else
echo -e "${CClear}\n[Unable to disable VPN. Unbound Active on Slot VPN$unboundclient]"; sleep 3
fi;;
2)
if [ "$usewg" = "0" ]; then
usewg=1
usewgDisp="${CGreen}Y${CCyan}"
elif [ "$usewg" = "1" ]; then
usewg=0
usewgDisp="${CRed}N${CCyan}"
fi;;
[Ee])
saveconfig
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN/WG Client Slot Monitoring/Display configuration saved" >> $logfile
timer="$timerloop"
break;;
esac
done
;;
10)
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Whitelist VPN Server IP Lists in Skynet ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate below if you would like to whitelist your VPN Server IP lists in${CClear}"
echo -e "${InvGreen} ${CClear} the Skynet Firewall. This provides for better stability in connecting to your VPN${CClear}"
echo -e "${InvGreen} ${CClear} provider, as there have been occasions where the Skynet blacklist will prevent${CClear}"
echo -e "${InvGreen} ${CClear} connections to your VPN Servers. This could cause a disruption in being able to${CClear}"
echo -e "${InvGreen} ${CClear} maintain a stable VPN connection. Note: Skynet must already be installed and${CClear}"
echo -e "${InvGreen} ${CClear} operational for this functionality to work.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Use 0 to Disable, 1 to Enable. (Default = 0)"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo
echo -e "${CClear}Current: ${CGreen}$updateskynetdisp${CClear}" ; echo
read -p "Please Choose? (Disable = 0, Enable = 1, e=Exit): " newUpdateSkyNet
if [ "$newUpdateSkyNet" = "1" ]
then
updateskynet=1
updateskynetdisp="Enabled"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN Server IP Skynet Whitelisting Enabled" >> $logfile
saveconfig
elif [ "$newUpdateSkyNet" = "0" ]
then
updateskynet=0
updateskynetdisp="Disabled"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN Server IP Skynet Whitelisting Disabled" >> $logfile
saveconfig
elif [ "$newUpdateSkyNet" = "e" ]
then
echo -e "\n[Exiting]"; sleep 2
else
previousValue="$updateskynet"
updateskynet="${updateskynet:=0}"
updateskynetdisp="$([ "$updateskynet" = "0" ] && echo "Disabled" || echo "Enabled")"
[ "$updateskynet" != "$previousValue" ] && \
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN Server IP Skynet Whitelisting $updateskynetdisp" >> $logfile
saveconfig
fi
;;
[Ee]) echo -e "${CClear}\n[Exiting]"; sleep 2; break ;;
11)
amtmevents
source "$config"
;;
12)
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Reset spdMerlin Interfaces on VPN Reset ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate below if you would like to reset your spdMerlin Interfaces each${CClear}"
echo -e "${InvGreen} ${CClear} time VPNMON-R3 resets. This functionality will allow VPNMON-R3 to update spdMerlin${CClear}"
echo -e "${InvGreen} ${CClear} whenever a VPN reset occurs. SpdMerlin will then know which interfaces are active${CClear}"
echo -e "${InvGreen} ${CClear} in order to run manual or automated speedtests from.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Use 0 to Disable, 1 to Enable. (Default = 0)"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo
echo -e "${CClear}Current: ${CGreen}$rstspdmerlindisp${CClear}" ; echo
read -p "Please Choose? (Disable = 0, Enable = 1, e=Exit): " newrstspdmerlin
if [ "$newrstspdmerlin" = "0" ]
then
rstspdmerlin=0
rstspdmerlindisp="Disabled"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: spdMerlin Interface Reset Disabled" >> $logfile
saveconfig
elif [ "$newrstspdmerlin" = "1" ]
then
rstspdmerlin=1
rstspdmerlindisp="Enabled"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: spdMerlin Interface Reset Enabled" >> $logfile
saveconfig
elif [ "$newrstspdmerlin" = "e" ]
then
echo -e "\n[Exiting]"; sleep 2
else
previousValue="$rstspdmerlin"
rstspdmerlin="${rstspdmerlin:=0}"
rstspdmerlindisp="$([ "$rstspdmerlin" = "0" ] && echo "Disabled" || echo "Enabled")"
[ "$rstspdmerlin" != "$previousValue" ] && \
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: spdMerlin Interface Reset $monitorwandisp" >> $logfile
saveconfig
fi
;;
13)
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Server List Item Selection Method ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate below if you would like to use a Random or Sequential method to pick${CClear}"
echo -e "${InvGreen} ${CClear} your next available Server List item to populate your VPN/WG slots. When choosing${CClear}"
echo -e "${InvGreen} ${CClear} 'Sequential', please know that this method will use a Round-Robin style method, and${CClear}"
echo -e "${InvGreen} ${CClear} will start at the beginning of your list again after it has used the last entry in${CClear}"
echo -e "${InvGreen} ${CClear} your list. The 'Sequential' method is a preferred method to use for those using${CClear}"
echo -e "${InvGreen} ${CClear} shorter lists of servers, as the chances of selecting the same server is much greater${CClear}"
echo -e "${InvGreen} ${CClear} when using a 'Random' method against these short lists.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} (Default = 0 - Random)"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo
echo -e "${CClear}Current: ${CGreen}$selectionmethoddisp${CClear}" ; echo
read -p "Please Choose? (Random = 0, Sequential = 1, e=Exit): " newselectionmethod
if [ "$newselectionmethod" = "0" ]
then
selectionmethod=0
newselectionmethoddisp="Random"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Server List Item Selection Method set to Random" >> $logfile
saveconfig
elif [ "$newselectionmethod" = "1" ]
then
selectionmethod=1
newselectionmethoddisp="Sequential"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Server List Item Selection Method set to Sequential" >> $logfile
saveconfig
elif [ "$newselectionmethod" = "e" ]
then
echo -e "\n[Exiting]"; sleep 2
else
previousValue="$selectionmethod"
selectionmethod="${selectionmethod:=0}"
selectionmethoddisp="$([ "$selectionmethod" = "0" ] && echo "Random" || echo "Sequential")"
[ "$selectionmethod" != "$previousValue" ] && \
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Server List Item Selection Method set to $selectionmethoddisp" >> $logfile
saveconfig
fi
;;
14)
while true
do
if [ "$bwdisp" = "1" ]; then bwdispval="Mbps"; else bwdispval="MB"; fi
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Connection Throughput Threshold Selections ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate below how you would like to configure the visual representation of${CClear}"
echo -e "${InvGreen} ${CClear} the Connection Throughput that are displayed in the main UI for each active OVPN/WG${CClear}"
echo -e "${InvGreen} ${CClear} Connection. This is very dependent on your own preferences and the total amount of${CClear}"
echo -e "${InvGreen} ${CClear} bandwidth your have at your disposal. These ranges represent the different colors${CClear}"
echo -e "${InvGreen} ${CClear} ${CGreen}Green${CClear} / ${CYellow}Yellow${CClear} / ${CRed}Red ${CClear} to provide visual indicators of the current speeds your${CClear}"
echo -e "${InvGreen} ${CClear} connections are experiencing at that moment. You are able to choose different sets${CClear}"
echo -e "${InvGreen} ${CClear} of RX/TX thresholds for those using asymmetric internet connections.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Use the corresponding ${CGreen}()${CClear} key to modify the different thresholds.${CClear}"
echo -e "${InvGreen} ${CClear} RX Defaults: 0->100 / 100->250 / 250->Max -- TX Defaults: 0->15 / 15->25 / 25->Max${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${InvDkGray}${CWhite} RX (Receive) Thresholds ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CClear} ${InvGreen}${CWhite} Low Utilization ${CClear} - 0$bwdispval ---> ${CGreen}(1) ${lowutilspd}$bwdispval${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CClear} ${InvYellow}${CBlack} Med Utilization ${CClear} - ${lowutilspd}$bwdispval ---> ${CGreen}(2) ${medutilspd}$bwdispval${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CClear} ${InvRed}${CWhite} High Utilization ${CClear} - ${medutilspd}$bwdispval ---> Max Limit${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${InvDkGray}${CWhite} TX (Transmit) Thresholds ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CClear} ${InvGreen}${CWhite} Low Utilization ${CClear} - 0$bwdispval ---> ${CGreen}(3) ${lowutilspdup}$bwdispval${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CClear} ${InvYellow}${CBlack} Med Utilization ${CClear} - ${lowutilspdup}$bwdispval ---> ${CGreen}(4) ${medutilspdup}$bwdispval${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CClear} ${InvRed}${CWhite} High Utilization ${CClear} - ${medutilspdup}$bwdispval ---> Max Limit${CClear}"
echo ""
read -p "Please select? (1-4, e=Exit): " SelectSlot
case $SelectSlot in
1)
echo ""
read -p "Please enter the upper 'Low RX Utilization' range (in $bwdispval)? (Default = 100): " lowutilspdchoice
if [ "$lowutilspdchoice" -le 0 ] || [ "$lowutilspdchoice" -ge "$medutilspd" ]
then
echo ""; echo -e "${CRed}ERROR: Your upper 'Low RX Utilization' range must be greater than 0 and less than $medutilspd.${CClear}"; echo ""
sleep 3
continue
elif [ -z "$lowutilspdchoice" ]
then
lowutilspd=100
continue
else
lowutilspd=$lowutilspdchoice
continue
fi;;
2)
echo ""
read -p "Please enter the upper 'Med RX Utilization' range (in $bwdispval)? (Default = 250): " medutilspdchoice
if [ "$medutilspdchoice" -le "$lowutilspd" ]
then
echo ""; echo -e "${CRed}ERROR: Your upper 'Med RX Utilization' range must be greater than $lowutilspd.${CClear}"; echo ""
sleep 3
continue
elif [ -z "$medutilspdchoice" ]
then
medutilspd=250
continue
else
medutilspd=$medutilspdchoice
continue
fi;;
3)
echo ""
read -p "Please enter the upper 'Low TX Utilization' range (in $bwdispval)? (Default = 15): " lowutilspdupchoice
if [ "$lowutilspdupchoice" -le 0 ] || [ "$lowutilspdupchoice" -ge "$medutilspdup" ]
then
echo ""; echo -e "${CRed}ERROR: Your upper 'Low TX Utilization' range must be greater than 0 and less than $medutilspdup.${CClear}"; echo ""
sleep 3
continue
elif [ -z "$lowutilspdupchoice" ]
then
lowutilspdup=15
continue
else
lowutilspdup=$lowutilspdupchoice
continue
fi;;
4)
echo ""
read -p "Please enter the upper 'Med TX Utilization' range (in $bwdispval)? (Default = 25): " medutilspdupchoice
if [ "$medutilspdupchoice" -le "$lowutilspdup" ]
then
echo ""; echo -e "${CRed}ERROR: Your upper 'Med TX Utilization' range must be greater than $lowutilspdup.${CClear}"; echo ""
sleep 3
continue
elif [ -z "$medutilspdupchoice" ]
then
medutilspdup=25
continue
else
medutilspdup=$medutilspdupchoice
continue
fi;;
[Ee])
saveconfig
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Connection Speed Threshold Selections Set -- RX: 0->$lowutilspd->$medutilspd->Max | TX: 0->$lowutilspdup->$medutilspdup->Max" >> $logfile
timer="$timerloop"
break;;
esac
done
;;
15)
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Connection Throughput Display Method ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate below what kind of information you would like to display in the${CClear}"
echo -e "${InvGreen} ${CClear} Connection Throughput field within the main VPNMON-R3 UI? You have the choice${CClear}"
echo -e "${InvGreen} ${CClear} between displaying Average Throughput in Mbps (average speed across tunnels), ${CClear}"
echo -e "${InvGreen} ${CClear} or Total Throughput in MB (total amount of data sent/received across tunnels),${CClear}"
echo -e "${InvGreen} ${CClear} which is calculated each time your timer restarts.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Use 1 for Average Throughput (in Mbps), 2 for Total Throughput (in MB). (Default = 1)"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo
echo -e "${CClear}Current: ${CGreen}$throughputmethoddisp${CClear}" ; echo
read -p "Please Choose? (Avg in Mbps = 1, Ttl in MB = 2, e=Exit): " newthroughputmethod
if [ "$newthroughputmethod" = "1" ]
then
bwdisp=1
throughputmethoddisp="Average Throughput (in Mbps)"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Connection Throughput Display Method set to: Average Throughput (in Mbps)" >> $logfile
saveconfig
elif [ "$newthroughputmethod" = "2" ]
then
bwdisp=2
throughputmethoddisp="Total Throughput (in MB)"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Connection Throughput Display Method set to: Total Throughput (in MB)" >> $logfile
saveconfig
elif [ "$newthroughputmethod" = "e" ]
then
echo -e "\n[Exiting]"; sleep 2
else
bwdisp=1
throughputmethoddisp="Average Throughput (in Mbps)"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Connection Throughput Display Method set to: Average Throughput (in Mbps)" >> $logfile
saveconfig
fi
;;
esac
done
}
# -------------------------------------------------------------------------------------------------------------------------
# uowginitstart is a function that initializes the virtual br0 interface when called from init-start
uowginitstart()
{
if [ -f "$config" ]
then
source "$config"
# Remove added virtual br0 interface if it already exists
ifconfig br0:UnboundWG down >/dev/null 2>&1
# Addvirtual br0 interface
ifconfig br0:UnboundWG 10.99.88.77 netmask 255.255.255.255 up >/dev/null 2>&1
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# uowgnatstart is a function that ties the virtual br0 interface to the assigned wgc slot
uowgnatstart()
{
if [ -f "$config" ]
then
source "$config"
# Remove ip rule if it already exists
ip rule del prio 11 >/dev/null 2>&1
# Add ip rule to tie br0 interface with assigned wgc slot
ip rule add from 10.99.88.77 lookup wgc$unboundwgclient prio 11 >/dev/null 2>&1
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# vupdate is a function that provides a UI to check for script updates and allows you to install the latest version...
vupdate()
{
updatecheck # Check for the latest version from source repository
while true; do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} VPNMON-R3 Update Utility ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} This utility allows you to check, download and install updates"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo ""
echo -e "Current Version: ${CGreen}$version${CClear}"
echo -e "Updated Version: ${CGreen}$DLversion${CClear}"
echo ""
if [ "$version" = "$DLversion" ]
then
echo -e "You are on the latest version! Would you like to download anyways? This will overwrite${CClear}"
echo -e "your local copy with the current build.${CClear}"
if promptyn "[y/n]: "; then
echo ""
echo -e "\nDownloading VPNMON-R3 ${CGreen}v$DLversion${CClear}"
curl --silent --retry 3 --connect-timeout 3 --max-time 5 --retry-delay 2 --retry-all-errors --fail "https://raw.githubusercontent.com/ViktorJp/VPNMON-R3/main/vpnmon-r3.sh" -o "/jffs/scripts/vpnmon-r3.sh" && chmod 755 "/jffs/scripts/vpnmon-r3.sh"
echo ""
echo -e "Download successful!${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Successfully downloaded and installed VPNMON-R3 v$DLversion" >> $logfile
echo ""
read -rsp $'Press any key to restart VPNMON-R3...\n' -n1 key
exec /jffs/scripts/vpnmon-r3.sh -setup
else
echo ""
echo ""
echo -e "Exiting Update Utility...${CClear}"
sleep 1
return
fi
else
echo -e "Score! There is a new version out there! Would you like to update?${CClear}"
if promptyn "[y/n]: "; then
echo ""
echo -e "\nDownloading VPNMON-R3 ${CGreen}v$DLversion${CClear}"
curl --silent --retry 3 --connect-timeout 3 --max-time 6 --retry-delay 2 --retry-all-errors --fail "https://raw.githubusercontent.com/ViktorJp/VPNMON-R3/main/vpnmon-r3.sh" -o "/jffs/scripts/vpnmon-r3.sh" && chmod 755 "/jffs/scripts/vpnmon-r3.sh"
echo ""
echo -e "Download successful!${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Successfully downloaded and installed VPNMON-R3 v$DLversion" >> $logfile
echo ""
read -rsp $'Press any key to restart VPNMON-R3...\n' -n1 key
exec /jffs/scripts/vpnmon-r3.sh -setup
else
echo ""
echo ""
echo -e "Exiting Update Utility...${CClear}"
sleep 1
return
fi
fi
done
}
# -------------------------------------------------------------------------------------------------------------------------
# updatecheck is a function that downloads the latest update version file, and compares it with what's currently installed
updatecheck()
{
# Download the latest version file from the source repository
curl --silent --retry 3 --connect-timeout 3 --max-time 6 --retry-delay 2 --retry-all-errors --fail "https://raw.githubusercontent.com/ViktorJp/VPNMON-R3/main/version.txt" -o "/jffs/addons/vpnmon-r3.d/version.txt"
if [ -f $dlverpath ]
then
# Read in its contents for the current version file
DLversion=$(cat $dlverpath)
# Compare the new version with the old version and log it
if [ "$beta" = "1" ]; then # Check if Dev/Beta Mode is enabled and disable notification message
UpdateNotify=0
elif [ "$DLversion" != "$version" ]; then
DLversionPF=$(printf "%-8s" $DLversion)
versionPF=$(printf "%-8s" $version)
UpdateNotify="${InvYellow} ${InvDkGray}${CWhite} Update available: v$versionPF -> v$DLversionPF ${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: A new update (v$DLversion) is available to download" >> $logfile
else
UpdateNotify=0
fi
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# vuninstall is a function that uninstalls and removes all traces of vpnmon-r3 from your router...
vuninstall()
{
while true; do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Uninstall Utility ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} You are about to uninstall VPNMON-R3! This action is irreversible."
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo ""
echo -e "Do you wish to proceed?${CClear}"
if promptyn "(y/n): "; then
echo ""
echo -e "\nAre you sure? Please type 'y' to validate you wish to proceed.${CClear}"
if promptyn "(y/n): "; then
clear
#Remove and uninstall files/directories
rm -f -r /jffs/addons/vpnmon-r3.d
rm -f /jffs/scripts/vpnmon-r3.sh
sed -i -e '/vpnmon-r3.sh/d' /jffs/scripts/services-start
cru d RunVPNMONR3reset
echo ""
echo -e "\nVPNMON-R3 has been uninstalled...${CClear}"
echo ""
exit 0
else
echo ""
echo -e "\nExiting Uninstall Utility...${CClear}"
sleep 1
return
fi
else
echo ""
echo -e "\nExiting Uninstall Utility...${CClear}"
sleep 1
return
fi
done
}
# -------------------------------------------------------------------------------------------------------------------------
# vlogs is a function that calls the nano text editor to view the BACKUPMON log file
vlogs()
{
export TERM=linux
nano +999999 --linenumbers $logfile
timer="$timerloop"
}
# -------------------------------------------------------------------------------------------------------------------------
# vpnslots lets you pick which vpn slot numbers are being monitored by vpnmon-r3
vpnslots()
{
while true
do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} VPN/WG Client Slot Monitoring ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate which VPN/WG slots you would like VPNMON-R3 to monitor, or to${CClear}"
echo -e "${InvGreen} ${CClear} alternatively reset the connected time on an active VPN/WG connection. Monitoring${CClear}"
echo -e "${InvGreen} ${CClear} a VPN/WG connection ensures that VPNMON-R3 will actively keep a watch over it, and${CClear}"
echo -e "${InvGreen} ${CClear} will reset it should the connection go down, or ping times go above set limits.${CClear}"
echo -e "${InvGreen} ${CClear} A Connection Time reset may be necessary for WG connections at times, as a router${CClear}"
echo -e "${InvGreen} ${CClear} reboot will start the WG tunnels up before VPNMON-R3 is able to start, and is not${CClear}"
echo -e "${InvGreen} ${CClear} aware that they were restarted.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Use the corresponding ${CGreen}()${CClear} key to enable/disable monitoring or to reset the time${CClear}"
echo -e "${InvGreen} ${CClear} for each connected slot:${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
if [ "$availableslots" = "1 2" ]
then
if [ "$VPN1" = "1" ]; then VPN1Disp="${CGreen}Y${CCyan}"; else VPN1=0; VPN1Disp="${CRed}N${CCyan}"; fi
if [ "$VPN2" = "1" ]; then VPN2Disp="${CGreen}Y${CCyan}"; else VPN2=0; VPN2Disp="${CRed}N${CCyan}"; fi
currtime=$(date +%s)
if [ "$VPNTIMER1" -gt 0 ]; then timediffvpn1=$((currtime-VPNTIMER1)); sincelastresetvpn1=$(printf '%dd %02dh:%02dm\n' $(($timediffvpn1/86400)) $(($timediffvpn1%86400/3600)) $(($timediffvpn1%3600/60))); else sincelastresetvpn1="${CDkGray}Disabled"; fi
if [ "$VPNTIMER2" -gt 0 ]; then timediffvpn2=$((currtime-VPNTIMER2)); sincelastresetvpn2=$(printf '%dd %02dh:%02dm\n' $(($timediffvpn2/86400)) $(($timediffvpn2%86400/3600)) $(($timediffvpn2%3600/60))); else sincelastresetvpn2="${CDkGray}Disabled"; fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${CWhite} Monitored? Y/N ${CClear}|${CWhite} Time Connected / Reset? ${CClear}"
echo -e "${InvGreen} ${CClear} |"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN1${CClear} ${CGreen}(1) -${CClear} $VPN1Disp | ${CGreen}(!) -${CClear} $sincelastresetvpn1 ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN2${CClear} ${CGreen}(2) -${CClear} $VPN2Disp | ${CGreen}(@) -${CClear} $sincelastresetvpn2 ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo ""
read -p "Please select? (1-2, !-@, e=Exit): " SelectSlot
case $SelectSlot in
1) currvpn1state="$(_VPN_GetClientState_ "1")"; if [ "$VPN1" = "0" ] && [ "$currvpn1state" -eq 2 ]; then VPN1=1; VPNTIMER1=$(date +%s); VPN1Disp="${CGreen}Y${CCyan}"; elif [ "$VPN1" = "1" ]; then VPN1=0; VPNTIMER2=0; VPN1Disp="${CRed}N${CCyan}"; fi;;
2) currvpn2state="$(_VPN_GetClientState_ "2")"; if [ "$VPN2" = "0" ] && [ "$currvpn2state" -eq 2 ]; then VPN2=1; VPNTIMER2=$(date +%s); VPN2Disp="${CGreen}Y${CCyan}"; elif [ "$VPN2" = "1" ]; then VPN2=0; VPNTIMER2=0; VPN2Disp="${CRed}N${CCyan}"; fi;;
[\!]) if [ "$VPN1" = "1" ]; then VPNTIMER1=$(date +%s); else VPNTIMER1=0; fi;;
[\@]) if [ "$VPN2" = "1" ]; then VPNTIMER2=$(date +%s); else VPNTIMER2=0; fi;;
[Ee])
{ echo 'VPN1='$VPN1
echo 'VPN2='$VPN2
} > /jffs/addons/vpnmon-r3.d/vr3clients.txt
{ echo 'VPNTIMER1='$VPNTIMER1
echo 'VPNTIMER2='$VPNTIMER2
} > /jffs/addons/vpnmon-r3.d/vr3timers.txt
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN/WG Client Slot Monitoring configuration / Connection Time Resets Saved" >> $logfile
timer="$timerloop"
break;;
esac
elif [ "$availableslots" = "1 2 3 4 5" ]
then
if [ "$VPN1" = "1" ]; then VPN1Disp="${CGreen}Y${CClear}"; else VPN1=0; VPN1Disp="${CRed}N${CClear}"; fi
if [ "$VPN2" = "1" ]; then VPN2Disp="${CGreen}Y${CClear}"; else VPN2=0; VPN2Disp="${CRed}N${CClear}"; fi
if [ "$VPN3" = "1" ]; then VPN3Disp="${CGreen}Y${CClear}"; else VPN3=0; VPN3Disp="${CRed}N${CClear}"; fi
if [ "$VPN4" = "1" ]; then VPN4Disp="${CGreen}Y${CClear}"; else VPN4=0; VPN4Disp="${CRed}N${CClear}"; fi
if [ "$VPN5" = "1" ]; then VPN5Disp="${CGreen}Y${CClear}"; else VPN5=0; VPN5Disp="${CRed}N${CClear}"; fi
if [ "$WG1" = "1" ]; then WG1Disp="${CGreen}Y${CClear}"; else WG1=0; WG1Disp="${CRed}N${CClear}"; fi
if [ "$WG2" = "1" ]; then WG2Disp="${CGreen}Y${CClear}"; else WG2=0; WG2Disp="${CRed}N${CClear}"; fi
if [ "$WG3" = "1" ]; then WG3Disp="${CGreen}Y${CClear}"; else WG3=0; WG3Disp="${CRed}N${CClear}"; fi
if [ "$WG4" = "1" ]; then WG4Disp="${CGreen}Y${CClear}"; else WG4=0; WG4Disp="${CRed}N${CClear}"; fi
if [ "$WG5" = "1" ]; then WG5Disp="${CGreen}Y${CClear}"; else WG5=0; WG5Disp="${CRed}N${CClear}"; fi
currtime=$(date +%s)
if [ "$VPNTIMER1" -gt 0 ]; then timediffvpn1=$((currtime-VPNTIMER1)); sincelastresetvpn1=$(printf '%dd %02dh:%02dm\n' $(($timediffvpn1/86400)) $(($timediffvpn1%86400/3600)) $(($timediffvpn1%3600/60))); else sincelastresetvpn1="${CDkGray}Disabled"; fi
if [ "$VPNTIMER2" -gt 0 ]; then timediffvpn2=$((currtime-VPNTIMER2)); sincelastresetvpn2=$(printf '%dd %02dh:%02dm\n' $(($timediffvpn2/86400)) $(($timediffvpn2%86400/3600)) $(($timediffvpn2%3600/60))); else sincelastresetvpn2="${CDkGray}Disabled"; fi
if [ "$VPNTIMER3" -gt 0 ]; then timediffvpn3=$((currtime-VPNTIMER3)); sincelastresetvpn3=$(printf '%dd %02dh:%02dm\n' $(($timediffvpn3/86400)) $(($timediffvpn3%86400/3600)) $(($timediffvpn3%3600/60))); else sincelastresetvpn3="${CDkGray}Disabled"; fi
if [ "$VPNTIMER4" -gt 0 ]; then timediffvpn4=$((currtime-VPNTIMER4)); sincelastresetvpn4=$(printf '%dd %02dh:%02dm\n' $(($timediffvpn4/86400)) $(($timediffvpn4%86400/3600)) $(($timediffvpn4%3600/60))); else sincelastresetvpn4="${CDkGray}Disabled"; fi
if [ "$VPNTIMER5" -gt 0 ]; then timediffvpn5=$((currtime-VPNTIMER5)); sincelastresetvpn5=$(printf '%dd %02dh:%02dm\n' $(($timediffvpn5/86400)) $(($timediffvpn5%86400/3600)) $(($timediffvpn5%3600/60))); else sincelastresetvpn5="${CDkGray}Disabled"; fi
if [ "$WGTIMER1" -gt 0 ]; then timediffwg1=$((currtime-WGTIMER1)); sincelastresetwg1=$(printf '%dd %02dh:%02dm\n' $(($timediffwg1/86400)) $(($timediffwg1%86400/3600)) $(($timediffwg1%3600/60))); else sincelastresetwg1="${CDkGray}Disabled"; fi
if [ "$WGTIMER2" -gt 0 ]; then timediffwg2=$((currtime-WGTIMER2)); sincelastresetwg2=$(printf '%dd %02dh:%02dm\n' $(($timediffwg2/86400)) $(($timediffwg2%86400/3600)) $(($timediffwg2%3600/60))); else sincelastresetwg2="${CDkGray}Disabled"; fi
if [ "$WGTIMER3" -gt 0 ]; then timediffwg3=$((currtime-WGTIMER3)); sincelastresetwg3=$(printf '%dd %02dh:%02dm\n' $(($timediffwg3/86400)) $(($timediffwg3%86400/3600)) $(($timediffwg3%3600/60))); else sincelastresetwg3="${CDkGray}Disabled"; fi
if [ "$WGTIMER4" -gt 0 ]; then timediffwg4=$((currtime-WGTIMER4)); sincelastresetwg4=$(printf '%dd %02dh:%02dm\n' $(($timediffwg4/86400)) $(($timediffwg4%86400/3600)) $(($timediffwg4%3600/60))); else sincelastresetwg4="${CDkGray}Disabled"; fi
if [ "$WGTIMER5" -gt 0 ]; then timediffwg5=$((currtime-WGTIMER5)); sincelastresetwg5=$(printf '%dd %02dh:%02dm\n' $(($timediffwg5/86400)) $(($timediffwg5%86400/3600)) $(($timediffwg5%3600/60))); else sincelastresetwg5="${CDkGray}Disabled"; fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${CWhite} Monitored? Y/N ${CClear}|${CWhite} Time Connected / Reset? ${CClear}"
echo -e "${InvGreen} ${CClear} |"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN1${CClear} ${CGreen}(1) -${CClear} $VPN1Disp | ${CGreen}(!) -${CClear} $sincelastresetvpn1 ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN2${CClear} ${CGreen}(2) -${CClear} $VPN2Disp | ${CGreen}(@) -${CClear} $sincelastresetvpn2 ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN3${CClear} ${CGreen}(3) -${CClear} $VPN3Disp | ${CGreen}(#) -${CClear} $sincelastresetvpn3 ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN4${CClear} ${CGreen}(4) -${CClear} $VPN4Disp | ${CGreen}($) -${CClear} $sincelastresetvpn4 ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN5${CClear} ${CGreen}(5) -${CClear} $VPN5Disp | ${CGreen}(%) -${CClear} $sincelastresetvpn5 ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} WG1${CClear} ${CGreen}(6) -${CClear} $WG1Disp | ${CGreen}(^) -${CClear} $sincelastresetwg1 ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} WG2${CClear} ${CGreen}(7) -${CClear} $WG2Disp | ${CGreen}(&) -${CClear} $sincelastresetwg2 ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} WG3${CClear} ${CGreen}(8) -${CClear} $WG3Disp | ${CGreen}(-) -${CClear} $sincelastresetwg3 ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} WG4${CClear} ${CGreen}(9) -${CClear} $WG4Disp | ${CGreen}(+) -${CClear} $sincelastresetwg4 ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} WG5${CClear} ${CGreen}(0) -${CClear} $WG5Disp | ${CGreen}(=) -${CClear} $sincelastresetwg5 ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo ""
read -p "Please select? (1-0, !-=, e=Exit): " SelectSlot
case $SelectSlot in
1) currvpn1state="$(_VPN_GetClientState_ "1")"; if [ "$VPN1" = "0" ] && [ "$currvpn1state" -eq 2 ]; then VPN1=1; VPNTIMER1=$(date +%s); VPN1Disp="${CGreen}Y${CCyan}"; elif [ "$VPN1" = "1" ]; then VPN1=0; VPNTIMER2=0; VPN1Disp="${CRed}N${CCyan}"; fi;;
2) currvpn2state="$(_VPN_GetClientState_ "2")"; if [ "$VPN2" = "0" ] && [ "$currvpn2state" -eq 2 ]; then VPN2=1; VPNTIMER2=$(date +%s); VPN2Disp="${CGreen}Y${CCyan}"; elif [ "$VPN2" = "1" ]; then VPN2=0; VPNTIMER2=0; VPN2Disp="${CRed}N${CCyan}"; fi;;
3) currvpn3state="$(_VPN_GetClientState_ "3")"; if [ "$VPN3" = "0" ] && [ "$currvpn3state" -eq 2 ]; then VPN3=1; VPNTIMER3=$(date +%s); VPN3Disp="${CGreen}Y${CCyan}"; elif [ "$VPN3" = "1" ]; then VPN3=0; VPNTIMER3=0; VPN3Disp="${CRed}N${CCyan}"; fi;;
4) currvpn4state="$(_VPN_GetClientState_ "4")"; if [ "$VPN4" = "0" ] && [ "$currvpn4state" -eq 2 ]; then VPN4=1; VPNTIMER4=$(date +%s); VPN4Disp="${CGreen}Y${CCyan}"; elif [ "$VPN4" = "1" ]; then VPN4=0; VPNTIMER4=0; VPN4Disp="${CRed}N${CCyan}"; fi;;
5) currvpn5state="$(_VPN_GetClientState_ "5")"; if [ "$VPN5" = "0" ] && [ "$currvpn5state" -eq 2 ]; then VPN5=1; VPNTIMER5=$(date +%s); VPN5Disp="${CGreen}Y${CCyan}"; elif [ "$VPN5" = "1" ]; then VPN5=0; VPNTIMER5=0; VPN5Disp="${CRed}N${CCyan}"; fi;;
6) currwg1state="$(_WG_GetClientState_ "1")"; if [ "$WG1" = "0" ] && [ "$currwg1state" -eq 2 ]; then WG1=1; WGTIMER1=$(date +%s); WG1Disp="${CGreen}Y${CCyan}"; elif [ "$WG1" = "1" ]; then WG1=0; WGTIMER1=0; WG1Disp="${CRed}N${CCyan}"; fi;;
7) currwg2state="$(_WG_GetClientState_ "2")"; if [ "$WG2" = "0" ] && [ "$currwg2state" -eq 2 ]; then WG2=1; WGTIMER2=$(date +%s); WG2Disp="${CGreen}Y${CCyan}"; elif [ "$WG2" = "1" ]; then WG2=0; WGTIMER2=0; WG2Disp="${CRed}N${CCyan}"; fi;;
8) currwg3state="$(_WG_GetClientState_ "3")"; if [ "$WG3" = "0" ] && [ "$currwg3state" -eq 2 ]; then WG3=1; WGTIMER3=$(date +%s); WG3Disp="${CGreen}Y${CCyan}"; elif [ "$WG3" = "1" ]; then WG3=0; WGTIMER3=0; WG3Disp="${CRed}N${CCyan}"; fi;;
9) currwg4state="$(_WG_GetClientState_ "4")"; if [ "$WG4" = "0" ] && [ "$currwg4state" -eq 2 ]; then WG4=1; WGTIMER4=$(date +%s); WG4Disp="${CGreen}Y${CCyan}"; elif [ "$WG4" = "1" ]; then WG4=0; WGTIMER4=0; WG4Disp="${CRed}N${CCyan}"; fi;;
0) currwg5state="$(_WG_GetClientState_ "5")"; if [ "$WG5" = "0" ] && [ "$currwg5state" -eq 2 ]; then WG5=1; WGTIMER5=$(date +%s); WG5Disp="${CGreen}Y${CCyan}"; elif [ "$WG5" = "1" ]; then WG5=0; WGTIMER5=0; WG5Disp="${CRed}N${CCyan}"; fi;;
[\!]) if [ "$VPN1" = "1" ]; then VPNTIMER1=$(date +%s); else VPNTIMER1=0; fi;;
[\@]) if [ "$VPN2" = "1" ]; then VPNTIMER2=$(date +%s); else VPNTIMER2=0; fi;;
[\#]) if [ "$VPN3" = "1" ]; then VPNTIMER3=$(date +%s); else VPNTIMER3=0; fi;;
[\$]) if [ "$VPN4" = "1" ]; then VPNTIMER4=$(date +%s); else VPNTIMER4=0; fi;;
[\%]) if [ "$VPN5" = "1" ]; then VPNTIMER5=$(date +%s); else VPNTIMER5=0; fi;;
[\^]) if [ "$WG1" = "1" ]; then WGTIMER1=$(date +%s); else WGTIMER1=0; fi;;
[\&]) if [ "$WG2" = "1" ]; then WGTIMER2=$(date +%s); else WGTIMER2=0; fi;;
[\-]) if [ "$WG3" = "1" ]; then WGTIMER3=$(date +%s); else WGTIMER3=0; fi;;
[\+]) if [ "$WG4" = "1" ]; then WGTIMER4=$(date +%s); else WGTIMER4=0; fi;;
[\=]) if [ "$WG5" = "1" ]; then WGTIMER5=$(date +%s); else WGTIMER5=0; fi;;
[Ee])
{ echo 'VPN1='$VPN1
echo 'VPN2='$VPN2
echo 'VPN3='$VPN3
echo 'VPN4='$VPN4
echo 'VPN5='$VPN5
echo 'WG1='$WG1
echo 'WG2='$WG2
echo 'WG3='$WG3
echo 'WG4='$WG4
echo 'WG5='$WG5
} > /jffs/addons/vpnmon-r3.d/vr3clients.txt
{ echo 'VPNTIMER1='$VPNTIMER1
echo 'VPNTIMER2='$VPNTIMER2
echo 'VPNTIMER3='$VPNTIMER3
echo 'VPNTIMER4='$VPNTIMER4
echo 'VPNTIMER5='$VPNTIMER5
echo 'WGTIMER1='$WGTIMER1
echo 'WGTIMER2='$WGTIMER2
echo 'WGTIMER3='$WGTIMER3
echo 'WGTIMER4='$WGTIMER4
echo 'WGTIMER5='$WGTIMER5
} > /jffs/addons/vpnmon-r3.d/vr3timers.txt
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN/WG Client Slot Monitoring configuration / Connection Time Resets Saved" >> $logfile
timer="$timerloop"
break;;
esac
fi
done
}
# -------------------------------------------------------------------------------------------------------------------------
# amtmevents lets you pick success or failure amtm email notification selections
amtmevents()
{
while true
do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} AMTM Email Notifications ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate if you would like VPNMON-R3 to send you email notifications for WAN${CClear}"
echo -e "${InvGreen} ${CClear} or VPN slot failures, or successes on scheduled VPN resets, or both? PLEASE NOTE:${CClear}"
echo -e "${InvGreen} ${CClear} This does require that AMTM email has been set up successfully under AMTM -> em${CClear}"
echo -e "${InvGreen} ${CClear} (email settings). Once you are able to send and receive test emails from AMTM, you${CClear}"
echo -e "${InvGreen} ${CClear} may use this functionality in VPNMON-R3. Additionally, this functionality will${CClear}"
echo -e "${InvGreen} ${CClear} download an AMTM email interface library courtesy of @Martinsky, and will be${CClear}"
echo -e "${InvGreen} ${CClear} located under a new common shared library folder called: /jffs/addons/shared-libs.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Secondarily, you can choose to rate limit the rate at which emails are sent to${CClear}"
echo -e "${InvGreen} ${CClear} your email account per hour. (0=Disabled, 1-9999)${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Use the corresponding ${CGreen}()${CClear} key to enable/disable email event notifications:${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
if [ "$amtmemailsuccess" = "1" ]; then amtmemailsuccessdisp="${CGreen}Y${CCyan}"; else amtmemailsuccess=0; amtmemailsuccessdisp="${CRed}N${CCyan}"; saveconfig; fi
if [ "$amtmemailfailure" = "1" ]; then amtmemailfailuredisp="${CGreen}Y${CCyan}"; else amtmemailfailure=0; amtmemailfailuredisp="${CRed}N${CCyan}"; saveconfig; fi
if [ "$ratelimit" = "0" ]; then ratelimitdisp="Disabled"; else ratelimitdisp=$ratelimit; fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN Success Event Notifications${CClear} ${CGreen}(1) -${CClear} $amtmemailsuccessdisp${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN Failure Event Notifications${CClear} ${CGreen}(2) -${CClear} $amtmemailfailuredisp${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}Set Email Rate Limit (per hour)${CClear} ${CGreen}(r) - $ratelimitdisp${CClear}"
echo ""
read -p "Please select? (1-2, r=Set Email Rate Limit, t=Test Email, e=Exit): " SelectSlot
case $SelectSlot in
1) if [ "$amtmemailsuccess" = "0" ]; then amtmemailsuccess=1; amtmemailsuccessdisp="${CGreen}Y${CCyan}"; elif [ "$amtmemailsuccess" = "1" ]; then amtmemailsuccess=0; amtmemailsuccessdisp="${CRed}N${CCyan}"; fi;;
2) if [ "$amtmemailfailure" = "0" ]; then amtmemailfailure=1; amtmemailfailuredisp="${CGreen}Y${CCyan}"; elif [ "$amtmemailfailure" = "1" ]; then amtmemailfailure=0; amtmemailfailuredisp="${CRed}N${CCyan}"; fi;;
[Tt])
if [ -f "$CUSTOM_EMAIL_LIBFile" ]
then
. "$CUSTOM_EMAIL_LIBFile"
if [ -z "${CEM_LIB_VERSION:+xSETx}" ] || \
_CheckLibraryUpdates_CEM_ "$CUSTOM_EMAIL_LIBDir" quiet
then
_DownloadCEMLibraryFile_ "update"
fi
else
_DownloadCEMLibraryFile_ "install"
fi
cemIsFormatHTML=true
cemIsVerboseMode=true ## true OR false ##
emailBodyTitle="Testing Email Notification"
emailSubject="TEST: VPNMON-R3 Email Notification"
tmpEMailBodyFile="/tmp/var/tmp/tmpEMailBody_${scriptFileNTag}.$$.TXT"
{
printf "This is a TEST to check & verify if sending email notifications is working well from VPNMON-R3.\n"
} > "$tmpEMailBodyFile"
_SendEMailNotification_ "VPNMON-R3 v$version" "$emailSubject" "$tmpEMailBodyFile" "$emailBodyTitle"
echo ; echo
read -rsp $'Press any key to acknowledge...\n' -n1 key
;;
[Rr])
echo ""
read -p "Please enter new Email Rate Limit (per hour)? (0=disabled, 1-9999, e=Exit): " newratelimit
if [ "$newratelimit" = "e" ]
then
echo -e "\n[Exiting]"; sleep 2
elif echo "$newratelimit" | grep -qE "^(0|[1-9][0-9]{0,3})$" && \
[ "$newratelimit" -ge 0 ] && [ "$newratelimit" -le 9999 ]
then
ratelimit="$newratelimit"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Email Rate Limit entered (per hour): $ratelimit" >> $logfile
saveconfig
else
previousValue="$ratelimit"
ratelimit="${ratelimit:=0}"
[ "$ratelimit" != "$previousValue" ] && \
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Email Rate Limit entered (per hour): $ratelimit" >> $logfile
saveconfig
fi
;;
[Ee])
saveconfig
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: AMTM Email notification configuration saved" >> $logfile
timer="$timerloop"
break;;
esac
done
}
# -------------------------------------------------------------------------------------------------------------------------
# vpnserverlistmaint lets you pick which vpn slot server list you want to edit/maintain
vpnserverlistmaint()
{
while true
do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} VPN Client Slot Server List Maintenance ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate which VPN Slot Server List you would like to edit/maintain.${CClear}"
echo -e "${InvGreen} ${CClear} Use the corresponding ${CGreen}()${CClear} key to launch and edit the list with the NANO text editor${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} VPN INSTRUCTIONS: Enter a single column of IP addresses or hostnames, as required by${CClear}"
echo -e "${InvGreen} ${CClear} your VPN provider. ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} NANO INSTRUCTIONS: CTRL-O + Enter (save), CTRL-X (exit)${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN1${CClear} ${CGreen}(1)${CClear}"
if [ -f /jffs/addons/vpnmon-r3.d/vr3svr1.txt ]; then
iplist=$(awk -vORS=, '{ print $1 }' /jffs/addons/vpnmon-r3.d/vr3svr1.txt | sed 's/,$/\n/')
echo -en "${InvGreen} ${CClear} Contents: "; printf "%.75s>\n" $iplist
else
echo -e "${InvGreen} ${CClear} Contents: "
fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN2${CClear} ${CGreen}(2)${CClear}"
if [ -f /jffs/addons/vpnmon-r3.d/vr3svr2.txt ]; then
iplist=$(awk -vORS=, '{ print $1 }' /jffs/addons/vpnmon-r3.d/vr3svr2.txt | sed 's/,$/\n/')
echo -en "${InvGreen} ${CClear} Contents: "; printf "%.75s>\n" $iplist
else
echo -e "${InvGreen} ${CClear} Contents: "
fi
echo -e "${InvGreen} ${CClear}"
if [ "$availableslots" = "1 2" ]
then
echo ""
read -p "Please select? (1-2, e=Exit): " SelectSlot
case $SelectSlot in
1) export TERM=linux; nano +999999 --linenumbers /jffs/addons/vpnmon-r3.d/vr3svr1.txt;;
2) export TERM=linux; nano +999999 --linenumbers /jffs/addons/vpnmon-r3.d/vr3svr2.txt;;
[Ee])
timer="$timerloop"
break;;
esac
fi
if [ "$availableslots" = "1 2 3 4 5" ]
then
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN3${CClear} ${CGreen}(3)${CClear}"
if [ -f /jffs/addons/vpnmon-r3.d/vr3svr3.txt ]; then
iplist=$(awk -vORS=, '{ print $1 }' /jffs/addons/vpnmon-r3.d/vr3svr3.txt | sed 's/,$/\n/')
echo -en "${InvGreen} ${CClear} Contents: "; printf "%.75s>\n" $iplist
else
echo -e "${InvGreen} ${CClear} Contents: "
fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN4${CClear} ${CGreen}(4)${CClear}"
if [ -f /jffs/addons/vpnmon-r3.d/vr3svr4.txt ]; then
iplist=$(awk -vORS=, '{ print $1 }' /jffs/addons/vpnmon-r3.d/vr3svr4.txt | sed 's/,$/\n/')
echo -en "${InvGreen} ${CClear} Contents: "; printf "%.75s>\n" $iplist
else
echo -e "${InvGreen} ${CClear} Contents: "
fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN5${CClear} ${CGreen}(5)${CClear}"
if [ -f /jffs/addons/vpnmon-r3.d/vr3svr5.txt ]; then
iplist=$(awk -vORS=, '{ print $1 }' /jffs/addons/vpnmon-r3.d/vr3svr5.txt | sed 's/,$/\n/')
echo -en "${InvGreen} ${CClear} Contents: "; printf "%.75s>\n" $iplist
else
echo -e "${InvGreen} ${CClear} Contents: "
fi
echo ""
read -p "Please select? (1-5, e=Exit): " SelectSlot
case $SelectSlot in
1) export TERM=linux; nano +999999 --linenumbers /jffs/addons/vpnmon-r3.d/vr3svr1.txt;;
2) export TERM=linux; nano +999999 --linenumbers /jffs/addons/vpnmon-r3.d/vr3svr2.txt;;
3) export TERM=linux; nano +999999 --linenumbers /jffs/addons/vpnmon-r3.d/vr3svr3.txt;;
4) export TERM=linux; nano +999999 --linenumbers /jffs/addons/vpnmon-r3.d/vr3svr4.txt;;
5) export TERM=linux; nano +999999 --linenumbers /jffs/addons/vpnmon-r3.d/vr3svr5.txt;;
[Ee])
timer="$timerloop"
break;;
esac
fi
done
}
# -------------------------------------------------------------------------------------------------------------------------
# wgserverlistmaint lets you pick which wg slot server list you want to edit/maintain
wgserverlistmaint()
{
if [ "$availableslots" = "1 2" ]
then
return
fi
while true
do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} WG Client Slot Server List Maintenance ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate which WG Slot Server List you would like to edit/maintain.${CClear}"
echo -e "${InvGreen} ${CClear} Use the corresponding ${CGreen}()${CClear} key to launch and edit the list with the NANO text editor${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} WG INSTRUCTIONS: Enter a 7-field comma-delimited row of WG Connections${CClear}"
echo -e "${InvGreen} ${CClear} Format: ${CWhite}ConnectionName,InterfaceIP/Sub,EndpointIP,EndpointPort,PrivateKey,PublicKey,PreSharedKey(Opt)${CClear}"
echo -e "${InvGreen} ${CClear} Example: ${CGreen}City WG,10.50.0.2/32,143.32.55.23,34334,fasdkaffkasdjfj=,221t949as2323kf=,23fj39fffjdaf=${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} NANO INSTRUCTIONS: CTRL-O + Enter (save), CTRL-X (exit)${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}WG1${CClear} ${CGreen}(6)${CClear}"
if [ -f /jffs/addons/vpnmon-r3.d/vr3wgsvr1.txt ]; then
wglist=$(awk -F, '{printf "%s%s", sep, $1; sep=","} END {print ""}' /jffs/addons/vpnmon-r3.d/vr3wgsvr1.txt | awk '{print substr($0, 1, 75) ">"}')
echo -en "${InvGreen} ${CClear} Contents: "; echo $wglist
else
echo -e "${InvGreen} ${CClear} Contents: "
fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}WG2${CClear} ${CGreen}(7)${CClear}"
if [ -f /jffs/addons/vpnmon-r3.d/vr3wgsvr2.txt ]; then
wglist=$(awk -F, '{printf "%s%s", sep, $1; sep=","} END {print ""}' /jffs/addons/vpnmon-r3.d/vr3wgsvr2.txt | awk '{print substr($0, 1, 75) ">"}')
echo -en "${InvGreen} ${CClear} Contents: "; echo $wglist
else
echo -e "${InvGreen} ${CClear} Contents: "
fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}WG3${CClear} ${CGreen}(8)${CClear}"
if [ -f /jffs/addons/vpnmon-r3.d/vr3wgsvr3.txt ]; then
wglist=$(awk -F, '{printf "%s%s", sep, $1; sep=","} END {print ""}' /jffs/addons/vpnmon-r3.d/vr3wgsvr3.txt | awk '{print substr($0, 1, 75) ">"}')
echo -en "${InvGreen} ${CClear} Contents: "; echo $wglist
else
echo -e "${InvGreen} ${CClear} Contents: "
fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}WG4${CClear} ${CGreen}(9)${CClear}"
if [ -f /jffs/addons/vpnmon-r3.d/vr3wgsvr4.txt ]; then
wglist=$(awk -F, '{printf "%s%s", sep, $1; sep=","} END {print ""}' /jffs/addons/vpnmon-r3.d/vr3wgsvr4.txt | awk '{print substr($0, 1, 75) ">"}')
echo -en "${InvGreen} ${CClear} Contents: "; echo $wglist
else
echo -e "${InvGreen} ${CClear} Contents: "
fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}WG5${CClear} ${CGreen}(0)${CClear}"
if [ -f /jffs/addons/vpnmon-r3.d/vr3wgsvr5.txt ]; then
wglist=$(awk -F, '{printf "%s%s", sep, $1; sep=","} END {print ""}' /jffs/addons/vpnmon-r3.d/vr3wgsvr5.txt | awk '{print substr($0, 1, 75) ">"}')
echo -en "${InvGreen} ${CClear} Contents: "; echo $wglist
else
echo -e "${InvGreen} ${CClear} Contents: "
fi
echo ""
read -p "Please select? (6-0, e=Exit): " SelectSlot
case $SelectSlot in
6) export TERM=linux; nano +999999 --linenumbers /jffs/addons/vpnmon-r3.d/vr3wgsvr1.txt;;
7) export TERM=linux; nano +999999 --linenumbers /jffs/addons/vpnmon-r3.d/vr3wgsvr2.txt;;
8) export TERM=linux; nano +999999 --linenumbers /jffs/addons/vpnmon-r3.d/vr3wgsvr3.txt;;
9) export TERM=linux; nano +999999 --linenumbers /jffs/addons/vpnmon-r3.d/vr3wgsvr4.txt;;
0) export TERM=linux; nano +999999 --linenumbers /jffs/addons/vpnmon-r3.d/vr3wgsvr5.txt;;
[Ee])
timer="$timerloop"
break;;
esac
done
}
# -------------------------------------------------------------------------------------------------------------------------
# vpnserverlistautomation lets you pick which vpn slot server list automation you want to edit/execute
vpnserverlistautomation()
{
while true
do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} WG/VPN Client Slot Server List Automation ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate which VPN Slot Automation Script you would like to edit/execute.${CClear}"
echo -e "${InvGreen} ${CClear} Use the corresponding ${CGreen}()${CClear} key to edit or launch your update statements${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} VPN INSTRUCTIONS: Insert CURL statement that outputs a single-column Server IP list${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} WG INSTRUCTIONS: Insert CURL statement that outputs a 7-field comma-separated list${CClear}"
echo -e "${InvGreen} ${CClear} Format: ${CWhite}ConnectionName,InterfaceIP/Sub,EndpointIP,EndpointPort,PrivateKey,PublicKey,PreSharedKey(Opt)${CClear}"
echo -e "${InvGreen} ${CClear} Example: ${CGreen}City WG,10.50.0.2/32,143.32.55.23,34334,fasdkaffkasdjfj=,221t949as2323kf=,23fj39fffjdaf=${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN1${CClear} ${CGreen}(e1)${CClear} View/Edit | ${CGreen}(x1)${CClear} Execute | ${CGreen}(s1)${CClear} Skynet WL Import${CClear}"
if [ -z "$automation1" ] || [ "$automation1" = "" ]; then
echo -e "${InvGreen} ${CClear} Contents: "
else
automation1unenc=$(echo "$automation1" | openssl enc -d -base64 -A)
echo -en "${InvGreen} ${CClear} Contents: ${InvDkGray}${CWhite}"; printf "%.75s>\n" "$automation1unenc"
fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN2${CClear} ${CGreen}(e2)${CClear} View/Edit | ${CGreen}(x2)${CClear} Execute | ${CGreen}(s2)${CClear} Skynet WL Import${CClear}"
if [ -z "$automation2" ] || [ "$automation2" = "" ]; then
echo -e "${InvGreen} ${CClear} Contents: "
else
automation2unenc=$(echo "$automation2" | openssl enc -d -base64 -A)
echo -en "${InvGreen} ${CClear} Contents: ${InvDkGray}${CWhite}"; printf "%.75s>\n" "$automation2unenc"
fi
echo -e "${InvGreen} ${CClear}"
if [ "$availableslots" = "1 2" ]; then
echo ""
read -p "Please select? (e1-e2, x1-x2, s1-s2, e=Exit): " SelectSlot2
case $SelectSlot2 in
e1)
echo ""
if [ "$automation1" = "" ] || [ -z "$automation1" ]; then
echo -e "${CClear}Old Script: "
echo ""
else
echo -en "${CClear}Old Script: "; echo "$automation1" | openssl enc -d -base64 -A
echo ""
fi
read -rp 'Enter New Script (e=Exit): ' automation1new
if [ "$automation1new" = "" ] || [ -z "$automation1new" ]; then
automation1=""
saveconfig
elif [ "$automation1new" = "e" ]; then
echo ""; echo -e "${CGreen}[Exiting]${CClear}"; sleep 1
else
automation1=`echo $automation1new | openssl enc -base64 -A`
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Custom VPN Server List Command entered for VPN Slot 1" >> $logfile
saveconfig
fi
;;
x1)
echo ""
echo -e "${CGreen}[Executing Script]${CClear}"
automation1unenc=$(echo "$automation1" | openssl enc -d -base64 -A)
echo -e "${CClear}Running: $automation1unenc"
echo ""
eval "$automation1unenc" > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
#Determine how many server entries are in each of the vpn slot alternate server files
if [ -f /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt ]; then
dlcnt=$(cat /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt | wc -l) >/dev/null 2>&1
if [ $dlcnt -lt 1 ]; then
dlcnt=0
elif [ -z $dlcnt ]; then
dlcnt=0
fi
else
dlcnt=0
fi
if [ "$dlcnt" -gt 1 ]
then
cp "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" "/jffs/addons/vpnmon-r3.d/vr3svr1.txt" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source]${CClear}"
echo ""
echo -e "${CGreen}[Saved to VPN Client Slot 1 Server List]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom VPN Server List Command executed for VPN Slot 1" >> $logfile
echo ""
skynetwhitelist 1
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
else
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source - Preserving Original Server List]${CClear}"
echo ""
echo -e "${CGreen}[Please check Query Language or VPN Service API may be down]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom VPN Client Server List Query for VPN Slot 1 yielded 0 rows -- Query may be invalid or VPN API service may be down" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
fi
;;
s1)
echo ""
echo -e "${CGreen}[Executing Skynet Whitelist Import]${CClear}"
firewall import whitelist /jffs/addons/vpnmon-r3.d/vr3svr1.txt "VPNMON-R3 VPN Slot 1 Import" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Contents of VPN Slot 1 Imported]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Skynet Whitelist imported for VPN Slot 1" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
;;
e2)
echo ""
if [ "$automation2" = "" ] || [ -z "$automation2" ]; then
echo -e "${CClear}Old Script: "
echo ""
else
echo -en "${CClear}Old Script: "; echo "$automation2" | openssl enc -d -base64 -A
echo ""
fi
read -rp 'Enter New Script (e=Exit): ' automation2new
if [ "$automation2new" = "" ] || [ -z "$automation2new" ]; then
automation2=""
saveconfig
elif [ "$automation2new" = "e" ]; then
echo ""; echo -e "${CGreen}[Exiting]${CClear}"; sleep 1
else
automation2=`echo $automation2new | openssl enc -base64 -A`
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Custom VPN Server List Command entered for VPN Slot 2" >> $logfile
saveconfig
fi
;;
x2)
echo ""
echo -e "${CGreen}[Executing Script]${CClear}"
automation2unenc=$(echo "$automation2" | openssl enc -d -base64 -A)
echo -e "${CClear}Running: $automation2unenc"
echo ""
eval "$automation2unenc" > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
#Determine how many server entries are in each of the vpn slot alternate server files
if [ -f /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt ]; then
dlcnt=$(cat /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt | wc -l) >/dev/null 2>&1
if [ $dlcnt -lt 1 ]; then
dlcnt=0
elif [ -z $dlcnt ]; then
dlcnt=0
fi
else
dlcnt=0
fi
if [ "$dlcnt" -gt 1 ]
then
cp "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" "/jffs/addons/vpnmon-r3.d/vr3svr2.txt" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source]${CClear}"
echo ""
echo -e "${CGreen}[Saved to VPN Client Slot 2 Server List]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom VPN Server List Command executed for VPN Slot 2" >> $logfile
echo ""
skynetwhitelist 2
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
else
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source - Preserving Original Server List]${CClear}"
echo ""
echo -e "${CGreen}[Please check Query Language or VPN Service API may be down]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom VPN Client Server List Query for VPN Slot 2 yielded 0 rows -- Query may be invalid or VPN API service may be down" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
fi
;;
s2)
echo ""
echo -e "${CGreen}[Executing Skynet Whitelist Import]${CClear}"
firewall import whitelist /jffs/addons/vpnmon-r3.d/vr3svr2.txt "VPNMON-R3 VPN Slot 2 Import" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Contents of VPN Slot 2 Imported]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Skynet Whitelist imported for VPN Slot 2" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
;;
[Ee])
timer="$timerloop"
break;;
esac
fi
if [ "$availableslots" = "1 2 3 4 5" ]; then
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN3${CClear} ${CGreen}(e3)${CClear} View/Edit | ${CGreen}(x3)${CClear} Execute | ${CGreen}(s3)${CClear} Skynet WL Import${CClear}"
if [ -z "$automation3" ] || [ "$automation3" = "" ]; then
echo -e "${InvGreen} ${CClear} Contents: "
else
automation3unenc=$(echo "$automation3" | openssl enc -d -base64 -A)
echo -en "${InvGreen} ${CClear} Contents: ${InvDkGray}${CWhite}"; printf "%.75s>\n" "$automation3unenc"
fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN4${CClear} ${CGreen}(e4)${CClear} View/Edit | ${CGreen}(x4)${CClear} Execute | ${CGreen}(s4)${CClear} Skynet WL Import${CClear}"
if [ -z "$automation4" ] || [ "$automation4" = "" ]; then
echo -e "${InvGreen} ${CClear} Contents: "
else
automation4unenc=$(echo "$automation4" | openssl enc -d -base64 -A)
echo -en "${InvGreen} ${CClear} Contents: ${InvDkGray}${CWhite}"; printf "%.75s>\n" "$automation4unenc"
fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite}VPN5${CClear} ${CGreen}(e5)${CClear} View/Edit | ${CGreen}(x5)${CClear} Execute | ${CGreen}(s5)${CClear} Skynet WL Import${CClear}"
if [ -z "$automation5" ] || [ "$automation5" = "" ]; then
echo -e "${InvGreen} ${CClear} Contents: "
else
automation5unenc=$(echo "$automation5" | openssl enc -d -base64 -A)
echo -en "${InvGreen} ${CClear} Contents: ${InvDkGray}${CWhite}"; printf "%.75s>\n" "$automation5unenc"
fi
echo -e "${InvGreen} ${CClear}"
##-------------------------------------##
## Added by Dan G. [2025-Jul-15] ##
##-------------------------------------##
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} WG1${CClear} ${CGreen}(e6)${CClear} View/Edit | ${CGreen}(x6)${CClear} Execute | ${CGreen}(s6)${CClear} Skynet WL Import${CClear}"
if [ -z "$wgautomation1" ] || [ "$wgautomation1" = "" ]; then
echo -e "${InvGreen} ${CClear} Contents: "
else
wgautomation1unenc=$(echo "$wgautomation1" | openssl enc -d -base64 -A)
echo -en "${InvGreen} ${CClear} Contents: ${InvDkGray}${CWhite}"; printf "%.75s>\n" "$wgautomation1unenc"
fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} WG2${CClear} ${CGreen}(e7)${CClear} View/Edit | ${CGreen}(x7)${CClear} Execute | ${CGreen}(s7)${CClear} Skynet WL Import${CClear}"
if [ -z "$wgautomation2" ] || [ "$wgautomation2" = "" ]; then
echo -e "${InvGreen} ${CClear} Contents: "
else
wgautomation2unenc=$(echo "$wgautomation2" | openssl enc -d -base64 -A)
echo -en "${InvGreen} ${CClear} Contents: ${InvDkGray}${CWhite}"; printf "%.75s>\n" "$wgautomation2unenc"
fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} WG3${CClear} ${CGreen}(e8)${CClear} View/Edit | ${CGreen}(x8)${CClear} Execute | ${CGreen}(s8)${CClear} Skynet WL Import${CClear}"
if [ -z "$wgautomation3" ] || [ "$wgautomation3" = "" ]; then
echo -e "${InvGreen} ${CClear} Contents: "
else
wgautomation3unenc=$(echo "$wgautomation3" | openssl enc -d -base64 -A)
echo -en "${InvGreen} ${CClear} Contents: ${InvDkGray}${CWhite}"; printf "%.75s>\n" "$wgautomation3unenc"
fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} WG4${CClear} ${CGreen}(e9)${CClear} View/Edit | ${CGreen}(x9)${CClear} Execute | ${CGreen}(s9)${CClear} Skynet WL Import${CClear}"
if [ -z "$wgautomation4" ] || [ "$wgautomation4" = "" ]; then
echo -e "${InvGreen} ${CClear} Contents: "
else
wgautomation4unenc=$(echo "$wgautomation4" | openssl enc -d -base64 -A)
echo -en "${InvGreen} ${CClear} Contents: ${InvDkGray}${CWhite}"; printf "%.75s>\n" "$wgautomation4unenc"
fi
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} ${InvDkGray}${CWhite} WG5${CClear} ${CGreen}(e0)${CClear} View/Edit | ${CGreen}(x0)${CClear} Execute | ${CGreen}(s0)${CClear} Skynet WL Import${CClear}"
if [ -z "$wgautomation5" ] || [ "$wgautomation5" = "" ]; then
echo -e "${InvGreen} ${CClear} Contents: "
else
wgautomation5unenc=$(echo "$wgautomation5" | openssl enc -d -base64 -A)
echo -en "${InvGreen} ${CClear} Contents: ${InvDkGray}${CWhite}"; printf "%.75s>\n" "$wgautomation5unenc"
fi
echo ""
read -p "Please select? (e1-e0, x1-x0, s1-s0, e=Exit): " SelectSlot5
case $SelectSlot5 in
e1)
echo ""
if [ "$automation1" = "" ] || [ -z "$automation1" ]; then
echo -e "${CClear}Old Script: "
echo ""
else
echo -en "${CClear}Old Script: "; echo "$automation1" | openssl enc -d -base64 -A
echo ""
fi
read -rp 'Enter New Script (e=Exit): ' automation1new
if [ "$automation1new" = "" ] || [ -z "$automation1new" ]; then
automation1=""
saveconfig
elif [ "$automation1new" = "e" ]; then
echo ""; echo -e "${CGreen}[Exiting]${CClear}"; sleep 1
else
automation1=`echo $automation1new | openssl enc -base64 -A`
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Custom VPN Server List Command entered for VPN Slot 1" >> $logfile
saveconfig
fi
;;
x1)
echo ""
echo -e "${CGreen}[Executing Script]${CClear}"
automation1unenc=$(echo "$automation1" | openssl enc -d -base64 -A)
echo -e "${CClear}Running: $automation1unenc"
echo ""
eval "$automation1unenc" > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
#Determine how many server entries are in each of the vpn slot alternate server files
if [ -f /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt ]; then
dlcnt=$(cat /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt | wc -l) >/dev/null 2>&1
if [ $dlcnt -lt 1 ]; then
dlcnt=0
elif [ -z $dlcnt ]; then
dlcnt=0
fi
else
dlcnt=0
fi
if [ "$dlcnt" -gt 1 ]
then
cp "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" "/jffs/addons/vpnmon-r3.d/vr3svr1.txt" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source]${CClear}"
echo ""
echo -e "${CGreen}[Saved to VPN Client Slot 1 Server List]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom VPN Server List Command executed for VPN Slot 1" >> $logfile
echo ""
skynetwhitelist 1
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
else
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source - Preserving Original Server List]${CClear}"
echo ""
echo -e "${CGreen}[Please check Query Language or VPN Service API may be down]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom VPN Client Server List Query for VPN Slot 1 yielded 0 rows -- Query may be invalid or VPN API service may be down" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
fi
;;
s1)
echo ""
echo -e "${CGreen}[Executing Skynet Whitelist Import]${CClear}"
firewall import whitelist /jffs/addons/vpnmon-r3.d/vr3svr1.txt "VPNMON-R3 VPN Slot 1 Import" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Contents of VPN Slot 1 Imported]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Skynet Whitelist imported for VPN Slot 1" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
;;
e2)
echo ""
if [ "$automation2" = "" ] || [ -z "$automation2" ]; then
echo -e "${CClear}Old Script: "
echo ""
else
echo -en "${CClear}Old Script: "; echo "$automation2" | openssl enc -d -base64 -A
echo ""
fi
read -rp 'Enter New Script (e=Exit): ' automation2new
if [ "$automation2new" = "" ] || [ -z "$automation2new" ]; then
automation2=""
saveconfig
elif [ "$automation2new" = "e" ]; then
echo ""; echo -e "${CGreen}[Exiting]${CClear}"; sleep 1
else
automation2=`echo $automation2new | openssl enc -base64 -A`
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Custom VPN Server List Command entered for VPN Slot 2" >> $logfile
saveconfig
fi
;;
x2)
echo ""
echo -e "${CGreen}[Executing Script]${CClear}"
automation2unenc=$(echo "$automation2" | openssl enc -d -base64 -A)
echo -e "${CClear}Running: $automation2unenc"
echo ""
eval "$automation2unenc" > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
#Determine how many server entries are in each of the vpn slot alternate server files
if [ -f /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt ]; then
dlcnt=$(cat /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt | wc -l) >/dev/null 2>&1
if [ $dlcnt -lt 1 ]; then
dlcnt=0
elif [ -z $dlcnt ]; then
dlcnt=0
fi
else
dlcnt=0
fi
if [ "$dlcnt" -gt 1 ]
then
cp "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" "/jffs/addons/vpnmon-r3.d/vr3svr2.txt" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source]${CClear}"
echo ""
echo -e "${CGreen}[Saved to VPN Client Slot 2 Server List]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom VPN Server List Command executed for VPN Slot 2" >> $logfile
echo ""
skynetwhitelist 2
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
else
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source - Preserving Original Server List]${CClear}"
echo ""
echo -e "${CGreen}[Please check Query Language or VPN Service API may be down]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom VPN Client Server List Query for VPN Slot 2 yielded 0 rows -- Query may be invalid or VPN API service may be down" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
fi
;;
s2)
echo ""
echo -e "${CGreen}[Executing Skynet Whitelist Import]${CClear}"
firewall import whitelist /jffs/addons/vpnmon-r3.d/vr3svr2.txt "VPNMON-R3 VPN Slot 2 Import" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Contents of VPN Slot 2 Imported]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Skynet Whitelist imported for VPN Slot 2" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
;;
e3)
echo ""
if [ "$automation3" = "" ] || [ -z "$automation3" ]; then
echo -e "${CClear}Old Script: "
echo ""
else
echo -en "${CClear}Old Script: "; echo "$automation3" | openssl enc -d -base64 -A
echo ""
fi
read -rp 'Enter New Script (e=Exit): ' automation3new
if [ "$automation3new" = "" ] || [ -z "$automation3new" ]; then
automation3=""
saveconfig
elif [ "$automation3new" = "e" ]; then
echo ""; echo -e "${CGreen}[Exiting]${CClear}"; sleep 1
else
automation3=`echo $automation3new | openssl enc -base64 -A`
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Custom VPN Server List Command entered for VPN Slot 3" >> $logfile
saveconfig
fi
;;
x3)
echo ""
echo -e "${CGreen}[Executing Script]${CClear}"
automation3unenc=$(echo "$automation3" | openssl enc -d -base64 -A)
echo -e "${CClear}Running: $automation3unenc"
echo ""
eval "$automation3unenc" > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
#Determine how many server entries are in each of the vpn slot alternate server files
if [ -f /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt ]; then
dlcnt=$(cat /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt | wc -l) >/dev/null 2>&1
if [ $dlcnt -lt 1 ]; then
dlcnt=0
elif [ -z $dlcnt ]; then
dlcnt=0
fi
else
dlcnt=0
fi
if [ "$dlcnt" -gt 1 ]
then
cp "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" "/jffs/addons/vpnmon-r3.d/vr3svr3.txt" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source]${CClear}"
echo ""
echo -e "${CGreen}[Saved to VPN Client Slot 3 Server List]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom VPN Server List Command executed for VPN Slot 3" >> $logfile
echo ""
skynetwhitelist 3
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
else
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source - Preserving Original Server List]${CClear}"
echo ""
echo -e "${CGreen}[Please check Query Language or VPN Service API may be down]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom VPN Client Server List Query for VPN Slot 3 yielded 0 rows -- Query may be invalid or VPN API service may be down" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
fi
;;
s3)
echo ""
echo -e "${CGreen}[Executing Skynet Whitelist Import]${CClear}"
firewall import whitelist /jffs/addons/vpnmon-r3.d/vr3svr3.txt "VPNMON-R3 VPN Slot 3 Import" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Contents of VPN Slot 3 Imported]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Skynet Whitelist imported for VPN Slot 3" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
;;
e4)
echo ""
if [ "$automation4" ="" ] || [ -z "$automation4" ]; then
echo -e "${CClear}Old Script: "
echo ""
else
echo -en "${CClear}Old Script: "; echo "$automation4" | openssl enc -d -base64 -A
echo ""
fi
read -rp 'Enter New Script (e=Exit): ' automation4new
if [ "$automation4new" = "" ] || [ -z "$automation4new" ]; then
automation4=""
saveconfig
elif [ "$automation4new" = "e" ]; then
echo ""; echo -e "${CGreen}[Exiting]${CClear}"; sleep 1
else
automation4=`echo $automation4new | openssl enc -base64 -A`
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Custom VPN Server List Command entered for VPN Slot 4" >> $logfile
saveconfig
fi
;;
x4)
echo ""
echo -e "${CGreen}[Executing Script]${CClear}"
automation4unenc=$(echo "$automation4" | openssl enc -d -base64 -A)
echo -e "${CClear}Running: $automation4unenc"
echo ""
eval "$automation4unenc" > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
#Determine how many server entries are in each of the vpn slot alternate server files
if [ -f /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt ]; then
dlcnt=$(cat /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt | wc -l) >/dev/null 2>&1
if [ $dlcnt -lt 1 ]; then
dlcnt=0
elif [ -z $dlcnt ]; then
dlcnt=0
fi
else
dlcnt=0
fi
if [ "$dlcnt" -gt 1 ]
then
cp "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" "/jffs/addons/vpnmon-r3.d/vr3svr4.txt" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source]${CClear}"
echo ""
echo -e "${CGreen}[Saved to VPN Client Slot 4 Server List]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom VPN Server List Command executed for VPN Slot 4" >> $logfile
echo ""
skynetwhitelist 4
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
else
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source - Preserving Original Server List]${CClear}"
echo ""
echo -e "${CGreen}[Please check Query Language or VPN Service API may be down]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom VPN Client Server List Query for VPN Slot 4 yielded 0 rows -- Query may be invalid or VPN API service may be down" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
fi
;;
s4)
echo ""
echo -e "${CGreen}[Executing Skynet Whitelist Import]${CClear}"
firewall import whitelist /jffs/addons/vpnmon-r3.d/vr3svr4.txt "VPNMON-R3 VPN Slot 4 Import" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Contents of VPN Slot 4 Imported]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Skynet Whitelist imported for VPN Slot 4" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
;;
e5)
echo ""
if [ "$automation5" = "" ] || [ -z "$automation5" ]; then
echo -e "${CClear}Old Script: "
echo ""
else
echo -en "${CClear}Old Script: "; echo "$automation5" | openssl enc -d -base64 -A
echo ""
fi
read -rp 'Enter New Script (e=Exit): ' automation5new
if [ "$automation5new" = "" ] || [ -z "$automation5new" ]; then
automation5=""
saveconfig
elif [ "$automation5new" = "e" ]; then
echo ""; echo -e "${CGreen}[Exiting]${CClear}"; sleep 1
else
automation5=`echo $automation5new | openssl enc -base64 -A`
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Custom VPN Server List Command entered for VPN Slot 5" >> $logfile
saveconfig
fi
;;
x5)
echo ""
echo -e "${CGreen}[Executing Script]${CClear}"
automation5unenc=$(echo "$automation5" | openssl enc -d -base64 -A)
echo -e "${CClear}Running: $automation5unenc"
echo ""
eval "$automation5unenc" > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
#Determine how many server entries are in each of the vpn slot alternate server files
if [ -f /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt ]; then
dlcnt=$(cat /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt | wc -l) >/dev/null 2>&1
if [ $dlcnt -lt 1 ]; then
dlcnt=0
elif [ -z $dlcnt ]; then
dlcnt=0
fi
else
dlcnt=0
fi
if [ "$dlcnt" -gt 1 ]
then
cp "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" "/jffs/addons/vpnmon-r3.d/vr3svr5.txt" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source]${CClear}"
echo ""
echo -e "${CGreen}[Saved to VPN Client Slot 5 Server List]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom VPN Server List Command executed for VPN Slot 5" >> $logfile
echo ""
skynetwhitelist 5
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
else
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source - Preserving Original Server List]${CClear}"
echo ""
echo -e "${CGreen}[Please check Query Language or VPN Service API may be down]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom VPN Client Server List Query for VPN Slot 5 yielded 0 rows -- Query may be invalid or VPN API service may be down" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
fi
;;
s5)
echo ""
echo -e "${CGreen}[Executing Skynet Whitelist Import]${CClear}"
firewall import whitelist /jffs/addons/vpnmon-r3.d/vr3svr5.txt "VPNMON-R3 VPN Slot 5 Import" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Contents of VPN Slot 5 Imported]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Skynet Whitelist imported for VPN Slot 5" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
;;
e6)
echo ""
if [ "$wgautomation1" = "" ] || [ -z "$wgautomation1" ]; then
echo -e "${CClear}Old Script: "
echo ""
else
echo -en "${CClear}Old Script: "; echo "$wgautomation1" | openssl enc -d -base64 -A
echo ""
fi
read -rp 'Enter New Script (e=Exit): ' wgautomation1new
if [ "$wgautomation1new" = "" ] || [ -z "$wgautomation1new" ]; then
wgautomation1=""
saveconfig
elif [ "$wgautomation1new" = "e" ]; then
echo ""; echo -e "${CGreen}[Exiting]${CClear}"; sleep 1
else
wgautomation1=`echo $wgautomation1new | openssl enc -base64 -A`
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Custom WG Server List Command entered for WG Slot 1" >> $logfile
saveconfig
fi
;;
x6)
echo ""
echo -e "${CGreen}[Executing Script]${CClear}"
wgautomation1unenc=$(echo "$wgautomation1" | openssl enc -d -base64 -A)
echo -e "${CClear}Running: $wgautomation1unenc"
echo ""
eval "$wgautomation1unenc" > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
#Determine how many server entries are in each of the vpn slot alternate server files
if [ -f /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt ]; then
dlcnt=$(cat /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt | wc -l) >/dev/null 2>&1
if [ $dlcnt -lt 1 ]; then
dlcnt=0
elif [ -z $dlcnt ]; then
dlcnt=0
fi
else
dlcnt=0
fi
if [ "$dlcnt" -gt 1 ]
then
cp "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" "/jffs/addons/vpnmon-r3.d/vr3wgsvr1.txt" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source]${CClear}"
echo ""
echo -e "${CGreen}[Saved to WG Client Slot 1 Server List]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom WG Server List Command executed for WG Slot 1" >> $logfile
echo ""
skynetwhitelist wg1
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
else
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source - Preserving Original Server List]${CClear}"
echo ""
echo -e "${CGreen}[Please check Query Language or WG Service API may be down]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom WG Client Server List Query for WG Slot 1 yielded 0 rows -- Query may be invalid or WG API service may be down" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
fi
;;
s6)
echo ""
echo -e "${CGreen}[Executing Skynet Whitelist Import]${CClear}"
awk -F',' '{print $2}' /jffs/addons/vpnmon-r3.d/vr3wgsvr1.txt > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
firewall import whitelist /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt "VPNMON-R3 WG Slot 1 Import" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Contents of WG Slot 1 Imported]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Skynet Whitelist imported for WG Slot 1" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
;;
e7)
echo ""
if [ "$wgautomation2" = "" ] || [ -z "$wgautomation2" ]; then
echo -e "${CClear}Old Script: "
echo ""
else
echo -en "${CClear}Old Script: "; echo "$wgautomation2" | openssl enc -d -base64 -A
echo ""
fi
read -rp 'Enter New Script (e=Exit): ' wgautomation2new
if [ "$wgautomation2new" = "" ] || [ -z "$wgautomation2new" ]; then
wgautomation2=""
saveconfig
elif [ "$wgautomation2new" = "e" ]; then
echo ""; echo -e "${CGreen}[Exiting]${CClear}"; sleep 1
else
wgautomation2=`echo $wgautomation2new | openssl enc -base64 -A`
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Custom WG Server List Command entered for WG Slot 2" >> $logfile
saveconfig
fi
;;
x7)
echo ""
echo -e "${CGreen}[Executing Script]${CClear}"
wgautomation2unenc=$(echo "$wgautomation2" | openssl enc -d -base64 -A)
echo -e "${CClear}Running: $wgautomation2unenc"
echo ""
eval "$wgautomation2unenc" > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
#Determine how many server entries are in each of the vpn slot alternate server files
if [ -f /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt ]; then
dlcnt=$(cat /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt | wc -l) >/dev/null 2>&1
if [ $dlcnt -lt 1 ]; then
dlcnt=0
elif [ -z $dlcnt ]; then
dlcnt=0
fi
else
dlcnt=0
fi
if [ "$dlcnt" -gt 1 ]
then
cp "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" "/jffs/addons/vpnmon-r3.d/vr3wgsvr2.txt" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source]${CClear}"
echo ""
echo -e "${CGreen}[Saved to WG Client Slot 2 Server List]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom WG Server List Command executed for WG Slot 2" >> $logfile
echo ""
skynetwhitelist wg2
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
else
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source - Preserving Original Server List]${CClear}"
echo ""
echo -e "${CGreen}[Please check Query Language or WG Service API may be down]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom WG Client Server List Query for WG Slot 2 yielded 0 rows -- Query may be invalid or WG API service may be down" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
fi
;;
s7)
echo ""
echo -e "${CGreen}[Executing Skynet Whitelist Import]${CClear}"
awk -F',' '{print $2}' /jffs/addons/vpnmon-r3.d/vr3wgsvr2.txt > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
firewall import whitelist /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt "VPNMON-R3 WG Slot 2 Import" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Contents of WG Slot 2 Imported]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Skynet Whitelist imported for WG Slot 2" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
;;
e8)
echo ""
if [ "$wgautomation3" = "" ] || [ -z "$wgautomation3" ]; then
echo -e "${CClear}Old Script: "
echo ""
else
echo -en "${CClear}Old Script: "; echo "$wgautomation3" | openssl enc -d -base64 -A
echo ""
fi
read -rp 'Enter New Script (e=Exit): ' wgautomation3new
if [ "$wgautomation3new" = "" ] || [ -z "$wgautomation3new" ]; then
wgautomation3=""
saveconfig
elif [ "$wgautomation3new" = "e" ]; then
echo ""; echo -e "${CGreen}[Exiting]${CClear}"; sleep 1
else
wgautomation3=`echo $wgautomation3new | openssl enc -base64 -A`
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Custom WG Server List Command entered for WG Slot 3" >> $logfile
saveconfig
fi
;;
x8)
echo ""
echo -e "${CGreen}[Executing Script]${CClear}"
wgautomation3unenc=$(echo "$wgautomation3" | openssl enc -d -base64 -A)
echo -e "${CClear}Running: $wgautomation3unenc"
echo ""
eval "$wgautomation3unenc" > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
#Determine how many server entries are in each of the vpn slot alternate server files
if [ -f /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt ]; then
dlcnt=$(cat /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt | wc -l) >/dev/null 2>&1
if [ $dlcnt -lt 1 ]; then
dlcnt=0
elif [ -z $dlcnt ]; then
dlcnt=0
fi
else
dlcnt=0
fi
if [ "$dlcnt" -gt 1 ]
then
cp "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" "/jffs/addons/vpnmon-r3.d/vr3wgsvr3.txt" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source]${CClear}"
echo ""
echo -e "${CGreen}[Saved to WG Client Slot 3 Server List]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom WG Server List Command executed for WG Slot 3" >> $logfile
echo ""
skynetwhitelist wg3
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
else
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source - Preserving Original Server List]${CClear}"
echo ""
echo -e "${CGreen}[Please check Query Language or WG Service API may be down]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom WG Client Server List Query for WG Slot 3 yielded 0 rows -- Query may be invalid or WG API service may be down" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
fi
;;
s8)
echo ""
echo -e "${CGreen}[Executing Skynet Whitelist Import]${CClear}"
awk -F',' '{print $2}' /jffs/addons/vpnmon-r3.d/vr3wgsvr3.txt > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
firewall import whitelist /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt "VPNMON-R3 WG Slot 3 Import" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Contents of WG Slot 3 Imported]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Skynet Whitelist imported for WG Slot 3" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
;;
e9)
echo ""
if [ "$wgautomation4" = "" ] || [ -z "$wgautomation4" ]; then
echo -e "${CClear}Old Script: "
echo ""
else
echo -en "${CClear}Old Script: "; echo "$wgautomation4" | openssl enc -d -base64 -A
echo ""
fi
read -rp 'Enter New Script (e=Exit): ' wgautomation4new
if [ "$wgautomation4new" = "" ] || [ -z "$wgautomation4new" ]; then
wgautomation4=""
saveconfig
elif [ "$wgautomation4new" = "e" ]; then
echo ""; echo -e "${CGreen}[Exiting]${CClear}"; sleep 1
else
wgautomation4=`echo $wgautomation4new | openssl enc -base64 -A`
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Custom WG Server List Command entered for WG Slot 4" >> $logfile
saveconfig
fi
;;
x9)
echo ""
echo -e "${CGreen}[Executing Script]${CClear}"
wgautomation4unenc=$(echo "$wgautomation4" | openssl enc -d -base64 -A)
echo -e "${CClear}Running: $wgautomation4unenc"
echo ""
eval "$wgautomation4unenc" > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
#Determine how many server entries are in each of the vpn slot alternate server files
if [ -f /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt ]; then
dlcnt=$(cat /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt | wc -l) >/dev/null 2>&1
if [ $dlcnt -lt 1 ]; then
dlcnt=0
elif [ -z $dlcnt ]; then
dlcnt=0
fi
else
dlcnt=0
fi
if [ "$dlcnt" -gt 1 ]
then
cp "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" "/jffs/addons/vpnmon-r3.d/vr3wgsvr4.txt" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source]${CClear}"
echo ""
echo -e "${CGreen}[Saved to WG Client Slot 4 Server List]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom WG Server List Command executed for WG Slot 4" >> $logfile
echo ""
skynetwhitelist wg4
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
else
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source - Preserving Original Server List]${CClear}"
echo ""
echo -e "${CGreen}[Please check Query Language or WG Service API may be down]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom WG Client Server List Query for WG Slot 4 yielded 0 rows -- Query may be invalid or WG API service may be down" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
fi
;;
s9)
echo ""
echo -e "${CGreen}[Executing Skynet Whitelist Import]${CClear}"
awk -F',' '{print $2}' /jffs/addons/vpnmon-r3.d/vr3wgsvr4.txt > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
firewall import whitelist /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt "VPNMON-R3 WG Slot 4 Import" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Contents of WG Slot 4 Imported]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Skynet Whitelist imported for WG Slot 4" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
;;
e0)
echo ""
if [ "$wgautomation5" = "" ] || [ -z "$wgautomation5" ]; then
echo -e "${CClear}Old Script: "
echo ""
else
echo -en "${CClear}Old Script: "; echo "$wgautomation5" | openssl enc -d -base64 -A
echo ""
fi
read -rp 'Enter New Script (e=Exit): ' wgautomation5new
if [ "$wgautomation5new" = "" ] || [ -z "$wgautomation5new" ]; then
wgautomation5=""
saveconfig
elif [ "$wgautomation5new" = "e" ]; then
echo ""; echo -e "${CGreen}[Exiting]${CClear}"; sleep 1
else
wgautomation5=`echo $wgautomation5new | openssl enc -base64 -A`
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Custom WG Server List Command entered for WG Slot 5" >> $logfile
saveconfig
fi
;;
x0)
echo ""
echo -e "${CGreen}[Executing Script]${CClear}"
wgautomation5unenc=$(echo "$wgautomation5" | openssl enc -d -base64 -A)
echo -e "${CClear}Running: $wgautomation5unenc"
echo ""
eval "$wgautomation5unenc" > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
#Determine how many server entries are in each of the vpn slot alternate server files
if [ -f /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt ]; then
dlcnt=$(cat /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt | wc -l) >/dev/null 2>&1
if [ $dlcnt -lt 1 ]; then
dlcnt=0
elif [ -z $dlcnt ]; then
dlcnt=0
fi
else
dlcnt=0
fi
if [ "$dlcnt" -gt 1 ]
then
cp "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" "/jffs/addons/vpnmon-r3.d/vr3wgsvr5.txt" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source]${CClear}"
echo ""
echo -e "${CGreen}[Saved to WG Client Slot 5 Server List]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom WG Server List Command executed for WG Slot 5" >> $logfile
echo ""
skynetwhitelist wg5
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
else
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source - Preserving Original Server List]${CClear}"
echo ""
echo -e "${CGreen}[Please check Query Language or WG Service API may be down]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom WG Client Server List Query for WG Slot 5 yielded 0 rows -- Query may be invalid or WG API service may be down" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
fi
;;
s0)
echo ""
echo -e "${CGreen}[Executing Skynet Whitelist Import]${CClear}"
awk -F',' '{print $2}' /jffs/addons/vpnmon-r3.d/vr3wgsvr5.txt > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
firewall import whitelist /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt "VPNMON-R3 WG Slot 5 Import" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo ""
echo -e "${CGreen}[Contents of WG Slot 5 Imported]${CClear}"
echo ""
echo -e "${CGreen}[Execution Complete]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Skynet Whitelist imported for WG Slot 5" >> $logfile
echo ""
read -rsp $'Press any key to acknowledge...\n' -n1 key
;;
[Ee])
timer="$timerloop"
break;;
esac
fi
done
}
# -------------------------------------------------------------------------------------------------------------------------
# timerloopconfig lets you configure how long you want the timer cycle to last between vpn connection checks
##----------------------------------------##
## Modified by Martinski W. [2024-Nov-02] ##
##----------------------------------------##
timerloopconfig()
{
while true
do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Timer Loop Configuration / Recovery Timeout Opportunities ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate how long the timer cycle should take between Connectivity checks,${CClear}"
echo -e "${InvGreen} ${CClear} as well as the number of Recovery Timeout Opportunities the loop should complete${CClear}"
echo -e "${InvGreen} ${CClear} before issuing a connection reset.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Recovery Timeout Opportunities are simply the number of chances the script will${CClear}"
echo -e "${InvGreen} ${CClear} give the connection to recover on its own before intervening. With this value${CClear}"
echo -e "${InvGreen} ${CClear} defaulting to 1x, if connectivity issues occur within the default 60 second Timer${CClear}"
echo -e "${InvGreen} ${CClear} Loop, the connectivity will be reset after those 60 seconds."
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Example: 60 Second Timer Loops with 3x Recovery Timeouts would reset the connection${CClear}"
echo -e "${InvGreen} ${CClear} after 3 minutes."
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} (Defaults: Timer Loop = 60 seconds | Recovery Timeouts = 1x)${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Current: Timer Loop = ${CGreen}$timerloop sec ${CClear}| Recovery Timeouts: ${CGreen}${recover}x${CClear}"
echo
read -p "Please enter new Timer Loop value in seconds [10-999] (e=Exit): " newTimerLoop
if [ -z "$newTimerLoop" ] || echo "$newTimerLoop" | grep -qE "^(e|E)$"
then
if echo "$timerloop" | grep -qE "^([1-9][0-9]{0,2})$" && \
[ "$timerloop" -ge 10 ] && [ "$timerloop" -le 999 ]
then
timer="$timerloop"
printf "\n${CClear}[Exiting]\n"
sleep 1 ; break
else
printf "\n${CRed}*ERROR*: Please enter a valid number between 10 and 999.${CClear}\n"
sleep 3
fi
elif echo "$newTimerLoop" | grep -qE "^([1-9][0-9]{0,2})$" && \
[ "$newTimerLoop" -ge 10 ] && [ "$newTimerLoop" -le 999 ]
then
timerloop="$newTimerLoop"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Timer Loop configuration saved" >> $logfile
saveconfig
timer="$timerloop"
printf "\n${CClear}[OK]\n"
sleep 1
else
printf "\n${CRed}*ERROR*: Please enter a valid number between 10 and 999.${CClear}\n"
sleep 3
fi
echo ""
read -p "Please enter new Recovery Timeout value [1-9] (e=Exit): " newRecoveryTimeout
if [ -z "$newRecoveryTimeout" ] || echo "$newRecoveryTimeout" | grep -qE "^(e|E)$"
then
if echo "$recover" | grep -qE "^([1-9])$" && \
[ "$recover" -ge 1 ] && [ "$recover" -le 9 ]
then
printf "\n${CClear}[Exiting]\n"
sleep 1 ; break
else
printf "\n${CRed}*ERROR*: Please enter a valid number between 1 and 9.${CClear}\n"
sleep 3
fi
elif echo "$newRecoveryTimeout" | grep -qE "^([1-9])$" && \
[ "$newRecoveryTimeout" -ge 1 ] && [ "$newRecoveryTimeout" -le 9 ]
then
recover="$newRecoveryTimeout"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New Recovery Timeout Opportunity configuration saved" >> $logfile
saveconfig
printf "\n${CClear}[OK]\n"
sleep 1 ; break
else
printf "\n${CRed}*ERROR*: Please enter a valid number between 1 and 9.${CClear}\n"
sleep 3
fi
done
}
# -------------------------------------------------------------------------------------------------------------------------
# maxping lets you configure how high the vpn tunnel ping will get before it's reset
##----------------------------------------##
## Modified by Martinski W. [2024-Oct-05] ##
##----------------------------------------##
maxping()
{
while true
do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Maximum Ping Before Reset ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate how high the PING can be across your VPN tunnel before resetting the${CClear}"
echo -e "${InvGreen} ${CClear} connection in favor of a different server with a lower PING? A connection with a${CClear}"
echo -e "${InvGreen} ${CClear} lower PING may provide better network performance and less latency.${CClear}"
echo -e "${InvGreen} ${CClear} (Default = 500 milliseconds, Disabled = 0)${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Current: ${CGreen}$pingreset ms${CClear}"
echo
read -p "Please enter numeric value (0-999)? (0=Disabled, e=Exit): " newPingReset
if echo "$newPingReset" | grep -qE "^(0|[1-9][0-9]{0,2})$" && \
[ "$newPingReset" -ge 0 ] && [ "$newPingReset" -le 999 ]
then
pingreset="$newPingReset"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: PING Reset Configuration saved" >> $logfile
saveconfig
elif [ -z "$newPingReset" ] || echo "$newPingReset" | grep -qE "^(E|e)$"
then
echo ; echo -e "${CClear}[Exiting]"
timer="$timerloop"
sleep 2
break
else
echo
echo -e "${CClear}[Please enter value between 0 and 999, e=Exit]"
sleep 3
fi
done
}
##-------------------------------------##
## Added by Martinski W. [2024-Oct-06] ##
##-------------------------------------##
_ValidateCronJobHour_()
{
if [ $# -eq 0 ] || [ -z "$1" ] ; then return 1 ; fi
if echo "$1" | grep -qE "^(0|[1-9][0-9]?)$" && \
[ "$1" -ge 0 ] && [ "$1" -lt 24 ]
then return 0 ; else return 1 ; fi
}
_ValidateCronJobMinute_()
{
if [ $# -eq 0 ] || [ -z "$1" ] ; then return 1 ; fi
if echo "$1" | grep -qE "^(0|[1-9][0-9]?)$" && \
[ "$1" -ge 0 ] && [ "$1" -lt 60 ]
then return 0 ; else return 1 ; fi
}
# -------------------------------------------------------------------------------------------------------------------------
# schedulevpnreset lets you enable and set a time for a scheduled daily vpn reset
##----------------------------------------##
## Modified by Martinski W. [2024-Oct-06] ##
##----------------------------------------##
schedulevpnreset()
{
while true
do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} VPN Reset Scheduler ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate below if you would like to enable and schedule a daily VPN Reset CRON"
echo -e "${InvGreen} ${CClear} job. This will reset each monitored VPN connection. (Default = Disabled)"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo -e "${InvGreen} ${CClear}"
if [ "$schedule" = "0" ]
then
echo -e "${InvGreen} ${CClear} Current: ${CRed}Disabled${CClear}"
elif [ "$schedule" = "1" ]
then
schedhrs="$(awk "BEGIN {printf \"%02.f\",${schedulehrs}}")"
schedmin="$(awk "BEGIN {printf \"%02.f\",${schedulemin}}")"
schedtime="${CGreen}$schedhrs:$schedmin${CClear}"
echo -e "${InvGreen} ${CClear} Current: ${CGreen}Enabled, Daily @ $schedtime${CClear}"
fi
echo
read -p 'Schedule Daily Reset? (0=No, 1=Yes, e=Exit): ' newSchedule
if [ -z "$newSchedule" ] ; then newSchedule="${schedule:=0}" ; fi
if [ "$newSchedule" = "0" ]
then
schedule=0
if [ -f /jffs/scripts/services-start ]
then
sed -i -e '/vpnmon-r3.sh/d' /jffs/scripts/services-start
cru d RunVPNMONR3reset
schedulehrs=1
schedulemin=0
echo ""
echo -e "${CGreen}[Modifiying SERVICES-START file]..."
sleep 2
echo ""
echo -e "${CGreen}[Modifying CRON jobs]..."
sleep 2
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN Reset Schedule Disabled" >> $logfile
saveconfig
timer="$timerloop"
break
fi
elif [ "$newSchedule" = "1" ]
then
schedule=1
echo
echo -e "${InvGreen} ${InvDkGray}${CWhite} VPN Reset Scheduler ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate below what time you would like to schedule a daily VPN Reset CRON"
echo -e "${InvGreen} ${CClear} job. (Default = 1 hr, 0 min = 01:00 = 1:00am)"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo
read -p 'Schedule HOURS [0-23]?: ' newScheduleHrs
if [ -z "$newScheduleHrs" ]
then
if _ValidateCronJobHour_ "$schedulehrs"
then scheduleHrsOK=true
else scheduleHrsOK=false
fi
elif _ValidateCronJobHour_ "$newScheduleHrs"
then
scheduleHrsOK=true
schedulehrs="$newScheduleHrs"
else
scheduleHrsOK=false
schedulehrs="${schedulehrs:=1}"
printf "${CRed}*ERROR*: INVALID Entry.${CClear}\n\n"
fi
read -p 'Schedule MINUTES [0-59]?: ' newScheduleMins
if [ -z "$newScheduleMins" ]
then
if _ValidateCronJobMinute_ "$schedulemin"
then scheduleMinsOK=true
else scheduleMinsOK=false
fi
elif _ValidateCronJobMinute_ "$newScheduleMins"
then
scheduleMinsOK=true
schedulemin="$newScheduleMins"
else
scheduleMinsOK=false
schedulemin="${schedulemin:=0}"
printf "${CRed}*ERROR*: INVALID Entry.${CClear}\n"
fi
if ! "$scheduleHrsOK" || ! "$scheduleMinsOK"
then
doResetSave=false
if ! "$scheduleHrsOK" && ! _ValidateCronJobHour_ "$schedulehrs"
then schedulehrs=1 ; doResetSave=true
fi
if ! "$scheduleMinsOK" && ! _ValidateCronJobMinute_ "$schedulemin"
then schedulemin=0 ; doResetSave=true
fi
if "$doResetSave"
then
schedule=0
saveconfig
printf "\n${CRed}INVALID input found. Resetting values.${CClear}\n\n"
else
printf "\n${CRed}INVALID input found. No changes made.${CClear}\n\n"
fi
echo -e "${CClear}[Exiting]"
timer="$timerloop"
sleep 3
break
fi
echo
echo -e "${CGreen}[Modifying SERVICES-START file]..."
sleep 2
if [ -f /jffs/scripts/services-start ]
then
if ! grep -q -F "sh /jffs/scripts/vpnmon-r3.sh -reset" /jffs/scripts/services-start
then
echo 'cru a RunVPNMONR3reset "'"$schedulemin $schedulehrs * * * sh /jffs/scripts/vpnmon-r3.sh -reset"'"' >> /jffs/scripts/services-start
cru a RunVPNMONR3reset "$schedulemin $schedulehrs * * * sh /jffs/scripts/vpnmon-r3.sh -reset"
else
#delete and re-add if it already exists in case there's a time change
sed -i -e '/vpnmon-r3.sh/d' /jffs/scripts/services-start
cru d RunVPNMONR3reset
echo 'cru a RunVPNMONR3reset "'"$schedulemin $schedulehrs * * * sh /jffs/scripts/vpnmon-r3.sh -reset"'"' >> /jffs/scripts/services-start
cru a RunVPNMONR3reset "$schedulemin $schedulehrs * * * sh /jffs/scripts/vpnmon-r3.sh -reset"
fi
else
echo 'cru a RunVPNMONR3reset "'"$schedulemin $schedulehrs * * * sh /jffs/scripts/vpnmon-r3.sh -reset"'"' >> /jffs/scripts/services-start
chmod 755 /jffs/scripts/services-start
cru a RunVPNMONR3reset "$schedulemin $schedulehrs * * * sh /jffs/scripts/vpnmon-r3.sh -reset"
fi
echo
echo -e "${CGreen}[Modifying CRON jobs]..."
sleep 2
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN Reset Schedule Enabled" >> $logfile
saveconfig
timer="$timerloop"
break
elif [ "$newSchedule" = "e" ]
then
echo ; echo -e "${CClear}[Exiting]"
timer="$timerloop"
sleep 2
break
else
schedule="${schedule:=0}"
schedulehrs="${schedulehrs:=1}"
schedulemin="${schedulemin:=0}"
saveconfig
fi
done
}
# -------------------------------------------------------------------------------------------------------------------------
# autostart lets you enable the ability for vpnmon-r3 to autostart after a router reboot
autostart()
{
while true; do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Reboot Protection ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Please indicate below if you would like to enable VPNMON-R3 to autostart after a"
echo -e "${InvGreen} ${CClear} router reboot. This will ensure continued, uninterrupted VPN connection monitoring."
echo -e "${InvGreen} ${CClear} (Default = Disabled)"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo -e "${InvGreen} ${CClear}"
if [ "$autostart" = "0" ]
then
echo -e "${InvGreen} ${CClear} Current: ${CRed}Disabled${CClear}"
elif [ "$autostart" = "1" ]
then
echo -e "${InvGreen} ${CClear} Current: ${CGreen}Enabled${CClear}"
fi
echo
read -p 'Enable Reboot Protection? (0=No, 1=Yes, e=Exit): ' newAutoStart
# Use default value on enter keypress or invalid input #
if [ -z "$newAutoStart" ] ; then newAutoStart="${autostart:=0}" ; fi
if [ "$newAutoStart" = "0" ]
then
autostart=0
if [ -f /jffs/scripts/post-mount ]
then
sed -i -e '/vpnmon-r3.sh/d' /jffs/scripts/post-mount
echo ""
echo -e "${CGreen}[Modifying POST-MOUNT file]..."
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Reboot Protection Disabled" >> $logfile
saveconfig
sleep 2
timer="$timerloop"
break
fi
elif [ "$newAutoStart" = "1" ]
then
autostart=1
if [ -f /jffs/scripts/post-mount ]
then
if ! grep -q -F "(sleep 30 && /jffs/scripts/vpnmon-r3.sh -screen) & # Added by vpnmon-r3" /jffs/scripts/post-mount
then
echo "(sleep 30 && /jffs/scripts/vpnmon-r3.sh -screen) & # Added by vpnmon-r3" >> /jffs/scripts/post-mount
echo
echo -e "${CGreen}[Modifying POST-MOUNT file]..."
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Reboot Protection Enabled" >> $logfile
saveconfig
sleep 2
timer="$timerloop"
break
else
saveconfig
sleep 1
fi
else
echo "#!/bin/sh" > /jffs/scripts/post-mount
echo "" >> /jffs/scripts/post-mount
echo "(sleep 30 && /jffs/scripts/vpnmon-r3.sh -screen) & # Added by vpnmon-r3" >> /jffs/scripts/post-mount
chmod 755 /jffs/scripts/post-mount
echo
echo -e "${CGreen}[Modifying POST-MOUNT file]..."
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Reboot Protection Enabled" >> $logfile
saveconfig
sleep 2
timer="$timerloop"
break
fi
elif [ "$newAutoStart" = "e" ]
then
echo ; echo -e "${CClear}[Exiting]"
timer="$timerloop"
sleep 2
break
else
autostart="${autostart:=0}"
saveconfig
fi
done
}
# -------------------------------------------------------------------------------------------------------------------------
# trimlogs will cut down log size (in rows) based on custom value
trimlogs()
{
if [ "$logsize" -gt 0 ]
then
currlogsize="$(wc -l $logfile | awk '{ print $1 }')" # Determine the number of rows in the log
if [ "$currlogsize" -gt "$logsize" ] # If it's bigger than the max allowed, tail/trim it!
then
echo "$(tail -$logsize $logfile)" > $logfile
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Trimmed the log file down to $logsize lines" >> $logfile
fi
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# saveconfig saves the vpnmon-r3.cfg file after every major change, and applies that to the script on the fly
saveconfig()
{
{ echo 'availableslots="'"$availableslots"'"'
echo 'PINGHOST="'"$PINGHOST"'"'
echo 'logsize='$logsize
echo 'timerloop='$timerloop
echo 'recover='$recover
echo 'schedule='$schedule
echo 'schedulehrs='$schedulehrs
echo 'schedulemin='$schedulemin
echo 'autostart='$autostart
echo 'pingreset='$pingreset
echo 'automation1="'"$automation1"'"'
echo 'automation2="'"$automation2"'"'
echo 'automation3="'"$automation3"'"'
echo 'automation4="'"$automation4"'"'
echo 'automation5="'"$automation5"'"'
echo 'wgautomation1="'"$wgautomation1"'"'
echo 'wgautomation2="'"$wgautomation2"'"'
echo 'wgautomation3="'"$wgautomation3"'"'
echo 'wgautomation4="'"$wgautomation4"'"'
echo 'wgautomation5="'"$wgautomation5"'"'
echo 'refreshserverlists='$refreshserverlists
echo 'unboundclient='$unboundclient
echo 'unboundwgclient='$unboundwgclient
echo 'unboundshowip='$unboundshowip
echo 'monitorwan='$monitorwan
echo 'useovpn='$useovpn
echo 'usewg='$usewg
echo 'updateskynet='$updateskynet
echo 'amtmemailsuccess='$amtmemailsuccess
echo 'amtmemailfailure='$amtmemailfailure
echo 'rstspdmerlin='$rstspdmerlin
echo 'ratelimit='$ratelimit
echo 'selectionmethod='$selectionmethod
echo 'lowutilspd='$lowutilspd
echo 'medutilspd='$medutilspd
echo 'lowutilspdup='$lowutilspdup
echo 'medutilspdup='$medutilspdup
echo 'bwdisp='$bwdisp
} > "$config"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: New vpnmon-r3.cfg File Saved" >> $logfile
if [ -f "$config" ]
then
source "$config"
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# VPN_GetClientState was created by @Martinski in many thanks to trying to eliminate unknown operand errors due to null
# vpn_clientX_state values
_VPN_GetClientState_()
{
if [ $# -lt 1 ] || [ -z "$1" ] || ! echo "$1" | grep -qE "^[1-5]$"
then echo "**ERROR**" ; return 1 ; fi
local nvramVal="$($timeoutcmd$timeoutsec nvram get "vpn_client${1}_state")"
if [ -z "$nvramVal" ] || ! echo "$nvramVal" | grep -qE "^[+-]?[0-9]$"
then echo "0" ; else echo "$nvramVal" ; fi
return 0
}
# -------------------------------------------------------------------------------------------------------------------------
# WG_GetClientState is based off _VPN_GetClientState_
_WG_GetClientState_()
{
if [ $# -lt 1 ] || [ -z "$1" ] || ! echo "$1" | grep -qE "^[1-5]$"
then echo "**ERROR**" ; return 1 ; fi
# Inspiration from ZebMcKayHan's WGC Watchdog Script
last_handshake=$(wg show wgc$1 latest-handshakes | awk '{print $2}') >/dev/null 2>&1
if [ -z $last_handshake ]
then
WGnvramVal=0 #disconnected
else
WGnvramVal=2 #connected
fi
#local WGnvramVal="$($timeoutcmd$timeoutsec nvram get "wgc${1}_enable")"
if [ -z "$WGnvramVal" ] || ! echo "$WGnvramVal" | grep -qE "^[+-]?[0-9]$"
then echo "0" ; else echo "$WGnvramVal" ; fi
return 0
}
# -------------------------------------------------------------------------------------------------------------------------
########################################################################
# AMTM Email Notification Functionality generously donated by @Martinski!
#
# Creation Date: 2020-Jun-11 [Martinski W.]
# Last Modified: 2024-Feb-07 [Martinski W.]
# Modified for VPNMON-R3 Purposes [Viktor Jaep]
########################################################################
#-----------------------------------------------------------#
_DownloadCEMLibraryFile_()
{
local msgStr retCode
case "$1" in
update) msgStr="Updating" ;;
install) msgStr="Installing" ;;
*) return 1 ;;
esac
printf "\33[2K\r"
printf "${CGreen}\r[INFO: ${msgStr} the shared AMTM email library script file to support email notifications...]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: ${msgStr} the shared AMTM email library script file to support email notifications..." >> $logfile
mkdir -m 755 -p "$CUSTOM_EMAIL_LIBDir"
curl -kLSs --retry 3 --retry-delay 5 --retry-connrefused \
"${CEM_LIB_URL}/$CUSTOM_EMAIL_LIBName" -o "$CUSTOM_EMAIL_LIBFile"
curlCode="$?"
if [ "$curlCode" -eq 0 ] && [ -f "$CUSTOM_EMAIL_LIBFile" ]
then
retCode=0
chmod 755 "$CUSTOM_EMAIL_LIBFile"
. "$CUSTOM_EMAIL_LIBFile"
#printf "\nDone.\n"
else
retCode=1
printf "\33[2K\r"
printf "${CRed}\r[ERROR: Unable to download the shared library script file ($CUSTOM_EMAIL_LIBName).]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - **ERROR**: Unable to download the shared AMTM email library script file [$CUSTOM_EMAIL_LIBName]." >> $logfile
fi
return "$retCode"
}
#-----------------------------------------------------------#
# ARG1: The email name/alias to be used as "FROM_NAME"
# ARG2: The email Subject string.
# ARG3: Full path of file containing the email Body text.
# ARG4: The email Body Title string [OPTIONAL].
#-----------------------------------------------------------#
_SendEMailNotification_()
{
if [ -z "${amtmIsEMailConfigFileEnabled:+xSETx}" ]
then
printf "\33[2K\r"
printf "${CRed}\r[ERROR: Email library script ($CUSTOM_EMAIL_LIBFile) *NOT* FOUND.]${CClear}"
sleep 5
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - **ERROR**: Email library script [$CUSTOM_EMAIL_LIBFile] *NOT* FOUND." >> $logfile
return 1
fi
if [ $# -lt 3 ] || [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]
then
printf "\33[2K\r"
printf "${CRed}\r[ERROR: INSUFFICIENT email parameters]${CClear}"
sleep 5
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - **ERROR**: INSUFFICIENT email parameters." >> $logfile
return 1
fi
local retCode emailBodyTitleStr=""
[ $# -gt 3 ] && [ -n "$4" ] && emailBodyTitleStr="$4"
FROM_NAME="$1"
_SendEMailNotification_CEM_ "$2" "-F=$3" "$emailBodyTitleStr"
retCode="$?"
if [ "$retCode" -eq 0 ]
then
printf "\33[2K\r"
printf "${CGreen}\r[Email notification was sent successfully ($2)]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Email notification was sent successfully [$2]" >> $logfile
sleep 5
else
printf "\33[2K\r"
printf "${CRed}\r[ERROR: Failure to send email notification (Error Code: $retCode - $2).]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - **ERROR**: Failure to send email notification [$2]" >> $logfile
sleep 5
fi
return "$retCode"
}
# -------------------------------------------------------------------------------------------------------------------------
# sendmessage is a function that sends an AMTM email based on activity within VPNMON-R3
# $1 = Success/Failure 0/1
# $2 = Component
# $3 = VPN Slot
sendmessage()
{
#If AMTM email functionality is disabled, return back to the function call
if [ "$amtmemailsuccess" = "0" ] && [ "$amtmemailfailure" = "0" ]; then
return
fi
#Load, install or update the shared AMTM Email integration library
if [ -f "$CUSTOM_EMAIL_LIBFile" ]
then
. "$CUSTOM_EMAIL_LIBFile"
if [ -z "${CEM_LIB_VERSION:+xSETx}" ] || \
_CheckLibraryUpdates_CEM_ "$CUSTOM_EMAIL_LIBDir" quiet
then
_DownloadCEMLibraryFile_ "update"
fi
else
_DownloadCEMLibraryFile_ "install"
fi
cemIsFormatHTML=true
cemIsVerboseMode=false
tmpEMailBodyFile="/tmp/var/tmp/tmpEMailBody_${scriptFileNTag}.$$.TXT"
ratelimiter
emaillimit="$?"
if [ "$emaillimit" -eq 0 ]
then
#Pick the scenario and send email
if [ "$1" = "1" ] && [ "$amtmemailfailure" = "1" ]; then
if [ "$2" = "Recovering from WAN Down" ]; then
emailSubject="ALERT: Router Recovering from WAN Down"
emailBodyTitle="ALERT: Router Recovering from WAN Down"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "ALERT: VPNMON-R3 is currently recovering from a WAN Down Situation!\n"
printf "Router has detected a WAN Link/Modem and waited 300 seconds for general network.\n"
printf "connectivity to stabilize before re-establishing VPN connectivity.\n"
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "VPN Slot In Error State" ]; then
emailSubject="FAILURE: VPN Slot $3 in Error State"
emailBodyTitle="FAILURE: VPN Slot $3 in Error State"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "FAILURE: VPNMON-R3 has detected that VPN Slot $3 is in an error state. VPN Slot $3 has been reset.\n"
printf "Please check your network environment and configuration if this error continues to persist."
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "VPN Tunnel Disconnected" ]; then
emailSubject="FAILURE: VPN Slot $3 has Disconnected"
emailBodyTitle="FAILURE: VPN Slot $3 has Disconnected"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "FAILURE: VPNMON-R3 has detected that VPN Slot $3 has disconnected. VPN Slot $3 has been reset.\n"
printf "Please check your network environment and configuration if this error continues to persist."
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "VPN Slot Is Non-Responsive" ]; then
emailSubject="FAILURE: VPN Slot $3 is Non-Responsive"
emailBodyTitle="FAILURE: VPN Slot $3 is Non-Responsive"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "FAILURE: VPNMON-R3 has detected that VPN Slot $3 is non-responsive. VPN Slot $3 has been reset.\n"
printf "Please check your network environment and configuration if this error continues to persist."
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "VPN Slot Exceeded Max Ping" ]; then
emailSubject="WARNING: VPN Slot $3 Exceeded Max Ping"
emailBodyTitle="WARNING: VPN Slot $3 Exceeded Max Ping"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "WARNING: VPNMON-R3 has detected that VPN Slot $3 exceeded max ping. VPN Slot $3 has been reset.\n"
printf "Please check your network environment and configuration if this error continues to persist."
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "VPN Slot Not Synced With Unbound" ]; then
emailSubject="WARNING: VPN Slot $3 Not Synced with Unbound"
emailBodyTitle="WARNING: VPN Slot $3 Not Synced with Unbound"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "WARNING: VPNMON-R3 has detected that VPN Slot $3 is not synced with Unbound. VPN Slot $3 has been reset.\n"
printf "Please check your network environment and configuration if this error continues to persist."
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "WG Slot Not Synced With Unbound" ]; then
emailSubject="WARNING: WG Slot $3 Not Synced with Unbound"
emailBodyTitle="WARNING: WG Slot $3 Not Synced with Unbound"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "WARNING: VPNMON-R3 has detected that WG Slot $3 is not synced with Unbound. WG Slot $3 has been reset.\n"
printf "Please check your network environment and configuration if this error continues to persist."
printf "\n"
} > "$tmpEMailBodyFile"
##-------------------------------------##
## Modified by Dan G. [2025-Jul-16] ##
##-------------------------------------##
elif [ "$2" = "VPN Server List Query Yielded 0 Rows" ]; then
emailSubject="WARNING: VPN Slot $3 Server List Query Yielded 0 Rows"
emailBodyTitle="WARNING: VPN Slot $3 Server List Query Yielded 0 Rows"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "WARNING: VPNMON-R3 has detected that the Custom Server List Query for VPN Slot $3 yielded 0 results.\n"
printf "This may be due to an error in the query, or the VPN provider API service may be down or unreachable."
printf "Please check your network environment and configuration if this error continues to persist."
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "WG Server List Query Yielded 0 Rows" ]; then
emailSubject="WARNING: WG Slot $3 Server List Query Yielded 0 Rows"
emailBodyTitle="WARNING: WG Slot $3 Server List Query Yielded 0 Rows"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "WARNING: VPNMON-R3 has detected that the Custom Server List Query for WG Slot $3 yielded 0 results.\n"
printf "This may be due to an error in the query, or the VPN provider API service may be down or unreachable."
printf "Please check your network environment and configuration if this error continues to persist."
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "WG Slot Exceeded Max Ping" ]; then
emailSubject="WARNING: WG Slot $3 Exceeded Max Ping"
emailBodyTitle="WARNING: WG Slot $3 Exceeded Max Ping"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "WARNING: VPNMON-R3 has detected that WG Slot $3 exceeded max ping. WG Slot $3 has been reset.\n"
printf "Please check your network environment and configuration if this error continues to persist."
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "WG Handshake Exceeded" ]; then
emailSubject="WARNING: WG Slot $3 Exceeded Handshake"
emailBodyTitle="WARNING: WG Slot $3 Exceeded Handshake"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "WARNING: VPNMON-R3 has detected that WG Slot $3 exceeded a 200s handshake. WG Slot $3 has been reset.\n"
printf "Please check your network environment and configuration if this error continues to persist."
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "WG Tunnel Disconnected" ]; then
emailSubject="WARNING: WG Slot $3 Tunnel Disconnected"
emailBodyTitle="WARNING: WG Slot $3 Tunnel Disconnected"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "WARNING: VPNMON-R3 has detected that WG Slot $3 tunnel disconnected. WG Slot $3 has been reset.\n"
printf "Please check your network environment and configuration if this error continues to persist."
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "WG Slot Is Non-Responsive" ]; then
emailSubject="WARNING: WG Slot $3 is Non-Responsive"
emailBodyTitle="WARNING: WG Slot $3 is Non-Responsive"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "WARNING: VPNMON-R3 has detected that WG Slot $3 is not responding. WG Slot $3 has been reset.\n"
printf "Please check your network environment and configuration if this error continues to persist."
printf "\n"
} > "$tmpEMailBodyFile"
fi
_SendEMailNotification_ "VPNMON-R3 v$version" "$emailSubject" "$tmpEMailBodyFile" "$emailBodyTitle"
fi
if [ "$1" = "0" ] && [ "$amtmemailsuccess" = "1" ]; then
if [ "$2" = "VPN Connection Scheduled Reset" ]; then
emailSubject="SUCCESS: VPN Slot $3 Manual/Scheduled Reset"
emailBodyTitle="SUCCESS: VPN Slot $3 Manual/Scheduled Reset"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "SUCCESS: VPNMON-R3 completed a successful manual/scheduled reset on VPN Slot $3\n"
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "VPN Reset" ]; then
emailSubject="SUCCESS: VPN Slot $3 Manual Reset"
emailBodyTitle="SUCCESS: VPN Slot $3 Manual Reset"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "SUCCESS: VPNMON-R3 completed a successful manual reset on VPN Slot $3\n"
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "VPN Killed" ]; then
emailSubject="SUCCESS: VPN Slot $3 Manually Stopped & Unmonitored"
emailBodyTitle="SUCCESS: VPN Slot $3 Manually Stopped & Unmonitored"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "SUCCESS: VPNMON-R3 successfully manually stopped and unmonitored VPN Slot $3\n"
printf "\n"
} > "$tmpEMailBodyFile"
##-------------------------------------##
## Added by Dan G. [2025-Jul-16] ##
##-------------------------------------##
elif [ "$2" = "WG Connection Scheduled Reset" ]; then
emailSubject="SUCCESS: WG Slot $3 Manual/Scheduled Reset"
emailBodyTitle="SUCCESS: WG Slot $3 Manual/Scheduled Reset"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "SUCCESS: VPNMON-R3 completed a successful manual/scheduled reset on WG Slot $3\n"
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "WG Reset" ]; then
emailSubject="SUCCESS: WG Slot $3 Manual Reset"
emailBodyTitle="SUCCESS: WG Slot $3 Manual Reset"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "SUCCESS: VPNMON-R3 completed a successful manual reset on WG Slot $3\n"
printf "\n"
} > "$tmpEMailBodyFile"
elif [ "$2" = "WG Killed" ]; then
emailSubject="SUCCESS: WG Slot $3 Manually Stopped & Unmonitored"
emailBodyTitle="SUCCESS: WG Slot $3 Manually Stopped & Unmonitored"
{
printf "Date/Time: $(date +'%b %d %Y %X')\n"
printf "Asus Router Model: ${ROUTERMODEL}\n"
printf "Firmware/Build Number: ${FWBUILD}\n"
printf "\n"
printf "SUCCESS: VPNMON-R3 successfully manually stopped and unmonitored WG Slot $3\n"
printf "\n"
} > "$tmpEMailBodyFile"
fi
_SendEMailNotification_ "VPNMON-R3 v$version" "$emailSubject" "$tmpEMailBodyFile" "$emailBodyTitle"
fi
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# Function to keep track of emails sent, and determine if they need to be rate-limited
ratelimiter()
{
#if rate limiting is disabled, exit right away
if [ "$ratelimit" = "0" ]; then
return 0
fi
#Make sure log file exists
touch "$vr3emails"
#check current time and 1h into the past
current_time=$(date +%s)
cutoff_time=$((current_time - 3600))
#create a temp file where current data will get moved over into that is less than 1hr old
vr3emailstemp="${vr3emails}.tmp"
awk -v cutoff="$cutoff_time" '$1 > cutoff' "$vr3emails" > "$vr3emailstemp"
#check to see how many emails have been sent in the last hour
recent_email_count=$(wc -l < "$vr3emailstemp" | tr -d ' ')
printf "\33[2K\r"
printf "${CGreen}\r[Checking email rate limit... $recent_email_count/$ratelimit emails sent within the last hour]"
sleep 2
#logic to determine if rate limit has been hit
if [ "$recent_email_count" -ge "$ratelimit" ]
then
printf "\33[2K\r"
printf "${CGreen}\r[Rate limit exceeded. Emails will be prevented from sending]"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Email Rate limit exceeded ($ratelimit). Emails will be prevented from sending." >> $logfile
sleep 2
mv "$vr3emailstemp" "$vr3emails"
return 1
else
printf "\33[2K\r"
printf "${CGreen}\r[Rate within limits. Proceeding to send email]"
sleep 1
echo "$current_time" >> "$vr3emailstemp"
mv "$vr3emailstemp" "$vr3emails"
return 0
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# Testing to see if VPNMON-R3 external reset is currently running, and if so, hold off until it finishes
lockcheck()
{
while [ -f "$lockfile" ]; do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} External VPN Reset Currently In-Progress ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} VPNMON-R3 is currently performing an external scheduled reset of the VPN through${CClear}"
echo -e "${InvGreen} ${CClear} the means of the '-reset' commandline option, or scheduled CRON job.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} [Retrying to resume normal operations every 15 seconds]${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo ""
spinner 15
lockactive=1
done
if [ "$lockactive" = "1" ]; then
timerreset=1
lockactive=0
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# Initiate a VPN restart - $1 = slot number
restartvpn()
{
echo -e "${CGreen}\nMessages: ${CClear}"
echo ""
#Check the current connection state of vpn slot
currvpnstate="$(_VPN_GetClientState_ "$1")"
if [ "$currvpnstate" -ne 0 ]; then
printf "${CGreen}\r[Stopping VPN Client $1]"
service stop_vpnclient$1 >/dev/null 2>&1
sleep 20
if [ "$currvpnstate" = "-1" ]; then
nvram set vpn_client$1_state=0
fi
printf "\33[2K\r"
fi
#Determine how many server entries are in the assigned vpn slot alternate servers file
if [ -f "/jffs/addons/vpnmon-r3.d/vr3svr$1.txt" ]
then
servers=$(cat "/jffs/addons/vpnmon-r3.d/vr3svr$1.txt" | wc -l) >/dev/null 2>&1
if [ -z "$servers" ] || [ "$servers" -eq 0 ]
then
#Restart the same server currently allocated to that vpn slot
currvpnhost=$($timeoutcmd$timeoutsec nvram get vpn_client$1_addr)
printf "\33[2K\r"
printf "${CGreen}\r[Starting VPN Client $1]"
service start_vpnclient$1 >/dev/null 2>&1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN$1 Connection Restarted - Current Server: $currvpnhost" >> $logfile
resettimer $1 "VPN"
sleep 10
printf "\33[2K\r"
printf "${CGreen}\r[Letting VPN$1 Settle]"
sleep 10
return
elif [ "$selectionmethod" -eq 1 ] # 1=roundrobin
then
robintracker="/jffs/addons/vpnmon-r3.d/vr3robin.txt"
# If the robintracker file doesn't exist, create it and start all from 0.
if [ ! -f "$robintracker" ]; then
{ echo 'VPN1RR=0'
echo 'VPN2RR=0'
echo 'VPN3RR=0'
echo 'VPN4RR=0'
echo 'VPN5RR=0'
echo 'WG1RR=0'
echo 'WG2RR=0'
echo 'WG3RR=0'
echo 'WG4RR=0'
echo 'WG5RR=0'
} > "$robintracker"
printf "\33[2K\r"
printf "${CGreen}\r[Writing New Sequential Tracker File]"
sleep 1
fi
# Read the last used line number from the tracker file, calculate next
lastused=$(grep 'VPN'$1'RR=' "$robintracker" | cut -d'=' -f2)
nextup="$((lastused+1))"
# Check if we've reached the end of the file. If so, loop back to line 1.
if [ "$nextup" -gt "$servers" ]; then
nextup=1
fi
printf "\33[2K\r"
printf "${CGreen}\r[Selecting Next Sequential Entry]"
#---------OVPN-specific nvram values
# Extract the target line and parse it
RNDVPNIP=$(sed -n "${nextup}p" /jffs/addons/vpnmon-r3.d/vr3svr$1.txt)
nvram set vpn_client"$1"_addr="$RNDVPNIP"
nvram set vpn_client"$1"_desc="VPN$1 - $RNDVPNIP added by VPNMON-R3"
sleep 2
#---------OVPN-specific nvram values
# Update the tracker file with the line number we just used.
sed -i "s/^VPN$1RR=.*/VPN$1RR=$nextup/" "$robintracker"
#Restart the new server currently allocated to that vpn slot
printf "\33[2K\r"
printf "${CGreen}\r[Starting VPN Client $1]"
service start_vpnclient$1 >/dev/null 2>&1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN$1 Connection Restarted [SEQ] - New Server: $RNDVPNIP" >> $logfile
resettimer $1 "VPN"
sleep 10
printf "\33[2K\r"
printf "${CGreen}\r[Letting VPN$1 Settle]"
sleep 10
elif [ "$selectionmethod" -eq 0 ] # 0=Random
then
#Pick a random server from the alternate servers file, populate in vpn client slot, and restart
printf "\33[2K\r"
printf "${CGreen}\r[Selecting Random Entry]"
RANDOM=$(awk 'BEGIN {srand(); print int(32768 * rand())}')
R_LINE=$(( RANDOM % servers + 1 ))
#---------OVPN-specific nvram values
RNDVPNIP=$(sed -n "${R_LINE}p" /jffs/addons/vpnmon-r3.d/vr3svr$1.txt)
nvram set vpn_client"$1"_addr="$RNDVPNIP"
nvram set vpn_client"$1"_desc="VPN$1 - $RNDVPNIP added by VPNMON-R3"
sleep 2
#---------OVPN-specific nvram values
#Restart the new server currently allocated to that vpn slot
printf "\33[2K\r"
printf "${CGreen}\r[Starting VPN Client $1]"
service start_vpnclient$1 >/dev/null 2>&1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN$1 Connection Restarted [RND] - New Server: $RNDVPNIP" >> $logfile
resettimer $1 "VPN"
sleep 10
printf "\33[2K\r"
printf "${CGreen}\r[Letting VPN$1 Settle]"
sleep 10
fi
else
#Restart the same server currently allocated to that vpn slot
printf "\33[2K\r"
printf "${CGreen}\r[Starting VPN Client $1]"
currvpnhost="$($timeoutcmd$timeoutsec nvram get vpn_client$1_addr)"
service start_vpnclient$1 >/dev/null 2>&1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN$1 Connection Restarted - Current Server: $currvpnhost" >> $logfile
resettimer $1 "VPN"
sleep 10
printf "\33[2K\r"
printf "${CGreen}\r[Letting VPN$1 Settle]"
sleep 10
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# Initiate a WG restart - $1 = slot number
restartwg()
{
echo -e "${CGreen}\nMessages: ${CClear}"
echo ""
#Check the current connection state of vpn slot
currwgstate="$(_WG_GetClientState_ $1)"
if [ "$currwgstate" -ne 0 ]; then
printf "${CGreen}\r[Stopping WG Client $1]"
service "stop_wgc $1" >/dev/null 2>&1
sleep 20
printf "\33[2K\r"
fi
#Determine how many server entries are in the assigned vpn slot alternate servers file
if [ -f "/jffs/addons/vpnmon-r3.d/vr3wgsvr$1.txt" ]
then
servers=$(cat "/jffs/addons/vpnmon-r3.d/vr3wgsvr$1.txt" | wc -l) >/dev/null 2>&1
if [ -z "$servers" ] || [ "$servers" -eq 0 ]
then
#Restart the same server currently allocated to that wg slot
currwghost="$($timeoutcmd$timeoutsec nvram get wgc$1_ep_addr)"
currwghostname="$($timeoutcmd$timeoutsec nvram get wgc$1_desc)"
printf "\33[2K\r"
printf "${CGreen}\r[Starting WG Client $1]"
service "start_wgc $1" >/dev/null 2>&1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: WGC$1 Connection Restarted - Current Server: $currwghostname | $currwghost" >> $logfile
resettimer $1 "WG"
sleep 10
printf "\33[2K\r"
printf "${CGreen}\r[Letting WGC$1 Settle]"
sleep 10
return
elif [ "$selectionmethod" -eq 1 ] # 1=roundrobin
then
robintracker="/jffs/addons/vpnmon-r3.d/vr3robin.txt"
# If the robintracker file doesn't exist, create it and start from 0.
if [ ! -f "$robintracker" ]; then
{ echo 'VPN1RR=0'
echo 'VPN2RR=0'
echo 'VPN3RR=0'
echo 'VPN4RR=0'
echo 'VPN5RR=0'
echo 'WG1RR=0'
echo 'WG2RR=0'
echo 'WG3RR=0'
echo 'WG4RR=0'
echo 'WG5RR=0'
} > "$robintracker"
printf "\33[2K\r"
printf "${CGreen}\r[Writing New Round-Robin Tracker File]"
sleep 1
fi
# Read the last used line number from the tracker file, calculate next
lastused=$(grep 'WG'$1'RR=' "$robintracker" | cut -d'=' -f2)
nextup="$((lastused+1))"
# Check if we've reached the end of the file. If so, loop back to line 1.
if [ "$nextup" -gt "$servers" ]; then
nextup=1
fi
printf "\33[2K\r"
printf "${CGreen}\r[Selecting Next Sequential Entry]"
#---------WG-specific nvram values
# Extract the target line and parse it
WGLINE=$(sed -n "${nextup}p" /jffs/addons/vpnmon-r3.d/vr3wgsvr$1.txt)
wgdescription=$(echo "$WGLINE" | cut -d ',' -f 1)
interfaceip=$(echo "$WGLINE" | cut -d ',' -f 2)
endpointip=$(echo "$WGLINE" | cut -d ',' -f 3)
endpointport=$(echo "$WGLINE" | cut -d ',' -f 4)
privatekey=$(echo "$WGLINE" | cut -d ',' -f 5)
publickey=$(echo "$WGLINE" | cut -d ',' -f 6)
presharedkey=$(echo "$WGLINE" | cut -d ',' -f 7) #Optional, required by AirVPN
nvram set wgc"$1"_desc="$wgdescription"
nvram set wgc"$1"_addr="$interfaceip"
nvram set wgc"$1"_ep_addr="$endpointip"
nvram set wgc"$1"_ep_addr_r="$endpointip"
nvram set wgc"$1"_ep_port="$endpointport"
nvram set wgc"$1"_priv="${privatekey}"
nvram set wgc"$1"_ppub="${publickey}"
nvram set wgc"$1"_psk="${presharedkey}" #Optional, required by AirVPN
sleep 2
#---------WG-specific nvram values
# Update the tracker file with the line number we just used.
sed -i "s/^WG$1RR=.*/WG$1RR=$nextup/" "$robintracker"
#Restart the new server currently allocated to that wg slot
printf "\33[2K\r"
printf "${CGreen}\r[Starting WG Client $1]"
service "start_wgc $1" >/dev/null 2>&1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: WGC$1 Connection Restarted [SEQ] - New Server: $wgdescription | $endpointip" >> $logfile
resettimer $1 "WG"
sleep 10
printf "\33[2K\r"
printf "${CGreen}\r[Letting WGC$1 Settle]"
sleep 10
elif [ "$selectionmethod" -eq 0 ] # 0=random
then
# Pick a random server from the alternate servers file, populate in wg client slot, and restart
printf "\33[2K\r"
printf "${CGreen}\r[Selecting Random Entry]"
RANDOM=$(awk 'BEGIN {srand(); print int(32768 * rand())}')
R_LINE=$(( RANDOM % servers + 1 ))
#---------WG-specific nvram values
WGLINE=$(sed -n "${R_LINE}p" /jffs/addons/vpnmon-r3.d/vr3wgsvr$1.txt)
wgdescription=$(echo "$WGLINE" | cut -d ',' -f 1)
interfaceip=$(echo "$WGLINE" | cut -d ',' -f 2)
endpointip=$(echo "$WGLINE" | cut -d ',' -f 3)
endpointport=$(echo "$WGLINE" | cut -d ',' -f 4)
privatekey=$(echo "$WGLINE" | cut -d ',' -f 5)
publickey=$(echo "$WGLINE" | cut -d ',' -f 6)
presharedkey=$(echo "$WGLINE" | cut -d ',' -f 7) #Optional, required by AirVPN
nvram set wgc"$1"_desc="$wgdescription"
nvram set wgc"$1"_addr="$interfaceip"
nvram set wgc"$1"_ep_addr="$endpointip"
nvram set wgc"$1"_ep_addr_r="$endpointip"
nvram set wgc"$1"_ep_port="$endpointport"
nvram set wgc"$1"_priv="${privatekey}"
nvram set wgc"$1"_ppub="${publickey}"
nvram set wgc"$1"_psk="${presharedkey}" #Optional, required by AirVPN
sleep 2
#---------WG-specific nvram values
# Restart the new server currently allocated to that wg slot
printf "\33[2K\r"
printf "${CGreen}\r[Starting WG Client $1]"
service "start_wgc $1" >/dev/null 2>&1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: WGC$1 Connection Restarted [RND] - New Server: $wgdescription | $endpointip" >> $logfile
resettimer $1 "WG"
sleep 10
printf "\33[2K\r"
printf "${CGreen}\r[Letting WGC$1 Settle]"
sleep 10
fi
else
#Restart the same server currently allocated to that wg slot
printf "\33[2K\r"
printf "${CGreen}\r[Starting WG Client $1]"
currwghost="$($timeoutcmd$timeoutsec nvram get wgc$1_ep_addr)"
service "start_wgc $1" >/dev/null 2>&1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: WGC$1 Connection Restarted - Current Server: $currwghost" >> $logfile
resettimer $1 "WG"
sleep 10
printf "\33[2K\r"
printf "${CGreen}\r[Letting WGC$1 Settle]"
sleep 10
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# Separating off the vpnrouting service restart
restartrouting()
{
printf "\33[2K\r"
printf "${CGreen}\r[Restarting VPN Routing]"
service restart_vpnrouting0 >/dev/null 2>&1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN Director Routing Service Restarted" >> $logfile
sleep 5
printf "\33[2K\r"
trimlogs
}
# -------------------------------------------------------------------------------------------------------------------------
# Optionally reset spdMerlin interfaces
resetspdmerlin()
{
if [ "$rstspdmerlin" = "1" ]
then
printf "\33[2K\r"
printf "${CGreen}\r[Reset spdMerlin Interfaces]"
/jffs/scripts/spdmerlin reset_interfaces force >/dev/null 2>&1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: spdMerlin Interfaces Reset" >> $logfile
sleep 5
printf "\33[2K\r"
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# Kill a vpn connnection, and unmonitor it - $1 = slot number
killunmonvpn()
{
# Stop the service
echo -e "${CGreen}\nMessages: ${CClear}"
echo ""
printf "${CGreen}\r[Stopping VPN Client $1]"
service stop_vpnclient$1 >/dev/null 2>&1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN$1 has been stopped and no longer being monitored" >> $logfile
sleep 15
printf "\33[2K\r"
printf "${CGreen}\r[Unmonitoring VPN Client $1]"
# Write the VPN client file back with the correct monitoring configuration
sed -i "s/^VPN$1=.*/VPN$1=0/" "/jffs/addons/vpnmon-r3.d/vr3clients.txt"
sed -i "s/^VPNTIMER$1=.*/VPNTIMER$1=0/" "/jffs/addons/vpnmon-r3.d/vr3timers.txt"
sleep 5
# Restart VPN Director Routing Services
restartrouting
}
# -------------------------------------------------------------------------------------------------------------------------
# Kill a wg connnection, and unmonitor it - $1 = slot number
killunmonwg()
{
# Stop the service
echo -e "${CGreen}\nMessages: ${CClear}"
echo ""
printf "${CGreen}\r[Stopping WG Client $1]"
service "stop_wgc $1" >/dev/null 2>&1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: WGC$1 has been stopped and no longer being monitored" >> $logfile
sleep 15
printf "\33[2K\r"
printf "${CGreen}\r[Unmonitoring WG Client $1]"
# Write the VPN client file back with the correct monitoring configuration
sed -i "s/^WG$1=.*/WG$1=0/" "/jffs/addons/vpnmon-r3.d/vr3clients.txt"
sed -i "s/^WGTIMER$1=.*/WGTIMER$1=0/" "/jffs/addons/vpnmon-r3.d/vr3timers.txt"
sleep 5
# Restart VPN Director Routing Services
restartrouting
}
# -------------------------------------------------------------------------------------------------------------------------
# Whitelist Server Slot IP lists in Skynet - $1 = VPN Slot
skynetwhitelist()
{
if [ "$updateskynet" = "1" ]
then
##-------------------------------------##
## Modified by Dan G. [2025-Jul-15] ##
##-------------------------------------##
if echo "$1" | grep -q "wg"; then
slotnum=$(echo "$1" | tr -cd '0-9')
printf "${CGreen}\r[Whitelisting WG Server Slot $slotnum List in the Skynet Firewall]${CClear}\n"
awk -F',' '{print $2}' /jffs/addons/vpnmon-r3.d/vr3wgsvr${slotnum}.txt > /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt
firewall import whitelist /jffs/addons/vpnmon-r3.d/vr3svrtmp.txt "VPNMON-R3 - WG Server Slot $slotnum Whitelist" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: WG Server Slot $slotnum List has been whitelisted in Skynet" >> $logfile
else
printf "${CGreen}\r[Whitelisting VPN Server Slot $1 List in the Skynet Firewall]${CClear}\n"
firewall import whitelist /jffs/addons/vpnmon-r3.d/vr3svr$1.txt "VPNMON-R3 - VPN Server Slot $1 Whitelist" >/dev/null 2>&1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN Server Slot $1 List has been whitelisted in Skynet" >> $logfile
fi
sleep 5
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# Reset the VPN connection timer
resettimer()
{
# Create initial vr3timers.txt file if it does not exist
if [ ! -f /jffs/addons/vpnmon-r3.d/vr3timers.txt ]; then
if [ "$availableslots" = "1 2" ]; then
{ echo 'VPNTIMER1=0'
echo 'VPNTIMER2=0'
} > /jffs/addons/vpnmon-r3.d/vr3timers.txt
elif [ "$availableslots" = "1 2 3 4 5" ]; then
{ echo 'VPNTIMER1=0'
echo 'VPNTIMER2=0'
echo 'VPNTIMER3=0'
echo 'VPNTIMER4=0'
echo 'VPNTIMER5=0'
echo 'WGTIMER1=0'
echo 'WGTIMER2=0'
echo 'WGTIMER3=0'
echo 'WGTIMER4=0'
echo 'WGTIMER5=0'
} > /jffs/addons/vpnmon-r3.d/vr3timers.txt
fi
fi
source /jffs/addons/vpnmon-r3.d/vr3timers.txt
source /jffs/addons/vpnmon-r3.d/vr3clients.txt
vpnslottmp="VPN${1}"
eval vpnslottmp="\$${vpnslottmp}"
wgslottmp="WG${1}"
eval wgslottmp="\$${wgslottmp}"
if [ "$2" = "VPN" ] && [ "$vpnslottmp" = "1" ]; then
sed -i "s/^VPNTIMER$1=.*/VPNTIMER$1=$(date +%s)/" "/jffs/addons/vpnmon-r3.d/vr3timers.txt"
elif [ "$2" = "WG" ] && [ "$wgslottmp" = "1" ]; then
sed -i "s/^WGTIMER$1=.*/WGTIMER$1=$(date +%s)/" "/jffs/addons/vpnmon-r3.d/vr3timers.txt"
fi
source /jffs/addons/vpnmon-r3.d/vr3timers.txt
source /jffs/addons/vpnmon-r3.d/vr3clients.txt
}
# -------------------------------------------------------------------------------------------------------------------------
# Reset the managed VPN connections
vreset()
{
# Grab the VPNMON-R3 config file and read it in
if [ -f "$config" ]
then
source "$config"
else
clear
echo -e "${CRed}ERROR: VPNMON-R3 is not configured. Please run 'vpnmon-r3.sh -setup' first."
echo ""
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: VPNMON-R3 config file not found. Please run the setup/configuration utility" >> $logfile
echo -e "${CClear}"
exit 1
fi
# Grab the monitored slots file and read it in
if [ -f /jffs/addons/vpnmon-r3.d/vr3clients.txt ]
then
source /jffs/addons/vpnmon-r3.d/vr3clients.txt
else
clear
echo -e "${CRed}ERROR: VPNMON-R3 is not configured. Please run 'vpnmon-r3.sh -setup' first."
echo ""
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: VPNMON-R3 VPN Client Monitoring file not found. Please run the setup/configuration utility" >> $logfile
echo -e "${CClear}"
exit 1
fi
# Create a rudimentary lockfile so that VPNMON-R3 doesn't interfere during the reset
echo -n > $lockfile
slot=0
for slot in $availableslots #loop through the 2/5 vpn slots
do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} VPNMON-R3 - v$version | $(date) ${CClear}\n"
echo -e "${CGreen}[VPN Connection Reset Commencing]"
echo ""
echo -e "${CGreen}[Checking VPN Slot $slot]"
echo ""
sleep 2
#determine if the slot is monitored and reset it
if [ "$((VPN$slot))" = "1" ]
then
if [ "$refreshserverlists" -eq 1 ]
then
if [ -f "/jffs/addons/vpnmon-r3.d/vr3svr$slot.txt" ]
then
echo -e "${CGreen}[Executing Custom Server List Script for VPN Slot $slot]${CClear}"
slottmp="automation${slot}"
eval slottmp="\$${slottmp}"
if [ -z "$slottmp" ]
then
echo ""
echo -e "${CGreen}[Custom VPN Client Server Query not found for VPN Slot $slot]${CClear}"
else
automationunenc="$(echo "$slottmp" | openssl enc -d -base64 -A)"
echo ""
echo -e "${CClear}Running: $automationunenc"
echo ""
eval "$automationunenc" > "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt"
if [ -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" ]
then
dlcnt=$(cat "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" | wc -l) >/dev/null 2>&1
if [ -z "$dlcnt" ] || [ "$dlcnt" -lt 1 ]
then dlcnt=0 ; fi
else
dlcnt=0
fi
if [ "$dlcnt" -gt 1 ]
then
cp "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" "/jffs/addons/vpnmon-r3.d/vr3svr$slot.txt" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom VPN Client Server List Query Executed for VPN Slot $slot ($dlcnt rows)" >> $logfile
sleep 3
echo ""
skynetwhitelist $slot
echo ""
else
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source - Preserving Original Server List]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom VPN Client Server List Query for VPN Slot $slot yielded 0 rows -- Query may be invalid or VPN API service may be down" >> $logfile
sendmessage 1 "VPN Server List Query Yielded 0 Rows" $slot
sleep 3
echo ""
fi
fi
else
echo ""
echo -e "${CRed}[Custom VPN Client Server List File not found for VPN Slot $slot]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom VPN Client Server List File not found for VPN Slot $slot" >> $logfile
sleep 3
fi
fi
restartvpn $slot
sendmessage 0 "VPN Connection Scheduled Reset" $slot
fi
done
slot=0
for slot in $availableslots #loop through the 5 wg slots
do
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} VPNMON-R3 - v$version | $(date) ${CClear}\n"
echo -e "${CGreen}[WG Connection Reset Commencing]"
echo ""
echo -e "${CGreen}[Checking WG Slot $slot]"
echo ""
sleep 2
#determine if the slot is monitored and reset it
if [ "$((WG$slot))" = "1" ]
then
if [ "$refreshserverlists" -eq 1 ]
then
if [ -f "/jffs/addons/vpnmon-r3.d/vr3wgsvr$slot.txt" ]
then
echo -e "${CGreen}[Executing Custom WG Server List Script for WG Slot $slot]${CClear}"
slottmp="wgautomation${slot}"
eval slottmp="\$${slottmp}"
if [ -z "$slottmp" ]
then
echo ""
echo -e "${CGreen}[Custom WG Client Server Query not found for WG Slot $slot]${CClear}"
else
wgautomationunenc="$(echo "$slottmp" | openssl enc -d -base64 -A)"
echo ""
echo -e "${CClear}Running: $wgautomationunenc"
echo ""
eval "$wgautomationunenc" > "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt"
if [ -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" ]
then
dlcnt=$(cat "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" | wc -l) >/dev/null 2>&1
if [ -z "$dlcnt" ] || [ "$dlcnt" -lt 1 ]
then dlcnt=0 ; fi
else
dlcnt=0
fi
if [ "$dlcnt" -gt 1 ]
then
cp "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" "/jffs/addons/vpnmon-r3.d/vr3wgsvr$slot.txt" >/dev/null 2>&1
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: Custom WG Client Server List Query Executed for WG Slot $slot ($dlcnt rows)" >> $logfile
sleep 3
echo ""
skynetwhitelist wg$slot
echo ""
else
rm -f "/jffs/addons/vpnmon-r3.d/vr3svrtmp.txt" >/dev/null 2>&1
echo -e "${CGreen}[$dlcnt Rows Retrieved From Source - Preserving Original Server List]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom WG Client Server List Query for WG Slot $slot yielded 0 rows -- Query may be invalid or WG API service may be down" >> $logfile
sendmessage 1 "WG Server List Query Yielded 0 Rows" $slot
sleep 3
echo ""
fi
fi
else
echo ""
echo -e "${CRed}[Custom WG Client Server List File not found for WG Slot $slot]${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: Custom WG Client Server List File not found for WG Slot $slot" >> $logfile
sleep 3
fi
fi
restartwg $slot
sendmessage 0 "WG Connection Scheduled Reset" $slot
fi
done
restartrouting
resetspdmerlin
echo -e "${CGreen}[Reset Complete]${CClear}"
# Clean up lockfile
rm -f $lockfile >/dev/null 2>&1
echo -e "\n${CClear}"
exit 0
}
# -------------------------------------------------------------------------------------------------------------------------
##----------------------------------------##
## Modified by Martinski W. [2024-Oct-18] ##
##----------------------------------------##
# Find the VPN IP
getvpnip()
{
ubsync=""
TUN="tun1$1"
icanhazvpnip="$($timeoutcmd$timeoutsec nvram get vpn_client$1_rip)"
if [ -z "$icanhazvpnip" ] || [ "$icanhazvpnip" = "unknown" ]
then
# Grab the public IP of the VPN Connection #
icanhazvpnip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$TUN" --request GET --url https://ipv4.icanhazip.com"
icanhazvpnip="$(eval $icanhazvpnip)"
if [ -z "$icanhazvpnip" ] || echo "$icanhazvpnip" | grep -qoE 'Internet|traffic|Error|error' ; then icanhazvpnip="0.0.0.0" ; fi
fi
if [ -z "$icanhazvpnip" ]
then
vpnip="000.000.000.000"
return
else
vpnip="$(printf '%15s' "$icanhazvpnip")"
fi
if [ "$unboundclient" -ne 0 ] && [ "$unboundclient" -eq "$1" ]
then
if [ "$ResolverTimer" -eq 1 ]; then
ResolverTimer=0
if [ "$unboundshowip" -eq 0 ]; then
ubsync="${CYellow}-?[UB]${CClear}"
else
ubsync="${CYellow}-?[UB:Resolving]${CClear}"
fi
else
# Huge thanks to @SomewhereOverTheRainbow for his expertise in troublshooting and coming up with this DNS Resolver methodology!
DNSResolver="$({ unbound-control flush whoami.akamai.net >/dev/null 2>&1; } && dig whoami.akamai.net +short @"$(netstat -nlp 2>/dev/null | awk '/.*(unbound){1}.*/{split($4, ip_addr, ":");if(substr($4,11) !~ /.*953.*/)print ip_addr[1];if(substr($4,11) !~ /.*953.*/)exit}')" -p "$(netstat -nlp 2>/dev/null | awk '/.*(unbound){1}.*/{if(substr($4,11) !~ /.*953.*/)print substr($4,11);if(substr($4,11) !~ /.*953.*/)exit}')" 2>/dev/null)"
if [ -z "$DNSResolver" ]
then
if [ "$unboundshowip" -eq 0 ]; then
ubsync="${CRed}-X[UB]${CClear}"
else
ubsync="${CRed}-X[UB:$DNSResolver]${CClear}"
fi
# rudimentary check to make sure value coming back is in the format of an IP address... Don't care if it's more than 255.
elif expr "$DNSResolver" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null
then
# If the DNS resolver and public VPN IP address don't match in our Unbound scenario, reset!
if [ "$DNSResolver" != "$icanhazvpnip" ]
then
if [ "$unboundshowip" -eq 0 ]; then
ubsync="${CRed}-X[UB]${CClear}"
else
ubsync="${CRed}-X[UB:$DNSResolver]${CClear}"
fi
ResolverTimer=1
unboundreset=$1
else
if [ "$unboundshowip" -eq 0 ]; then
ubsync="${CGreen}->[UB]${CClear}"
else
ubsync="${CGreen}->[UB:$DNSResolver]${CClear}"
fi
fi
else
if [ "$unboundshowip" -eq 0 ]; then
ubsync="${CYellow}-?[UB]${CClear}"
else
ubsync="${CYellow}-?[UB:$DNSResolver]${CClear}"
fi
fi
fi
else
ubsync=""
fi
# Insert bogus IP if screenshotmode is on #
if [ "$screenshotmode" = "1" ]; then
vpnip="$(printf '%15s' "12.34.56.78")"
fi
}
# -------------------------------------------------------------------------------------------------------------------------
##-----------------------------------------------------------------------------------------##
## Modified by ViktorJp [2025-Jul-06], origial getvpnip modded by Martinski. [2024-Oct-18] ##
##-----------------------------------------------------------------------------------------##
# Find the WG IP
getwgip()
{
ubsync=""
TUN="wgc$1"
# Added ping workaround for site2site scenarios based on suggestion from @ZebMcKayhan
TUN_IP=$($timeoutcmd$timeoutsec nvram get "$TUN"_addr | cut -d '/' -f1)
ip rule add from $TUN_IP lookup $TUN prio 10 >/dev/null 2>&1
icanhazwgip="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$TUN" --request GET --url https://ipv4.icanhazip.com"
icanhazwgip="$(eval $icanhazwgip)"
if [ -z "$icanhazwgip" ] || echo "$icanhazwgip" | grep -qoE 'Internet|traffic|Error|error' ; then icanhazwgip="0.0.0.0" ; fi
if [ -z "$icanhazwgip" ]
then
wgip="000.000.000.000"
return
else
wgip="$(printf '%15s' "$icanhazwgip")"
fi
if [ "$unboundwgclient" -ne 0 ] && [ "$unboundwgclient" -eq "$1" ]
then
if [ "$ResolverTimer" -eq 1 ]; then
ResolverTimer=0
if [ "$unboundshowip" -eq 0 ]; then
ubsync="${CYellow}-?[UB]${CClear}"
else
ubsync="${CYellow}-?[UB:Resolving]${CClear}"
fi
else
# Huge thanks to @SomewhereOverTheRainbow for his expertise in troublshooting and coming up with this DNS Resolver methodology!
DNSResolver="$({ unbound-control flush whoami.akamai.net >/dev/null 2>&1; } && dig whoami.akamai.net +short @"$(netstat -nlp 2>/dev/null | awk '/.*(unbound){1}.*/{split($4, ip_addr, ":");if(substr($4,11) !~ /.*953.*/)print ip_addr[1];if(substr($4,11) !~ /.*953.*/)exit}')" -p "$(netstat -nlp 2>/dev/null | awk '/.*(unbound){1}.*/{if(substr($4,11) !~ /.*953.*/)print substr($4,11);if(substr($4,11) !~ /.*953.*/)exit}')" 2>/dev/null)"
if [ -z "$DNSResolver" ]
then
if [ "$unboundshowip" -eq 0 ]; then
ubsync="${CRed}-X[UB]${CClear}"
else
ubsync="${CRed}-X[UB:$DNSResolver]${CClear}"
fi
# rudimentary check to make sure value coming back is in the format of an IP address... Don't care if it's more than 255.
elif expr "$DNSResolver" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null
then
# If the DNS resolver and public VPN IP address don't match in our Unbound scenario, reset!
if [ "$DNSResolver" != "$icanhazwgip" ]
then
if [ "$unboundshowip" -eq 0 ]; then
ubsync="${CRed}-X[UB]${CClear}"
else
ubsync="${CRed}-X[UB:$DNSResolver]${CClear}"
fi
ResolverTimer=1
unboundreset=$1
else
if [ "$unboundshowip" -eq 0 ]; then
ubsync="${CGreen}->[UB]${CClear}"
else
ubsync="${CGreen}->[UB:$DNSResolver]${CClear}"
fi
fi
else
if [ "$unboundshowip" -eq 0 ]; then
ubsync="${CYellow}-?[UB]${CClear}"
else
ubsync="${CYellow}-?[UB:$DNSResolver]${CClear}"
fi
fi
fi
else
ubsync=""
fi
# Added based on suggestion from @ZebMcKayhan
ip rule del prio 10 >/dev/null 2>&1
# Insert bogus IP if screenshotmode is on #
if [ "$screenshotmode" = "1" ]; then
wgip="$(printf '%15s' "12.34.56.78")"
fi
}
# -------------------------------------------------------------------------------------------------------------------------
##----------------------------------------##
## Modified by Martinski W. [2024-Oct-18] ##
##----------------------------------------##
# Find and remember the VPN city so it doesn't have to make successive API lookups
getvpncity()
{
if [ "$icanhazvpnip" = "0.0.0.0" ]; then
vpncity="Undetermined"
return
fi
if [ "$1" = "1" ]
then
lastvpnip1="$icanhazvpnip"
if [ "$lastvpnip1" != "$oldvpnip1" ]
then
vpncity="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --request GET --url http://ip-api.com/json/$icanhazvpnip | jq --raw-output .city"
vpncity="$(eval $vpncity)"
if [ -z "$vpncity" ] || echo "$vpncity" | grep -qoE '\b(error.*:.*True.*|Undefined)\b' ; then vpncity="Undetermined" ; fi
citychange="${CGreen}- NEW ${CClear}"
vpncity1="$vpncity"
fi
vpncity="$vpncity1"
oldvpnip1="$lastvpnip1"
elif [ "$1" = "2" ]
then
lastvpnip2="$icanhazvpnip"
if [ "$lastvpnip2" != "$oldvpnip2" ]
then
vpncity="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --request GET --url http://ip-api.com/json/$icanhazvpnip | jq --raw-output .city"
vpncity="$(eval $vpncity)"
if [ -z "$vpncity" ] || echo "$vpncity" | grep -qoE '\b(error.*:.*True.*|Undefined)\b' ; then vpncity="Undetermined" ; fi
citychange="${CGreen}- NEW ${CClear}"
vpncity2="$vpncity"
fi
vpncity="$vpncity2"
oldvpnip2="$lastvpnip2"
elif [ "$1" = "3" ]
then
lastvpnip3="$icanhazvpnip"
if [ "$lastvpnip3" != "$oldvpnip3" ]
then
vpncity="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --request GET --url http://ip-api.com/json/$icanhazvpnip | jq --raw-output .city"
vpncity="$(eval $vpncity)"
if [ -z "$vpncity" ] || echo "$vpncity" | grep -qoE '\b(error.*:.*True.*|Undefined)\b' ; then vpncity="Undetermined" ; fi
citychange="${CGreen}- NEW ${CClear}"
vpncity3="$vpncity"
fi
vpncity="$vpncity3"
oldvpnip3="$lastvpnip3"
elif [ "$1" = "4" ]
then
lastvpnip4="$icanhazvpnip"
if [ "$lastvpnip4" != "$oldvpnip4" ]
then
vpncity="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --request GET --url http://ip-api.com/json/$icanhazvpnip | jq --raw-output .city"
vpncity="$(eval $vpncity)"
if [ -z "$vpncity" ] || echo "$vpncity" | grep -qoE '\b(error.*:.*True.*|Undefined)\b' ; then vpncity="Undetermined" ; fi
citychange="${CGreen}- NEW ${CClear}"
vpncity4="$vpncity"
fi
vpncity="$vpncity4"
oldvpnip4="$lastvpnip4"
elif [ "$1" = "5" ]
then
lastvpnip5="$icanhazvpnip"
if [ "$lastvpnip5" != "$oldvpnip5" ]
then
vpncity="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --request GET --url http://ip-api.com/json/$icanhazvpnip | jq --raw-output .city"
vpncity="$(eval $vpncity)"
if [ -z "$vpncity" ] || echo "$vpncity" | grep -qoE '\b(error.*:.*True.*|Undefined)\b' ; then vpncity="Undetermined" ; fi
citychange="${CGreen}- NEW ${CClear}"
vpncity5="$vpncity"
fi
vpncity="$vpncity5"
oldvpnip5="$lastvpnip5"
fi
# Insert bogus City if screenshotmode is on
if [ "$screenshotmode" = "1" ]; then
vpncity="Gotham City"
fi
}
# -------------------------------------------------------------------------------------------------------------------------
##------------------------------------------------------------------------------------------------##
## Modified by ViktorJp [2025-Jul-06], Original getvpncity() modded bt Martinski W. [2024-Oct-18] ##
##------------------------------------------------------------------------------------------------##
# Find and remember the WG city so it doesn't have to make successive API lookups
getwgcity()
{
if [ "$icanhazwgip" = "0.0.0.0" ]; then
wgcity="Undetermined"
return
fi
# Added ping workaround for site2site scenarios based on suggestion from @ZebMcKayhan
TUN_IP=$($timeoutcmd$timeoutsec nvram get "$TUN"_addr | cut -d '/' -f1)
ip rule add from $TUN_IP lookup $TUN prio 10 >/dev/null 2>&1
if [ "$1" = "1" ]
then
lastwgip1="$icanhazwgip"
if [ "$lastwgip1" != "$oldwgip1" ]
then
wgcity="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --request GET --url http://ip-api.com/json/$icanhazwgip | jq --raw-output .city"
wgcity="$(eval $wgcity)"
if [ -z "$wgcity" ] || echo "$wgcity" | grep -qoE '\b(error.*:.*True.*|Undefined)\b' ; then wgcity="Undetermined" ; fi
wgcitychange="${CGreen}- NEW ${CClear}"
wgcity1="$wgcity"
fi
wgcity="$wgcity1"
oldwgip1="$lastwgip1"
elif [ "$1" = "2" ]
then
lastwgip2="$icanhazwgip"
if [ "$lastwgip2" != "$oldwgip2" ]
then
wgcity="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --request GET --url http://ip-api.com/json/$icanhazwgip | jq --raw-output .city"
wgcity="$(eval $wgcity)"
if [ -z "$wgcity" ] || echo "$wgcity" | grep -qoE '\b(error.*:.*True.*|Undefined)\b' ; then wgcity="Undetermined" ; fi
wgcitychange="${CGreen}- NEW ${CClear}"
wgcity2="$wgcity"
fi
wgcity="$wgcity2"
oldwgip2="$lastwgip2"
elif [ "$1" = "3" ]
then
lastwgip3="$icanhazwgip"
if [ "$lastwgip3" != "$oldwgip3" ]
then
wgcity="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --request GET --url http://ip-api.com/json/$icanhazwgip | jq --raw-output .city"
wgcity="$(eval $wgcity)"
if [ -z "$wgcity" ] || echo "$wgcity" | grep -qoE '\b(error.*:.*True.*|Undefined)\b' ; then wgcity="Undetermined" ; fi
wgcitychange="${CGreen}- NEW ${CClear}"
wgcity3="$wgcity"
fi
wgcity="$wgcity3"
oldwgip3="$lastwgip3"
elif [ "$1" = "4" ]
then
lastwgip4="$icanhazwgip"
if [ "$lastwgip4" != "$oldwgip4" ]
then
wgcity="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --request GET --url http://ip-api.com/json/$icanhazwgip | jq --raw-output .city"
wgcity="$(eval $wgcity)"
if [ -z "$wgcity" ] || echo "$wgcity" | grep -qoE '\b(error.*:.*True.*|Undefined)\b' ; then wgcity="Undetermined" ; fi
wgcitychange="${CGreen}- NEW ${CClear}"
wgcity4="$wgcity"
fi
wgcity="$wgcity4"
oldwgip4="$lastwgip4"
elif [ "$1" = "5" ]
then
lastwgip5="$icanhazwgip"
if [ "$lastwgip5" != "$oldwgip5" ]
then
wgcity="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --request GET --url http://ip-api.com/json/$icanhazwgip | jq --raw-output .city"
wgcity="$(eval $wgcity)"
if [ -z "$wgcity" ] || echo "$wgcity" | grep -qoE '\b(error.*:.*True.*|Undefined)\b' ; then wgcity="Undetermined" ; fi
wgcitychange="${CGreen}- NEW ${CClear}"
wgcity5="$wgcity"
fi
wgcity="$wgcity5"
oldwgip5="$lastwgip5"
fi
# Added based on suggestion from @ZebMcKayhan
ip rule del prio 10 >/dev/null 2>&1
# Insert bogus City if screenshotmode is on
if [ "$screenshotmode" = "1" ]; then
wgcity="Gotham City"
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# Check health of the vpn connection using PING and CURL
checkvpn()
{
CNT=0
TRIES=3
TUN="tun1$1"
while [ "$CNT" -lt "$TRIES" ]; do # Loop through number of tries
ping -I $TUN -q -c 1 -W 2 $PINGHOST > /dev/null 2>&1 # First try pings
RC=$?
# Grab the public IP of the VPN Connection #
ICANHAZIP="$(curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$TUN" --request GET --url https://ipv4.icanhazip.com)"
IC=$?
if [ "$RC" -eq 0 ] && [ "$IC" -eq 0 ]; then # If both ping/curl come back successful, then proceed
vpnping=$(ping -I $TUN -c 1 -W 2 $PINGHOST | awk -F'time=| ms' 'NF==3{print $(NF-1)}' | sort -rn) > /dev/null 2>&1
VP=$?
if [ "$VP" -eq 0 ]; then
vpnhealth="${CGreen}[ OK ]${CClear}"
vpnindicator="${InvGreen} ${CClear}"
if [ "$problemvpnslot" -eq "$1" ]; then
vrcnt=0
problemvpnslot=0
fi
else
vpnping=0
vpnhealth="${CYellow}[UNKN]${CClear}"
vpnindicator="${InvYellow} ${CClear}"
fi
printf "\33[2K\r"
break
else
CNT="$((CNT+1))"
printf "\33[2K\r"
printf "\r${InvDkGray} ${CWhite} VPN$1${CClear} [Attempt $CNT]"
sleep 1 # Giving the VPN a chance to recover a certain number of times
if [ "$CNT" -eq "$TRIES" ];then # But if it fails, report back that we have an issue requiring a VPN reset
printf "\33[2K\r"
vpnping=0
vpnhealth="${CRed}[FAIL]${CClear}"
vpnindicator="${InvRed} ${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: VPN$1 failed to respond" >> $logfile
vrcnt="$((vrcnt+1))"
problemvpnslot="$1"
if [ "$vrcnt" -ge 10 ]; then
monitored="${CRed}[!]${CClear}"
else
monitored="${CRed}[$vrcnt]${CClear}"
fi
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: VPN$1 attempt $vrcnt of $recover to allow connection to recover" >> $logfile
if [ "$vrcnt" -eq "$recover" ]; then
if [ "$((VPN$1))" = "1" ]; then
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: VPN$1 failed to respond after $recover attempt(s)" >> $logfile
resetvpn=$1
fi
fi
fi
fi
done
}
# -------------------------------------------------------------------------------------------------------------------------
# Check health of the WG connection using PING and CURL
checkwg()
{
CNT=0
TRIES=3
TUN="wgc$1"
# Added ping workaround for site2site scenarios based on suggestion from @ZebMcKayhan
TUN_IP=$($timeoutcmd$timeoutsec nvram get "$TUN"_addr | cut -d '/' -f1)
ip rule add from $TUN_IP lookup $TUN prio 10 >/dev/null 2>&1
while [ "$CNT" -lt "$TRIES" ]; do # Loop through number of tries
ping -I $TUN -q -c 1 -W 2 $PINGHOST > /dev/null 2>&1 # First try pings
RC=$?
# Grab the public IP of the VPN Connection #
ICANHAZIP="$(curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$TUN" --request GET --url https://ipv4.icanhazip.com)"
IC=$?
if [ "$RC" -eq 0 ] && [ "$IC" -eq 0 ]; then # If both ping/curl come back successful, then proceed
wgping=$(ping -I $TUN -c 1 -W 2 $PINGHOST | awk -F'time=| ms' 'NF==3{print $(NF-1)}' | sort -rn) > /dev/null 2>&1
VP=$?
if [ "$VP" -eq 0 ]; then
wghealth="${CGreen}[ OK ]${CClear}"
wgindicator="${InvGreen} ${CClear}"
if [ "$problemwgslot" -eq "$1" ]; then
wrcnt=0
problemwgslot=0
fi
else
wgping=0
wghealth="${CYellow}[UNKN]${CClear}"
wgindicator="${InvYellow} ${CClear}"
fi
printf "\33[2K\r"
break
else
CNT="$((CNT+1))"
printf "\33[2K\r"
printf "\r${InvDkGray} ${CWhite} WGC$1${CClear} [Attempt $CNT]"
sleep 1 # Giving the VPN a chance to recover a certain number of times
if [ "$CNT" -eq "$TRIES" ]; then # But if it fails, report back that we have an issue requiring a VPN reset
printf "\33[2K\r"
wgping=0
wghealth="${CRed}[FAIL]${CClear}"
wgindicator="${InvRed} ${CClear}"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: WGC$1 failed to respond" >> $logfile
wrcnt="$((wrcnt+1))"
problemwgslot="$1"
if [ "$wrcnt" -ge 10 ]; then
wgmonitored="${CRed}[!]${CClear}"
else
wgmonitored="${CRed}[$wrcnt]${CClear}"
fi
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: WGC$1 attempt $wrcnt of $recover to allow connection to recover" >> $logfile
if [ "$wrcnt" -eq "$recover" ]; then
if [ "$((WG$1))" = "1" ]; then
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: WGC$1 failed to respond after $recover attempt(s)" >> $logfile
resetwg=$1
fi
fi
fi
fi
done
# Added based on suggestion from @ZebMcKayhan
ip rule del prio 10 >/dev/null 2>&1
}
# -------------------------------------------------------------------------------------------------------------------------
# Checkwan is a function that checks the viability of the current WAN connection and will loop until the WAN connection is restored.
checkwan()
{
# Using Google's DNS server as default to test for WAN connectivity over verified SSL Handshake
wandownbreakertrip=0
testssl="$PING_HOST_Deflt"
printf "\33[2K\r"
printf "\r${InvYellow} ${CClear} [Checking WAN Connectivity]..."
#Run main checkwan loop
while true
do
# Check the actual WAN State from NVRAM before running connectivity test, or insert itself into loop after failing an SSL handshake test
if [ "$($timeoutcmd$timeoutsec nvram get wan0_state_t)" -eq 2 ] || [ "$($timeoutcmd$timeoutsec nvram get wan1_state_t)" -eq 2 ]
then
# Test the active WAN connection using 443 and verifying a handshake... if this fails, then the WAN connection is most likely down... or Google is down ;)
if ($timeoutcmd$timeoutlng nc -w3 $testssl 443 >/dev/null 2>&1 && echo | $timeoutcmd$timeoutlng openssl s_client -connect $testssl:443 >/dev/null 2>&1 | awk 'handshake && $1 == "Verification" { if ($2=="OK") exit; exit 1 } $1 $2 == "SSLhandshake" { handshake = 1 }' >/dev/null 2>&1)
##OFF##if ($timeoutcmd$timeoutlng nc -w1 $testssl 443 >/dev/null 2>&1 && echo | $timeoutcmd$timeoutlng openssl s_client -connect $testssl:443 >/dev/null 2>&1 | awk '$1 == "SSL" && $2 == "handshake" { handshake = 1 } handshake && $1 == "Verification:" { ok = $2; exit } END { exit ok != "OK" }' >/dev/null 2>&1)
then
printf "\r${InvGreen} ${CClear} [Checking WAN Connectivity]...ACTIVE"
sleep 1
printf "\33[2K\r"
return
else
wandownbreakertrip=1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: WAN Connectivity Issue Detected" >> $logfile
fi
else
wandownbreakertrip=1
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: WAN Connectivity Issue Detected" >> $logfile
fi
if [ "$wandownbreakertrip" = "1" ]
then
# The WAN is most likely down, and keep looping through until NVRAM reports that it's back up
while [ "$wandownbreakertrip" = "1" ]
do
if [ "$availableslots" = "1 2" ]
then
state1="$(_VPN_GetClientState_ 1)"
state2="$(_VPN_GetClientState_ 2)"
printf "\r${InvGreen} ${CClear} [Confirming VPN Clients Disconnected]... 1:$state1 2:$state2 "
sleep 3
elif [ "$availableslots" = "1 2 3 4 5" ]
then
state1="$(_VPN_GetClientState_ 1)"
state2="$(_VPN_GetClientState_ 2)"
state3="$(_VPN_GetClientState_ 3)"
state4="$(_VPN_GetClientState_ 4)"
state5="$(_VPN_GetClientState_ 5)"
printf "\r${InvGreen} ${CClear} [Confirming VPN Clients Disconnected]... 1:$state1 2:$state2 3:$state3 4:$state4 5:$state5 "
sleep 3
fi
# Preemptively kill all the VPN Clients incase they're trying to reconnect on their own
for slot in $availableslots
do
if [ $((state$slot)) -ne 0 ]; then
printf "\r${InvGreen} ${CClear} [Retrying Kill Command on VPN$slot Client Connection]... "
service stop_vpnclient$slot >/dev/null 2>&1
sleep 3
fi
done
# Check the wireguard side and bring those down as well
if [ "$availableslots" = "1 2 3 4 5" ]
then
wgstate1="$(_WG_GetClientState_ 1)"
wgstate2="$(_WG_GetClientState_ 2)"
wgstate3="$(_WG_GetClientState_ 3)"
wgstate4="$(_WG_GetClientState_ 4)"
wgstate5="$(_WG_GetClientState_ 5)"
printf "\r${InvGreen} ${CClear} [Confirming WG Clients Disconnected]... 1:$wgstate1 2:$wgstate2 3:$wgstate3 4:$wgstate4 5:$wgstate5 "
sleep 3
fi
# Preemptively kill all the WG Clients incase they're trying to reconnect on their own
for slot in $availableslots
do
if [ $((wgstate$slot)) -ne 0 ]; then
printf "\r${InvGreen} ${CClear} [Retrying Kill Command on WGC$slot Client Connection]... "
service "stop_wgc $slot" >/dev/null 2>&1
sleep 3
fi
done
# Continue to test for WAN connectivity while in this loop. If it comes back up, break out of the loop and reset VPN
if [ "$($timeoutcmd$timeoutsec nvram get wan0_state_t)" -ne 2 ] && [ "$($timeoutcmd$timeoutsec nvram get wan1_state_t)" -ne 2 ]
then
# Continue to loop and retest the WAN every 15 seconds
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: WAN DOWN" >> $logfile
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} Router is Currently Experiencing a WAN Down Situation ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Router is unable to provide a stable WAN connection. Please reboot your modem,${CClear}"
echo -e "${InvGreen} ${CClear} check with your ISP, or perform general internet connectivity troubleshooting${CClear}"
echo -e "${InvGreen} ${CClear} in order to re-establish a stable VPN connection.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} [Retrying to resume normal operations roughly every 60 seconds]${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo ""
spinner 60
wandownbreakertrip=1
else
wandownbreakertrip=2
break
fi
done
fi
# If the WAN was down, and now it has just reset, then run a VPN Reset, and try to establish a new VPN connection
if [ "$wandownbreakertrip" = "2" ]
then
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: WAN Link Detected -- Trying to Reconnect/Reset VPN/WG" >> $logfile
wandownbreakertrip=0
clear
echo -e "${InvGreen} ${InvDkGray}${CWhite} VPNMON-R3 is currently recovering from a WAN Down Situation ${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} Router has detected a WAN Link/Modem and waiting 300 seconds for general network${CClear}"
echo -e "${InvGreen} ${CClear} connectivity to stabilize before re-establishing VPN/WG connectivity.${CClear}"
echo -e "${InvGreen} ${CClear}"
echo -e "${InvGreen} ${CClear} [Retrying to resume normal operations in roughly 300 seconds...Please stand by!]${CClear}"
echo -e "${InvGreen} ${CClear}${CDkGray}---------------------------------------------------------------------------------------${CClear}"
echo ""
spinner 300
#sendmessage 1 "Recovering from WAN Down" - this doesn't work when the internet is down
exec sh /jffs/scripts/vpnmon-r3.sh -noswitch
fi
done
}
# -------------------------------------------------------------------------------------------------------------------------
##----------------------------------------##
## Modified by Martinski W. [2024-Oct-18] ##
##----------------------------------------##
# wancheck is a function that checks each wan connection to see if its active, and performs a ping and a city lookup...
wancheck()
{
WANIF="$1"
WANIFNAME="$(get_wan_setting ifname)"
DUALWANMODE="$($timeoutcmd$timeoutsec nvram get wans_mode)"
# Uptime calc #
uptimeStr="$(awk '{printf("%dd %02dh:%02dm\n",($1/60/60/24),($1/60/60%24),($1/60%60),($1%60))}' /proc/uptime)"
# If WAN 0 or 1 is connected, then proceed, else display that it's inactive
if [ "$WANIF" = "0" ]
then
if [ "$($timeoutcmd$timeoutsec nvram get wan0_state_t)" -eq 2 ]
then
# Call the get_wan_setting function courtesy of @dave14305 and using this interface name to ping and get a city name from
WAN0IFNAME="$(get_wan_setting0 ifname)"
# Ping through the WAN interface #
if [ "$WANIFNAME" = "$WAN0IFNAME" ] || [ "$DUALWANMODE" = "lb" ]
then
WAN0PING="$(ping -I "$WAN0IFNAME" -c 1 "$PINGHOST" 2>/dev/null | awk -F'[/=]' 'END{print $5}')"
## No need to do left-padding with zeros for alignment ##
[ -n "${WAN0PING:+xSETx}" ] && WAN0PING="$(printf "[%8.3f]" "$WAN0PING")"
else
WAN0PING="[FAILOVER]"
fi
# On the rare occasion where it's unable to get the Ping time, show ERROR #
if [ -z "$WAN0PING" ] ; then WAN0PING="${CRed}[PING ERR]${CClear}" ; fi
# Get the public IP of the WAN, determine the city from it, and display it on screen #
if [ -z "${WAN0IP:+xSETx}" ]
then
WAN0IP="$(curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WAN0IFNAME" --request GET --url https://ipv4.icanhazip.com)"
WAN0CITY="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --request GET --url http://ip-api.com/json/$WAN0IP | jq --raw-output .city"
WAN0CITY="$(eval $WAN0CITY)"
if [ -z "$WAN0CITY" ] || echo "$WAN0CITY" | grep -qoE '\b(error.*:.*True.*|Undefined)\b' ; then WAN0CITY="$WAN0IP" ; fi
WAN0IP="$(printf '%15s' "$WAN0IP")"
fi
# Insert bogus IP and City if screenshotmode is on
if [ "$screenshotmode" = "1" ]
then
WAN0CITY="Metropolis"
WAN0IP="$(printf '%15s' "11.22.33.44")"
fi
WAN0BWRX="$(printf '%4s' "$diffwan0rxbytes")"
if [ -z "$diffwan0rxbytes" ] || [ "$diffwan0rxbytes" = "" ] || [ "$diffwan0rxbytes" -lt 0 ]
then
WAN0RX1="${CRed}[UNKN]${CClear}"
elif [ "$diffwan0rxbytes" -ge 0 ] && [ "$diffwan0rxbytes" -le "$lowutilspd" ]
then
WAN0RX1="${CGreen}[$WAN0BWRX]${CClear}"
elif [ "$diffwan0rxbytes" -gt "$lowutilspd" ] && [ "$diffwan0rxbytes" -le "$medutilspd" ]
then
WAN0RX1="${CYellow}[$WAN0BWRX]${CClear}"
elif [ "$diffwan0rxbytes" -gt "$medutilspd" ]
then
WAN0RX1="${CRed}[$WAN0BWRX]${CClear}"
fi
WAN0BWTX="$(printf '%4s' "$diffwan0txbytes")"
if [ -z "$diffwan0txbytes" ] || [ "$diffwan0txbytes" = "" ] || [ "$diffwan0txbytes" -lt 0 ]
then
WAN0TX1="${CRed}[UNKN]${CClear}"
elif [ "$diffwan0txbytes" -ge 0 ] && [ "$diffwan0txbytes" -le "$lowutilspdup" ]
then
WAN0TX1="${CGreen}[$WAN0BWTX]${CClear}"
elif [ "$diffwan0txbytes" -gt "$lowutilspdup" ] && [ "$diffwan0txbytes" -le "$medutilspdup" ]
then
WAN0TX1="${CYellow}[$WAN0BWTX]${CClear}"
elif [ "$diffwan0txbytes" -gt "$medutilspdup" ]
then
WAN0TX1="${CRed}[$WAN0BWTX]${CClear}"
fi
WAN0TPRX="$(printf '%4s' "$thruwan0rxbytes")"
if [ -z "$thruwan0rxbytes" ] || [ "$thruwan0rxbytes" = "" ] || [ "$thruwan0rxbytes" -lt 0 ]
then
WAN0RX2="${CRed}[UNKN]${CClear}"
elif [ "$thruwan0rxbytes" -ge 0 ] && [ "$thruwan0rxbytes" -le "$lowutilspd" ]
then
WAN0RX2="${CGreen}[$WAN0TPRX]${CClear}"
elif [ "$thruwan0rxbytes" -gt "$lowutilspd" ] && [ "$thruwan0rxbytes" -le "$medutilspd" ]
then
WAN0RX2="${CYellow}[$WAN0TPRX]${CClear}"
elif [ "$thruwan0rxbytes" -gt "$medutilspd" ]
then
WAN0RX2="${CRed}[$WAN0TPRX]${CClear}"
fi
WAN0TPTX="$(printf '%4s' "$thruwan0txbytes")"
if [ -z "$thruwan0txbytes" ] || [ "$thruwan0txbytes" = "" ] || [ "$thruwan0txbytes" -lt 0 ]
then
WAN0TX2="${CRed}[UNKN]${CClear}"
elif [ "$thruwan0txbytes" -ge 0 ] && [ "$thruwan0txbytes" -le "$lowutilspdup" ]
then
WAN0TX2="${CGreen}[$WAN0TPTX]${CClear}"
elif [ "$thruwan0txbytes" -gt "$lowutilspdup" ] && [ "$thruwan0txbytes" -le "$medutilspdup" ]
then
WAN0TX2="${CYellow}[$WAN0TPTX]${CClear}"
elif [ "$thruwan0txbytes" -gt "$medutilspdup" ]
then
WAN0TX2="${CRed}[$WAN0TPTX]${CClear}"
fi
if [ "$WAN0PING" = "[FAILOVER]" ]
then
echo -en "${InvGreen} ${InvDkGray}${CWhite} WAN0${CClear} | ${CGreen}[X]${CClear} | "
printf "%-6s" "$WAN0IFNAME"
if [ "$bwdisp" = "1" ]; then
echo -e " | ${CGreen}[ OK ]${CClear} | Failover | $WAN0IP | $WAN0PING | $WAN0RX1 | $WAN0TX1 | $WAN0CITY: $uptimeStr"
else
echo -e " | ${CGreen}[ OK ]${CClear} | Failover | $WAN0IP | $WAN0PING | $WAN0RX2 | $WAN0TX2 | $WAN0CITY: $uptimeStr"
fi
else
echo -en "${InvGreen} ${InvDkGray}${CWhite} WAN0${CClear} | ${CGreen}[X]${CClear} | "
printf "%-6s" "$WAN0IFNAME"
if [ "$bwdisp" = "1" ]; then
echo -e " | ${CGreen}[ OK ]${CClear} | Active | $WAN0IP | $WAN0PING | $WAN0RX1 | $WAN0TX1 | $WAN0CITY: $uptimeStr"
else
echo -e " | ${CGreen}[ OK ]${CClear} | Active | $WAN0IP | $WAN0PING | $WAN0RX2 | $WAN0TX2 | $WAN0CITY: $uptimeStr"
fi
fi
else
echo -e "${InvDkGray}${CWhite} WAN0${CClear} | ${CGreen}[X]${CClear} | ${CDkGray}[n/a]${CClear} | ${CDkGray}[n/a ]${CClear} | Inactive | ${CDkGray}[n/a]${CClear} | ${CDkGray}[n/a]${CClear} | ${CDkGray}[n/a ]${CClear} | ${CDkGray}[n/a ]${CClear} | ${CDkGray}[n/a]${CClear}"
fi
fi
if [ "$WANIF" = "1" ]
then
if [ "$($timeoutcmd$timeoutsec nvram get wan1_state_t)" -eq 2 ]
then
# Call the get_wan_setting function courtesy of @dave14305 and using this interface name to ping and get a city name from
WAN1IFNAME="$(get_wan_setting1 ifname)"
# Ping through the WAN interface #
if [ "$WANIFNAME" = "$WAN1IFNAME" ] || [ "$DUALWANMODE" = "lb" ]
then
WAN1PING="$(ping -I "$WAN1IFNAME" -c 1 "$PINGHOST" 2>/dev/null | awk -F'[/=]' 'END{print $5}')"
## No need to do left-padding with zeros for alignment ##
[ -n "${WAN1PING:+xSETx}" ] && WAN1PING="$(printf "[%8.3f]" "$WAN1PING")"
else
WAN1PING="[FAILOVER]"
fi
# On the rare occasion where it's unable to get the Ping time, show ERROR #
if [ -z "$WAN1PING" ] ; then WAN1PING="${CRed}[PING ERR]${CClear}" ; fi
# Get the public IP of the WAN, determine the city from it, and display it on screen #
if [ -z "${WAN1IP:+xSETx}" ]
then
WAN1IP="$(curl --silent --retry 3 --retry-delay 2 --retry-all-errors --fail --interface "$WAN1IFNAME" --request GET --url https://ipv4.icanhazip.com)"
WAN1CITY="curl --silent --retry 3 --retry-delay 2 --retry-all-errors --request GET --url http://ip-api.com/json/$WAN1IP | jq --raw-output .city"
WAN1CITY="$(eval $WAN1CITY)"
if [ -z "$WAN1CITY" ] || echo "$WAN1CITY" | grep -qoE '\b(error.*:.*True.*|Undefined)\b' ; then WAN1CITY="$WAN1IP" ; fi
WAN1IP="$(printf '%15s' "$WAN1IP")"
fi
WAN1BWRX="$(printf '%4s' "$diffwan1rxbytes")"
if [ -z "$diffwan1rxbytes" ] || [ "$diffwan1rxbytes" = "" ] || [ "$diffwan1rxbytes" -lt 0 ]
then
WAN1RX1="${CRed}[UNKN]${CClear}"
elif [ "$diffwan1rxbytes" -ge 0 ] && [ "$diffwan1rxbytes" -le "$lowutilspd" ]
then
WAN1RX1="${CGreen}[$WAN1BWRX]${CClear}"
elif [ "$diffwan1rxbytes" -gt "$lowutilspd" ] && [ "$diffwan1rxbytes" -le "$medutilspd" ]
then
WAN1RX1="${CYellow}[$WAN1BWRX]${CClear}"
elif [ "$diffwan1rxbytes" -gt "$medutilspd" ]
then
WAN1RX1="${CRed}[$WAN1BWRX]${CClear}"
fi
WAN1BWTX="$(printf '%4s' "$diffwan1txbytes")"
if [ -z "$diffwan1txbytes" ] || [ "$diffwan1txbytes" = "" ] || [ "$diffwan1txbytes" -lt 0 ]
then
WAN1TX1="${CRed}[UNKN]${CClear}"
elif [ "$diffwan1txbytes" -ge 0 ] && [ "$diffwan1txbytes" -le "$lowutilspdup" ]
then
WAN1TX1="${CGreen}[$WAN1BWTX]${CClear}"
elif [ "$diffwan1txbytes" -gt "$lowutilspdup" ] && [ "$diffwan1txbytes" -le "$medutilspdup" ]
then
WAN1TX1="${CYellow}[$WAN1BWTX]${CClear}"
elif [ "$diffwan1txbytes" -gt "$medutilspdup" ]
then
WAN1TX1="${CRed}[$WAN1BWTX]${CClear}"
fi
WAN1TPRX="$(printf '%4s' "$thruwan1rxbytes")"
if [ -z "$thruwan1rxbytes" ] || [ "$thruwan1rxbytes" = "" ] || [ "$thruwan1rxbytes" -lt 0 ]
then
WAN1RX2="${CRed}[UNKN]${CClear}"
elif [ "$thruwan1rxbytes" -ge 0 ] && [ "$thruwan1rxbytes" -le "$lowutilspd" ]
then
WAN1RX2="${CGreen}[$WAN1TPRX]${CClear}"
elif [ "$thruwan1rxbytes" -gt "$lowutilspd" ] && [ "$thruwan1rxbytes" -le "$medutilspd" ]
then
WAN1RX2="${CYellow}[$WAN1TPRX]${CClear}"
elif [ "$thruwan1rxbytes" -gt "$medutilspd" ]
then
WAN1RX2="${CRed}[$WAN1TPRX]${CClear}"
fi
WAN1TPTX="$(printf '%4s' "$thruwan1txbytes")"
if [ -z "$thruwan1txbytes" ] || [ "$thruwan1txbytes" = "" ] || [ "$thruwan1txbytes" -lt 0 ]
then
WAN1TX2="${CRed}[UNKN]${CClear}"
elif [ "$thruwan1txbytes" -ge 0 ] && [ "$thruwan1txbytes" -le "$lowutilspdup" ]
then
WAN1TX2="${CGreen}[$WAN1TPTX]${CClear}"
elif [ "$thruwan1txbytes" -gt "$lowutilspdup" ] && [ "$thruwan1txbytes" -le "$medutilspdup" ]
then
WAN1TX2="${CYellow}[$WAN1TPTX]${CClear}"
elif [ "$thruwan1txbytes" -gt "$medutilspdup" ]
then
WAN1TX2="${CRed}[$WAN1TPTX]${CClear}"
fi
if [ "$WAN1PING" = "[FAILOVER]" ]
then
echo -en "${InvGreen} ${InvDkGray}${CWhite} WAN1${CClear} | ${CGreen}[X]${CClear} | "
printf "%-6s" "$WAN1IFNAME"
if [ "$bwdisp" = "1" ]; then
echo -e " | ${CGreen}[ OK ]${CClear} | Failover | $WAN1IP | $WAN1PING | $WAN1RX1 | $WAN1TX1 | $WAN1CITY: $uptimeStr"
else
echo -e " | ${CGreen}[ OK ]${CClear} | Failover | $WAN1IP | $WAN1PING | $WAN1RX2 | $WAN1TX2 | $WAN1CITY: $uptimeStr"
fi
else
echo -en "${InvGreen} ${InvDkGray}${CWhite} WAN1${CClear} | ${CGreen}[X]${CClear} | "
printf "%-6s" "$WAN1IFNAME"
if [ "$bwdisp" = "1" ]; then
echo -e " | ${CGreen}[ OK ]${CClear} | Active | $WAN1IP | $WAN1PING | $WAN1RX1 | $WAN1TX1 | $WAN1CITY: $uptimeStr"
else
echo -e " | ${CGreen}[ OK ]${CClear} | Active | $WAN1IP | $WAN1PING | $WAN1RX2 | $WAN1TX2 | $WAN1CITY: $uptimeStr"
fi
fi
else
echo -e "${InvDkGray}${CWhite} WAN1${CClear} | ${CGreen}[X]${CClear} | ${CDkGray}[n/a]${CClear} | ${CDkGray}[n/a ]${CClear} | Inactive | ${CDkGray}[n/a]${CClear} | ${CDkGray}[n/a]${CClear} | ${CDkGray}[n/a ]${CClear} | ${CDkGray}[n/a ]${CClear} | ${CDkGray}[n/a]${CClear}"
fi
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# This function was "borrowed" graciously from @dave14305 from his FlexQoS script to determine the active WAN connection.
# Thanks much for your troubleshooting help as we tackled how to best derive the active WAN interface, Dave!
get_wan_setting()
{
local varname varval
varname="${1}"
prefixes="wan0_ wan1_"
if [ "$($timeoutcmd$timeoutsec nvram get wans_mode)" = "lb" ] ; then
for prefix in $prefixes; do
state="$($timeoutcmd$timeoutsec nvram get "${prefix}"state_t)"
sbstate="$($timeoutcmd$timeoutsec nvram get "${prefix}"sbstate_t)"
auxstate="$($timeoutcmd$timeoutsec nvram get "${prefix}"auxstate_t)"
# is_wan_connect()
[ "${state}" = "2" ] || continue
[ "${sbstate}" = "0" ] || continue
[ "${auxstate}" = "0" ] || [ "${auxstate}" = "2" ] || continue
# get_wan_ifname()
proto="$($timeoutcmd$timeoutsec nvram get "${prefix}"proto)"
if [ "${proto}" = "pppoe" ] || [ "${proto}" = "pptp" ] || [ "${proto}" = "l2tp" ] ; then
varval="$($timeoutcmd$timeoutsec nvram get "${prefix}"pppoe_"${varname}")"
else
varval="$($timeoutcmd$timeoutsec nvram get "${prefix}""${varname}")"
fi
done
else
for prefix in $prefixes; do
primary="$($timeoutcmd$timeoutsec nvram get "${prefix}"primary)"
[ "${primary}" = "1" ] && break
done
proto="$($timeoutcmd$timeoutsec nvram get "${prefix}"proto)"
if [ "${proto}" = "pppoe" ] || [ "${proto}" = "pptp" ] || [ "${proto}" = "l2tp" ] ; then
varval="$($timeoutcmd$timeoutsec nvram get "${prefix}"pppoe_"${varname}")"
else
varval="$($timeoutcmd$timeoutsec nvram get "${prefix}""${varname}")"
fi
fi
printf "%s" "${varval}"
}
# Separated these out to get the ifname for a dual-wan/failover situation where both WAN connections are on
get_wan_setting0()
{
local varname varval
varname="${1}"
prefixes="wan0_"
if [ "$($timeoutcmd$timeoutsec nvram get wans_mode)" = "lb" ] ; then
for prefix in $prefixes; do
state="$($timeoutcmd$timeoutsec nvram get "${prefix}"state_t)"
sbstate="$($timeoutcmd$timeoutsec nvram get "${prefix}"sbstate_t)"
auxstate="$($timeoutcmd$timeoutsec nvram get "${prefix}"auxstate_t)"
# is_wan_connect()
[ "${state}" = "2" ] || continue
[ "${sbstate}" = "0" ] || continue
[ "${auxstate}" = "0" ] || [ "${auxstate}" = "2" ] || continue
# get_wan_ifname()
proto="$($timeoutcmd$timeoutsec nvram get "${prefix}"proto)"
if [ "${proto}" = "pppoe" ] || [ "${proto}" = "pptp" ] || [ "${proto}" = "l2tp" ] ; then
varval="$($timeoutcmd$timeoutsec nvram get "${prefix}"pppoe_"${varname}")"
else
varval="$($timeoutcmd$timeoutsec nvram get "${prefix}""${varname}")"
fi
done
else
for prefix in $prefixes; do
primary="$($timeoutcmd$timeoutsec nvram get "${prefix}"primary)"
[ "${primary}" = "1" ] && break
done
proto="$($timeoutcmd$timeoutsec nvram get "${prefix}"proto)"
if [ "${proto}" = "pppoe" ] || [ "${proto}" = "pptp" ] || [ "${proto}" = "l2tp" ] ; then
varval="$($timeoutcmd$timeoutsec nvram get "${prefix}"pppoe_"${varname}")"
else
varval="$($timeoutcmd$timeoutsec nvram get "${prefix}""${varname}")"
fi
fi
printf "%s" "${varval}"
}
# Separated these out to get the ifname for a dual-wan/failover situation where both WAN connections are on
get_wan_setting1()
{
local varname varval
varname="${1}"
prefixes="wan1_"
if [ "$($timeoutcmd$timeoutsec nvram get wans_mode)" = "lb" ] ; then
for prefix in $prefixes; do
state="$($timeoutcmd$timeoutsec nvram get "${prefix}"state_t)"
sbstate="$($timeoutcmd$timeoutsec nvram get "${prefix}"sbstate_t)"
auxstate="$($timeoutcmd$timeoutsec nvram get "${prefix}"auxstate_t)"
# is_wan_connect()
[ "${state}" = "2" ] || continue
[ "${sbstate}" = "0" ] || continue
[ "${auxstate}" = "0" ] || [ "${auxstate}" = "2" ] || continue
# get_wan_ifname()
proto="$($timeoutcmd$timeoutsec nvram get "${prefix}"proto)"
if [ "${proto}" = "pppoe" ] || [ "${proto}" = "pptp" ] || [ "${proto}" = "l2tp" ] ; then
varval="$($timeoutcmd$timeoutsec nvram get "${prefix}"pppoe_"${varname}")"
else
varval="$($timeoutcmd$timeoutsec nvram get "${prefix}""${varname}")"
fi
done
else
for prefix in $prefixes; do
primary="$($timeoutcmd$timeoutsec nvram get "${prefix}"primary)"
[ "${primary}" = "1" ] && break
done
proto="$($timeoutcmd$timeoutsec nvram get "${prefix}"proto)"
if [ "${proto}" = "pppoe" ] || [ "${proto}" = "pptp" ] || [ "${proto}" = "l2tp" ] ; then
varval="$($timeoutcmd$timeoutsec nvram get "${prefix}"pppoe_"${varname}")"
else
varval="$($timeoutcmd$timeoutsec nvram get "${prefix}""${varname}")"
fi
fi
printf "%s" "${varval}"
}
# -------------------------------------------------------------------------------------------------------------------------
# These functions grab the difference between WAN, OVPN and WG connection stats and calculate Mbps
getifacestats()
{
if [ ! -z "$WAN0IFNAME" ]
then
oldwan0rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$WAN0IFNAME/statistics/rx_bytes)"
oldwan0txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$WAN0IFNAME/statistics/tx_bytes)"
fi
if [ ! -z "$WAN1IFNAME" ]
then
oldwan1rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$WAN1IFNAME/statistics/rx_bytes)"
oldwan1txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$WAN1IFNAME/statistics/tx_bytes)"
fi
if [ "$availableslots" = "1 2" ]
then
state1="$(_VPN_GetClientState_ 1)"
state2="$(_VPN_GetClientState_ 2)"
state3=0
state4=0
state5=0
wgstate1=0
wgstate2=0
wgstate3=0
wgstate4=0
wgstate5=0
elif [ "$availableslots" = "1 2 3 4 5" ]
then
state1="$(_VPN_GetClientState_ 1)"
state2="$(_VPN_GetClientState_ 2)"
state3="$(_VPN_GetClientState_ 3)"
state4="$(_VPN_GetClientState_ 4)"
state5="$(_VPN_GetClientState_ 5)"
wgstate1="$(_WG_GetClientState_ 1)"
wgstate2="$(_WG_GetClientState_ 2)"
wgstate3="$(_WG_GetClientState_ 3)"
wgstate4="$(_WG_GetClientState_ 4)"
wgstate5="$(_WG_GetClientState_ 5)"
fi
if [ "$state1" -eq 2 ]; then
oldvpn1txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client1/status 2>/dev/null)
oldvpn1rxbytes="$(echo $oldvpn1txrxbytes | cut -d' ' -f1)"
oldvpn1txbytes="$(echo $oldvpn1txrxbytes | cut -d' ' -f2)"
if [ -z $oldvpn1rxbytes ]; then oldvpn1rxbytes=0; fi
if [ -z $oldvpn1txbytes ]; then oldvpn1txbytes=0; fi
fi
if [ "$state2" -eq 2 ]; then
oldvpn2txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client2/status 2>/dev/null)
oldvpn2rxbytes="$(echo $oldvpn2txrxbytes | cut -d' ' -f1)"
oldvpn2txbytes="$(echo $oldvpn2txrxbytes | cut -d' ' -f2)"
if [ -z $oldvpn2rxbytes ]; then oldvpn2rxbytes=0; fi
if [ -z $oldvpn2txbytes ]; then oldvpn2txbytes=0; fi
fi
if [ "$state3" -eq 2 ]; then
oldvpn3txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client3/status 2>/dev/null)
oldvpn3rxbytes="$(echo $oldvpn3txrxbytes | cut -d' ' -f1)"
oldvpn3txbytes="$(echo $oldvpn3txrxbytes | cut -d' ' -f2)"
if [ -z $oldvpn3rxbytes ]; then oldvpn3rxbytes=0; fi
if [ -z $oldvpn3txbytes ]; then oldvpn3txbytes=0; fi
fi
if [ "$state4" -eq 2 ]; then
oldvpn4txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client4/status 2>/dev/null)
oldvpn4rxbytes="$(echo $oldvpn4txrxbytes | cut -d' ' -f1)"
oldvpn4txbytes="$(echo $oldvpn4txrxbytes | cut -d' ' -f2)"
if [ -z $oldvpn4rxbytes ]; then oldvpn4rxbytes=0; fi
if [ -z $oldvpn4txbytes ]; then oldvpn4txbytes=0; fi
fi
if [ "$state5" -eq 2 ]; then
oldvpn5txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client5/status 2>/dev/null)
oldvpn5rxbytes="$(echo $oldvpn5txrxbytes | cut -d' ' -f1)"
oldvpn5txbytes="$(echo $oldvpn5txrxbytes | cut -d' ' -f2)"
if [ -z $oldvpn5rxbytes ]; then oldvpn5rxbytes=0; fi
if [ -z $oldvpn5txbytes ]; then oldvpn5txbytes=0; fi
fi
if [ "$wgstate1" -eq 2 ]; then
oldwg1txrxbytes=$(wg show wgc1 transfer)
oldwg1rxbytes="$(echo $oldwg1txrxbytes | cut -d' ' -f2)"
oldwg1txbytes="$(echo $oldwg1txrxbytes | cut -d' ' -f3)"
if [ -z $oldwg1rxbytes ] || [ $oldwg1rxbytes -le 0 ]; then oldwg1rxbytes=0; fi
if [ -z $oldwg1txbytes ] || [ $oldwg1txbytes -le 0 ]; then oldwg1txbytes=0; fi
fi
if [ "$wgstate2" -eq 2 ]; then
oldwg2txrxbytes=$(wg show wgc2 transfer)
oldwg2rxbytes="$(echo $oldwg2txrxbytes | cut -d' ' -f2)"
oldwg2txbytes="$(echo $oldwg2txrxbytes | cut -d' ' -f3)"
if [ -z $oldwg2rxbytes ] || [ $oldwg2rxbytes -le 0 ]; then oldwg2rxbytes=0; fi
if [ -z $oldwg2txbytes ] || [ $oldwg2txbytes -le 0 ]; then oldwg2txbytes=0; fi
fi
if [ "$wgstate3" -eq 2 ]; then
oldwg3txrxbytes=$(wg show wgc3 transfer)
oldwg3rxbytes="$(echo $oldwg3txrxbytes | cut -d' ' -f2)"
oldwg3txbytes="$(echo $oldwg3txrxbytes | cut -d' ' -f3)"
if [ -z $oldwg3rxbytes ] || [ $oldwg3rxbytes -le 0 ]; then oldwg3rxbytes=0; fi
if [ -z $oldwg3txbytes ] || [ $oldwg3txbytes -le 0 ]; then oldwg3txbytes=0; fi
fi
if [ "$wgstate4" -eq 2 ]; then
oldwg4txrxbytes=$(wg show wgc4 transfer)
oldwg4rxbytes="$(echo $oldwg4txrxbytes | cut -d' ' -f2)"
oldwg4txbytes="$(echo $oldwg4txrxbytes | cut -d' ' -f3)"
if [ -z $oldwg4rxbytes ] || [ $oldwg4rxbytes -le 0 ]; then oldwg4rxbytes=0; fi
if [ -z $oldwg4txbytes ] || [ $oldwg4txbytes -le 0 ]; then oldwg4txbytes=0; fi
fi
if [ "$wgstate5" -eq 2 ]; then
oldwg5txrxbytes=$(wg show wgc5 transfer)
oldwg5rxbytes="$(echo $oldwg5txrxbytes | cut -d' ' -f2)"
oldwg5txbytes="$(echo $oldwg5txrxbytes | cut -d' ' -f3)"
if [ -z $oldwg5rxbytes ] || [ $oldwg5rxbytes -le 0 ]; then oldwg5rxbytes=0; fi
if [ -z $oldwg5txbytes ] || [ $oldwg5txbytes -le 0 ]; then oldwg5txbytes=0; fi
fi
}
calcifacestats()
{
if [ "$resetifacestatsswitch" -eq 1 ]
then
resetifacestatsswitch=0
return
fi
if [ ! -z "$WAN0IFNAME" ]
then
newwan0rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$WAN0IFNAME/statistics/rx_bytes)"
newwan0txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$WAN0IFNAME/statistics/tx_bytes)"
diffwan0rxbytes=$(awk -v new=$newwan0rxbytes -v old=$oldwan0rxbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
diffwan0txbytes=$(awk -v new=$newwan0txbytes -v old=$oldwan0txbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
thruwan0rxbytes=$(awk -v new=$newwan0rxbytes -v old=$oldwan0rxbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
thruwan0txbytes=$(awk -v new=$newwan0txbytes -v old=$oldwan0txbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
fi
if [ ! -z "$WAN1IFNAME" ]
then
newwan1rxbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$WAN1IFNAME/statistics/rx_bytes)"
newwan1txbytes="$($timeoutcmd$timeoutsec cat /sys/class/net/$WAN1IFNAME/statistics/tx_bytes)"
diffwan1rxbytes=$(awk -v new=$newwan1rxbytes -v old=$oldwan1rxbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
diffwan1txbytes=$(awk -v new=$newwan1txbytes -v old=$oldwan1txbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
thruwan1rxbytes=$(awk -v new=$newwan1rxbytes -v old=$oldwan1rxbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
thruwan1txbytes=$(awk -v new=$newwan1txbytes -v old=$oldwan1txbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
fi
if [ "$availableslots" = "1 2" ]
then
state1="$(_VPN_GetClientState_ 1)"
state2="$(_VPN_GetClientState_ 2)"
elif [ "$availableslots" = "1 2 3 4 5" ]
then
state1="$(_VPN_GetClientState_ 1)"
state2="$(_VPN_GetClientState_ 2)"
state3="$(_VPN_GetClientState_ 3)"
state4="$(_VPN_GetClientState_ 4)"
state5="$(_VPN_GetClientState_ 5)"
wgstate1="$(_WG_GetClientState_ 1)"
wgstate2="$(_WG_GetClientState_ 2)"
wgstate3="$(_WG_GetClientState_ 3)"
wgstate4="$(_WG_GetClientState_ 4)"
wgstate5="$(_WG_GetClientState_ 5)"
fi
if [ "$state1" -eq 2 ]; then
newvpn1txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client1/status 2>/dev/null)
newvpn1rxbytes="$(echo $newvpn1txrxbytes | cut -d' ' -f1)"
newvpn1txbytes="$(echo $newvpn1txrxbytes | cut -d' ' -f2)"
if [ -z $newvpn1rxbytes ]; then newvpn1rxbytes=0; fi
if [ -z $newvpn1txbytes ]; then newvpn1txbytes=0; fi
diffvpn1rxbytes=$(awk -v new=$newvpn1rxbytes -v old=$oldvpn1rxbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
diffvpn1txbytes=$(awk -v new=$newvpn1txbytes -v old=$oldvpn1txbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
thruvpn1rxbytes=$(awk -v new=$newvpn1rxbytes -v old=$oldvpn1rxbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
thruvpn1txbytes=$(awk -v new=$newvpn1txbytes -v old=$oldvpn1txbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
else
diffvpn1rxbytes=""
diffvpn1txbytes=""
thruvpn1rxbytes=""
thruvpn1txbytes=""
fi
if [ "$state2" -eq 2 ]; then
newvpn2txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client2/status 2>/dev/null)
newvpn2rxbytes="$(echo $newvpn2txrxbytes | cut -d' ' -f1)"
newvpn2txbytes="$(echo $newvpn2txrxbytes | cut -d' ' -f2)"
if [ -z $newvpn2rxbytes ]; then newvpn2rxbytes=0; fi
if [ -z $newvpn2txbytes ]; then newvpn2txbytes=0; fi
diffvpn2rxbytes=$(awk -v new=$newvpn2rxbytes -v old=$oldvpn2rxbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
diffvpn2txbytes=$(awk -v new=$newvpn2txbytes -v old=$oldvpn2txbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
thruvpn2rxbytes=$(awk -v new=$newvpn2rxbytes -v old=$oldvpn2rxbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
thruvpn2txbytes=$(awk -v new=$newvpn2txbytes -v old=$oldvpn2txbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
else
diffvpn2rxbytes=""
diffvpn2txbytes=""
thruvpn2rxbytes=""
thruvpn2txbytes=""
fi
if [ "$state3" -eq 2 ]; then
newvpn3txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client3/status 2>/dev/null)
newvpn3rxbytes="$(echo $newvpn3txrxbytes | cut -d' ' -f1)"
newvpn3txbytes="$(echo $newvpn3txrxbytes | cut -d' ' -f2)"
if [ -z $newvpn3rxbytes ]; then newvpn3rxbytes=0; fi
if [ -z $newvpn3txbytes ]; then newvpn3txbytes=0; fi
diffvpn3rxbytes=$(awk -v new=$newvpn3rxbytes -v old=$oldvpn3rxbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
diffvpn3txbytes=$(awk -v new=$newvpn3txbytes -v old=$oldvpn3txbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
thruvpn3rxbytes=$(awk -v new=$newvpn3rxbytes -v old=$oldvpn3rxbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
thruvpn3txbytes=$(awk -v new=$newvpn3txbytes -v old=$oldvpn3txbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
else
diffvpn3rxbytes=""
diffvpn3txbytes=""
thruvpn3rxbytes=""
thruvpn3txbytes=""
fi
if [ "$state4" -eq 2 ]; then
newvpn4txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client4/status 2>/dev/null)
newvpn4rxbytes="$(echo $newvpn4txrxbytes | cut -d' ' -f1)"
newvpn4txbytes="$(echo $newvpn4txrxbytes | cut -d' ' -f2)"
if [ -z $newvpn4rxbytes ]; then newvpn4rxbytes=0; fi
if [ -z $newvpn4txbytes ]; then newvpn4txbytes=0; fi
diffvpn4rxbytes=$(awk -v new=$newvpn4rxbytes -v old=$oldvpn4rxbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
diffvpn4txbytes=$(awk -v new=$newvpn4txbytes -v old=$oldvpn4txbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
thruvpn4rxbytes=$(awk -v new=$newvpn4rxbytes -v old=$oldvpn4rxbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
thruvpn4txbytes=$(awk -v new=$newvpn4txbytes -v old=$oldvpn4txbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
else
diffvpn4rxbytes=""
diffvpn4txbytes=""
thruvpn4rxbytes=""
thruvpn4txbytes=""
fi
if [ "$state5" -eq 2 ]; then
newvpn5txrxbytes=$(awk -F',' '1 == /TUN\/TAP read bytes/ {print $2} 1 == /TUN\/TAP write bytes/ {print $2}' /tmp/etc/openvpn/client5/status 2>/dev/null)
newvpn5rxbytes="$(echo $newvpn5txrxbytes | cut -d' ' -f1)"
newvpn5txbytes="$(echo $newvpn5txrxbytes | cut -d' ' -f2)"
if [ -z $newvpn5rxbytes ]; then newvpn5rxbytes=0; fi
if [ -z $newvpn5txbytes ]; then newvpn5txbytes=0; fi
diffvpn5rxbytes=$(awk -v new=$newvpn5rxbytes -v old=$oldvpn5rxbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
diffvpn5txbytes=$(awk -v new=$newvpn5txbytes -v old=$oldvpn5txbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
thruvpn5rxbytes=$(awk -v new=$newvpn5rxbytes -v old=$oldvpn5rxbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
thruvpn5txbytes=$(awk -v new=$newvpn5txbytes -v old=$oldvpn5txbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
else
diffvpn5rxbytes=""
diffvpn5txbytes=""
thruvpn5rxbytes=""
thruvpn5txbytes=""
fi
if [ "$wgstate1" -eq 2 ]; then
newwg1txrxbytes=$(wg show wgc1 transfer)
newwg1rxbytes="$(echo $newwg1txrxbytes | cut -d' ' -f2)"
newwg1txbytes="$(echo $newwg1txrxbytes | cut -d' ' -f3)"
if [ -z $newwg1rxbytes ] || [ $newwg1rxbytes -le 0 ]; then newwg1rxbytes=0; fi
if [ -z $newwg1txbytes ] || [ $newwg1txbytes -le 0 ]; then newwg1txbytes=0; fi
diffwg1rxbytes=$(awk -v new=$newwg1rxbytes -v old=$oldwg1rxbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
diffwg1txbytes=$(awk -v new=$newwg1txbytes -v old=$oldwg1txbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
thruwg1rxbytes=$(awk -v new=$newwg1rxbytes -v old=$oldwg1rxbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
thruwg1txbytes=$(awk -v new=$newwg1txbytes -v old=$oldwg1txbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
else
diffwg1rxbytes=""
diffwg1txbytes=""
thruwg1rxbytes=""
thruwg1txbytes=""
fi
if [ "$wgstate2" -eq 2 ]; then
newwg2txrxbytes=$(wg show wgc2 transfer)
newwg2rxbytes="$(echo $newwg2txrxbytes | cut -d' ' -f2)"
newwg2txbytes="$(echo $newwg2txrxbytes | cut -d' ' -f3)"
if [ -z $newwg2rxbytes ] || [ $newwg2rxbytes -le 0 ]; then newwg2rxbytes=0; fi
if [ -z $newwg2txbytes ] || [ $newwg2txbytes -le 0 ]; then newwg2txbytes=0; fi
diffwg2rxbytes=$(awk -v new=$newwg2rxbytes -v old=$oldwg2rxbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
diffwg2txbytes=$(awk -v new=$newwg2txbytes -v old=$oldwg2txbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
thruwg2rxbytes=$(awk -v new=$newwg2rxbytes -v old=$oldwg2rxbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
thruwg2txbytes=$(awk -v new=$newwg2txbytes -v old=$oldwg2txbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
else
diffwg2rxbytes=""
diffwg2txbytes=""
thruwg2rxbytes=""
thruwg2txbytes=""
fi
if [ "$wgstate3" -eq 2 ]; then
newwg3txrxbytes=$(wg show wgc3 transfer)
newwg3rxbytes="$(echo $newwg3txrxbytes | cut -d' ' -f2)"
newwg3txbytes="$(echo $newwg3txrxbytes | cut -d' ' -f3)"
if [ -z $newwg3rxbytes ] || [ $newwg3rxbytes -le 0 ]; then newwg3rxbytes=0; fi
if [ -z $newwg3txbytes ] || [ $newwg3txbytes -le 0 ]; then newwg3txbytes=0; fi
diffwg3rxbytes=$(awk -v new=$newwg3rxbytes -v old=$oldwg3rxbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
diffwg3txbytes=$(awk -v new=$newwg3txbytes -v old=$oldwg3txbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
thruwg3rxbytes=$(awk -v new=$newwg3rxbytes -v old=$oldwg3rxbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
thruwg3txbytes=$(awk -v new=$newwg3txbytes -v old=$oldwg3txbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
else
diffwg3rxbytes=""
diffwg3txbytes=""
thruwg3rxbytes=""
thruwg3txbytes=""
fi
if [ "$wgstate4" -eq 2 ]; then
newwg4txrxbytes=$(wg show wgc4 transfer)
newwg4rxbytes="$(echo $newwg4txrxbytes | cut -d' ' -f2)"
newwg4txbytes="$(echo $newwg4txrxbytes | cut -d' ' -f3)"
if [ -z $newwg4rxbytes ] || [ $newwg4rxbytes -le 0 ]; then newwg4rxbytes=0; fi
if [ -z $newwg4txbytes ] || [ $newwg4txbytes -le 0 ]; then newwg4txbytes=0; fi
diffwg4rxbytes=$(awk -v new=$newwg4rxbytes -v old=$oldwg4rxbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
diffwg4txbytes=$(awk -v new=$newwg4txbytes -v old=$oldwg4txbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
thruwg4rxbytes=$(awk -v new=$newwg4rxbytes -v old=$oldwg4rxbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
thruwg4txbytes=$(awk -v new=$newwg4txbytes -v old=$oldwg4txbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
else
diffwg4rxbytes=""
diffwg4txbytes=""
thruwg4rxbytes=""
thruwg4txbytes=""
fi
if [ "$wgstate5" -eq 2 ]; then
newwg5txrxbytes=$(wg show wgc5 transfer)
newwg5rxbytes="$(echo $newwg5txrxbytes | cut -d' ' -f2)"
newwg5txbytes="$(echo $newwg5txrxbytes | cut -d' ' -f3)"
if [ -z $newwg5rxbytes ] || [ $newwg5rxbytes -le 0 ]; then newwg5rxbytes=0; fi
if [ -z $newwg5txbytes ] || [ $newwg5txbytes -le 0 ]; then newwg5txbytes=0; fi
diffwg5rxbytes=$(awk -v new=$newwg5rxbytes -v old=$oldwg5rxbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
diffwg5txbytes=$(awk -v new=$newwg5txbytes -v old=$oldwg5txbytes -v mb=125000 -v lp=$timerloop 'BEGIN{printf "%.0f\n", ((new-old)/mb)/lp}')
thruwg5rxbytes=$(awk -v new=$newwg5rxbytes -v old=$oldwg5rxbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
thruwg5txbytes=$(awk -v new=$newwg5txbytes -v old=$oldwg5txbytes -v mb=1000000 'BEGIN{printf "%.0f\n", (new-old)/mb}')
else
diffwg5rxbytes=""
diffwg5txbytes=""
thruwg5rxbytes=""
thruwg5txbytes=""
fi
}
resetifacestats()
{
diffwan0rxbytes=""
diffwan0txbytes=""
diffwan1rxbytes=""
diffwan1txbytes=""
diffvpn1rxbytes=""
diffvpn1txbytes=""
diffvpn2rxbytes=""
diffvpn2txbytes=""
diffvpn3rxbytes=""
diffvpn3txbytes=""
diffvpn4rxbytes=""
diffvpn4txbytes=""
diffvpn5rxbytes=""
diffvpn5txbytes=""
diffwg1rxbytes=""
diffwg1txbytes=""
diffwg2rxbytes=""
diffwg2txbytes=""
diffwg3rxbytes=""
diffwg3txbytes=""
diffwg4rxbytes=""
diffwg4txbytes=""
diffwg5rxbytes=""
diffwg5txbytes=""
thruwan0rxbytes=""
thruwan0txbytes=""
thruwan1rxbytes=""
thruwan1txbytes=""
thruvpn1rxbytes=""
thruvpn1txbytes=""
thruvpn2rxbytes=""
thruvpn2txbytes=""
thruvpn3rxbytes=""
thruvpn3txbytes=""
thruvpn4rxbytes=""
thruvpn4txbytes=""
thruvpn5rxbytes=""
thruvpn5txbytes=""
thruwg1rxbytes=""
thruwg1txbytes=""
thruwg2rxbytes=""
thruwg2txbytes=""
thruwg3rxbytes=""
thruwg3txbytes=""
thruwg4rxbytes=""
thruwg4txbytes=""
thruwg5rxbytes=""
thruwg5txbytes=""
resetifacestatsswitch=1
}
# -------------------------------------------------------------------------------------------------------------------------
# This function displays the operations menu
##----------------------------------------##
## Modified by Martinski W. [2024-Oct-05] ##
##----------------------------------------##
displayopsmenu()
{
#scheduler colors and indicators
if [ "$schedule" = "0" ]
then
schedtime="${CDkGray}01:00${CClear}"
elif [ "$schedule" = "1" ]
then
schedhrs="$(printf "%02d" "$schedulehrs")"
schedmin="$(printf "%02d" "$schedulemin")"
schedtime="${CGreen}$schedhrs:$schedmin${CClear}"
fi
#autostart colors and indicators
if [ "$autostart" = "0" ]; then
rebootprot="${CDkGray}Disabled${CClear}"
elif [ "$autostart" = "1" ]; then
rebootprot="${CGreen}Enabled${CClear}"
fi
if [ "$logsize" -eq 0 ]; then
logSizeStr="${CDkGray}n/a${CClear}"
else
logSizeStr="${CGreen}${logsize}${CClear}"
fi
if [ -z "$timerloop" ]; then
timerLoopStr="${CDkGray}n/a${CClear}"
else
timerLoopStr="${CGreen}$timerloop sec${CClear}"
fi
if [ "$pingreset" -eq 0 ]; then
pingResetStr="${CDkGray}Disabled${CClear}"
else
pingResetStr="${CGreen}$pingreset ms${CClear}"
fi
if [ "$amtmemailsuccess" = "0" ] && [ "$amtmemailfailure" = "0" ]; then
amtmdisp="${CDkGray}Disabled "
elif [ "$amtmemailsuccess" = "1" ] && [ "$amtmemailfailure" = "0" ]; then
amtmdisp="${CGreen}Success "
elif [ "$amtmemailsuccess" = "0" ] && [ "$amtmemailfailure" = "1" ]; then
amtmdisp="${CGreen}Failure "
elif [ "$amtmemailsuccess" = "1" ] && [ "$amtmemailfailure" = "1" ]; then
amtmdisp="${CGreen}Success, Failure"
else
amtmdisp="${CDkGray}Disabled "
fi
rldisp=""
if [ "$amtmemailsuccess" = "1" ] || [ "$amtmemailfailure" = "1" ]
then
if [ "$ratelimit" = "0" ]; then
rldisp="| ${CRed}RL"
else
rldisp="| RL: ${CGreen}$ratelimit/h"
fi
fi
recoverdisp="${CClear}Recovery: ${CGreen}${recover}x${CClear}"
#display operations menu
if [ "$availableslots" = "1 2" ]
then
echo -e "${InvGreen} ${InvDkGray}${CWhite} Operations Menu ${CClear}"
echo -e "${InvGreen} ${CClear} Reset/Reconnect VPN 1:${CGreen}(1)${CClear} 2:${CGreen}(2)${CClear} ${InvGreen} ${CClear} ${CGreen}(C)${CClear}onfiguration Menu / Main Setup Menu $rldisp${CClear}"
echo -e "${InvGreen} ${CClear} Stop/Unmonitor VPN 1:${CGreen}(!)${CClear} 2:${CGreen}(@)${CClear} ${InvGreen} ${CClear} ${CGreen}(R)${CClear}eset VPN/WG CRON Time Scheduler: $schedtime"
echo -e "${InvGreen} ${CClear} Enable/Disable ${CGreen}(M)${CClear}onitored VPN Slots | Time Reset ${InvGreen} ${CClear} ${CGreen}(L)${CClear}og Viewer / Trim Log Size (rows): $logSizeStr"
echo -e "${InvGreen} ${CClear} Update/Maintain ${CGreen}(V)${CClear}PN Server Lists ${InvGreen} ${CClear} ${CGreen}(A)${CClear}utostart VPNMON-R3 on Reboot: $rebootprot"
echo -e "${InvGreen} ${CClear} Edit/R${CGreen}(U)${CClear}n Server List Automation ${InvGreen} ${CClear} ${CGreen}(T)${CClear}imer Loop Check Interval: $timerLoopStr | $recoverdisp"
echo -e "${InvGreen} ${CClear} AMTM Email Not${CGreen}(I)${CClear}fications: $amtmdisp ${InvGreen} ${CClear} ${CGreen}(P)${CClear}ing Maximum Before Reset in ms: $pingResetStr"
echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------------------------${CClear}"
echo ""
elif [ "$availableslots" = "1 2 3 4 5" ]
then
echo -e "${InvGreen} ${InvDkGray}${CWhite} Operations Menu ${CClear}"
echo -e "${InvGreen} ${CClear} Reset/Reconnect VPN 1:${CGreen}(1)${CClear} 2:${CGreen}(2)${CClear} 3:${CGreen}(3)${CClear} 4:${CGreen}(4)${CClear} 5:${CGreen}(5)${CClear} ${InvGreen} ${CClear} ${CGreen}(C)${CClear}onfiguration Menu / Main Setup Menu $rldisp${CClear}"
echo -e "${InvGreen} ${CClear} Stop/Unmonitor VPN 1:${CGreen}(!)${CClear} 2:${CGreen}(@)${CClear} 3:${CGreen}(#)${CClear} 4:${CGreen}($)${CClear} 5:${CGreen}(%)${CClear} ${InvGreen} ${CClear} ${CGreen}(R)${CClear}eset VPN/WG CRON Time Scheduler: $schedtime"
echo -e "${InvGreen} ${CClear} Reset/Reconnect WG 1:${CGreen}(6)${CClear} 2:${CGreen}(7)${CClear} 3:${CGreen}(8)${CClear} 4:${CGreen}(9)${CClear} 5:${CGreen}(0)${CClear} ${InvGreen} ${CClear} ${CGreen}(L)${CClear}og Viewer / Trim Log Size (rows): $logSizeStr"
echo -e "${InvGreen} ${CClear} Stop/Unmonitor WG 1:${CGreen}(^)${CClear} 2:${CGreen}(&)${CClear} 3:${CGreen}(-)${CClear} 4:${CGreen}(+)${CClear} 5:${CGreen}(=)${CClear} ${InvGreen} ${CClear} ${CGreen}(A)${CClear}utostart VPNMON-R3 on Reboot: $rebootprot"
echo -e "${InvGreen} ${CClear} Enable/Disable ${CGreen}(M)${CClear}onitored VPN/WG Slots | Time Reset ${InvGreen} ${CClear} ${CGreen}(T)${CClear}imer Loop Check Interval: $timerLoopStr | $recoverdisp"
echo -e "${InvGreen} ${CClear} Update/Maintain ${CGreen}(V)${CClear}PN/${CGreen}(W)${CClear}G Server Lists ${InvGreen} ${CClear} ${CGreen}(P)${CClear}ing Maximum Before Reset in ms: $pingResetStr"
echo -e "${InvGreen} ${CClear} Edit/R${CGreen}(U)${CClear}n Server List Automation ${InvGreen} ${CClear} AMTM Email Not${CGreen}(I)${CClear}fications: $amtmdisp"
echo -e "${InvGreen} ${CClear}${CDkGray}--------------------------------------------------------------------------------------------------------------------------------${CClear}"
echo ""
fi
}
# -------------------------------------------------------------------------------------------------------------------------
# Begin VPNMON-R2 Main Loop
# -------------------------------------------------------------------------------------------------------------------------
#DEBUG=; set -x # uncomment/comment to enable/disable debug mode
#{ # uncomment/comment to enable/disable debug mode
# Create the necessary folder/file structure for VPNMON-R3 under /jffs/addons
if [ ! -d "/jffs/addons/vpnmon-r3.d" ]; then
mkdir -p "/jffs/addons/vpnmon-r3.d"
fi
# Check for and add an alias for VPNMON-R3
if ! grep -F "sh /jffs/scripts/vpnmon-r3.sh" /jffs/configs/profile.add >/dev/null 2>/dev/null; then
echo "alias vpnmon-r3=\"sh /jffs/scripts/vpnmon-r3.sh\" # added by vpnmon-r3" >> /jffs/configs/profile.add
fi
##-------------------------------------##
## Added by Martinski W. [2024-Oct-05] ##
##-------------------------------------##
_SetUpTimeoutCmdVars_
_SetLAN_HostName_
##-------------------------------------##
## Added by Martinski W. [2024-Nov-04] ##
##-------------------------------------##
ROUTERMODEL="$($timeoutcmd$timeoutsec nvram get odmpid)"
[ -z "$ROUTERMODEL" ] && ROUTERMODEL="$($timeoutcmd$timeoutsec nvram get productid)"
FWVER="$($timeoutcmd$timeoutsec nvram get firmver | tr -d '.')"
BUILDNO="$($timeoutcmd$timeoutsec nvram get buildno)"
EXTENDNO="$($timeoutcmd$timeoutsec nvram get extendno)"
if [ -z "$EXTENDNO" ]; then EXTENDNO=0; fi
FWBUILD="${FWVER}.${BUILDNO}_${EXTENDNO}"
# Check for updates
updatecheck
# Check and see if any commandline option is being used
if [ $# -eq 0 ] || [ -z "$1" ]
then
clear
exec sh /jffs/scripts/vpnmon-r3.sh -noswitch
exit 0
fi
# Check and see if an invalid commandline option is being used
if [ "$1" = "-h" ] || [ "$1" = "-help" ] || [ "$1" = "-setup" ] || [ "$1" = "-reset" ] || [ "$1" = "-bw" ] || [ "$1" = "-noswitch" ] || [ "$1" = "-screen" ] || [ "$1" = "-now" ] || [ "$1" = "-uowginitstart" ] || [ "$1" = "-uowgnatstart" ]
then
clear
else
clear
echo ""
echo "VPNMON-R3 v$version"
echo ""
echo "Exiting due to invalid commandline options!"
echo "(run 'vpnmon-r3 -h' for help)"
echo ""
echo -e "${CClear}"
exit 0
fi
# Check to see if the help option is being called
if [ "$1" = "-h" ] || [ "$1" = "-help" ]
then
clear
echo ""
echo "VPNMON-R3 v$version Commandline Option Usage:"
echo ""
echo "vpnmon-r3 -h | -help"
echo "vpnmon-r3 -setup"
echo "vpnmon-r3 -reset"
echo "vpnmon-r3 -bw"
echo "vpnmon-r3 -screen"
echo "vpnmon-r3 -screen -now"
echo ""
echo " -h | -help (this output)"
echo " -setup (displays the setup menu)"
echo " -reset (resets vpn connections and exits)"
echo " -bw (runs vpnmon-r3 in monochrome mode)"
echo " -screen (runs vpnmon-r3 in screen background)"
echo " -screen -now (runs vpnmon-r3 in screen background immediately)"
echo ""
echo -e "${CClear}"
exit 0
fi
# Check to see if the Unbound-over-WG init-start action is being called
if [ "$1" = "-uowginitstart" ]
then
uowginitstart
exit 0
fi
# Check to see if the Unbound-over-WG nat-start action is being called
if [ "$1" = "-uowgnatstart" ]
then
uowgnatstart
exit 0
fi
# Check to see if a second command is being passed to remove color
if [ "$1" = "-bw" ] || { [ $# -gt 1 ] && [ "$2" = "-bw" ] ; }
then
blackwhite
fi
# Check to see if the -now parameter is being called to bypass the screen timer
if [ $# -gt 1 ] && [ "$2" = "-now" ]
then
bypassscreentimer=1
fi
# Check to see if the setup option is being called
if [ "$1" = "-setup" ]
then
logoNM
vsetup
exit 0
fi
# Check to see if the reset option is being called
if [ "$1" = "-reset" ]
then
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - INFO: VPN Reset initiated through -RESET switch" >> $logfile
vreset
fi
# Check to see if the screen option is being called and run operations normally using the screen utility
if [ "$1" = "-screen" ]
then
screen -wipe >/dev/null 2>&1 # Kill any dead screen sessions
sleep 1
ScreenSess=$(screen -ls | grep "vpnmon-r3" | awk '{print $1}' | cut -d . -f 1)
if [ -z $ScreenSess ]; then
if [ "$bypassscreentimer" = "1" ]; then
screen -dmS "vpnmon-r3" $apppath -noswitch
sleep 1
screen -r vpnmon-r3
else
clear
echo -e "${CClear}Executing ${CGreen}VPNMON-R3 v$version${CClear} using the SCREEN utility..."
echo ""
echo -e "${CClear}IMPORTANT:"
echo -e "${CClear}In order to keep VPNMON-R3 running in the background,"
echo -e "${CClear}properly exit the SCREEN session by using: ${CGreen}CTRL-A + D${CClear}"
echo ""
screen -dmS "vpnmon-r3" $apppath -noswitch
sleep 5
screen -r vpnmon-r3
exit 0
fi
else
if [ "$bypassscreentimer" = "1" ]; then
sleep 1
else
clear
echo -e "${CClear}Connecting to existing ${CGreen}VPNMON-R3 v$version${CClear} SCREEN session...${CClear}"
echo ""
echo -e "${CClear}IMPORTANT:${CClear}"
echo -e "${CClear}In order to keep VPNMON-R3 running in the background,${CClear}"
echo -e "${CClear}properly exit the SCREEN session by using: ${CGreen}CTRL-A + D${CClear}"
echo ""
echo -e "${CClear}Switching to the SCREEN session in T-5 sec...${CClear}"
echo -e "${CClear}"
spinner 5
fi
fi
screen -dr $ScreenSess
exit 0
fi
# Check to see if the noswitch option is being called
if [ "$1" = "-noswitch" ]
then
clear #last switch before the main program starts
firstrun=1
# Clean up lockfile
rm -f $lockfile >/dev/null 2>&1
if [ ! -f "$config" ] && [ ! -f "/opt/bin/timeout" ] && [ ! -f "/opt/sbin/screen" ] && [ ! -f "/opt/bin/jq" ]
then
echo -e "${CRed}ERROR: VPNMON-R3 is not configured. Please run 'vpnmon-r3 -setup' first.${CClear}"
echo ""
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: VPNMON-R3 is not configured. Please run the setup/configuration utility" >> $logfile
exit 0
fi
fi
ubsync=""
firstDataCollection=true
resetifacestatsswitch=0
##----------------------------------------##
## Modified by Martinski W. [2024-Nov-02] ##
##----------------------------------------##
while true
do
_SetUpTimeoutCmdVars_
_SetLAN_HostName_
# Grab the VPNMON-R3 config file and read it in
if [ -f "$config" ]
then
source "$config"
else
clear
echo -e "${CRed}ERROR: VPNMON-R3 is not configured. Please run 'vpnmon-r3.sh -setup' first."
echo ""
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: VPNMON-R3 config file not found. Please run the setup/configuration utility" >> $logfile
echo -e "${CClear}"
exit 1
fi
# Grab the monitored slots file and read it in
if [ -f /jffs/addons/vpnmon-r3.d/vr3clients.txt ]
then
source /jffs/addons/vpnmon-r3.d/vr3clients.txt
else
clear
echo -e "${CRed}ERROR: VPNMON-R3 is not configured. Please run 'vpnmon-r3.sh -setup' first."
echo ""
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: VPNMON-R3 VPN Client Monitoring file not found. Please run the setup/configuration utility" >> $logfile
echo -e "${CClear}"
exit 1
fi
createconfigs
# Grab the monitored slots file and read it in
if [ -f /jffs/addons/vpnmon-r3.d/vr3timers.txt ]
then
source /jffs/addons/vpnmon-r3.d/vr3timers.txt
else
clear
echo -e "${CRed}ERROR: VPNMON-R3 is not configured. Please run 'vpnmon-r3.sh -setup' first."
echo ""
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - ERROR: VPNMON-R3 VPN Timer Monitoring file not found. Please run the setup/configuration utility" >> $logfile
echo -e "${CClear}"
exit 1
fi
#Set variables
resetvpn=0
resetwg=0
#Check to see if a reset is currently underway
lockcheck
clear #display the header
if [ "$hideoptions" = "0" ] && [ "$hideoptions" != "$prevHideOpts" ]
then
timerreset=0
displayopsmenu
else
timerreset=0
fi
prevHideOpts="$hideoptions"
tzone="$(date +%Z)"
tzonechars="${#tzone}"
if [ "$tzonechars" = "1" ]; then tzspaces=" ";
elif [ "$tzonechars" = "2" ]; then tzspaces=" ";
elif [ "$tzonechars" = "3" ]; then tzspaces=" ";
elif [ "$tzonechars" = "4" ]; then tzspaces=" ";
elif [ "$tzonechars" = "5" ]; then tzspaces=" "; fi
#Display VPNMON-R3 client header
echo -en "${InvGreen} ${InvDkGray}${CWhite} VPNMON-R3 - v"
printf "%-8s" $version
echo -e " ${CGreen}(S)${CWhite}how/${CGreen}(H)${CWhite}ide Operations Menu ${InvDkGray} $tzspaces$(date) ${CClear}"
#Display VPNMON-R2 Found Warning
if [ -f /jffs/scripts/vpnmon-r2.sh ]; then
echo -e "${InvYellow} ${InvRed}${CWhite} VPNMON-R2 Install Detected. Support and availability for R2 is being sunset. Press (X) for Uninstall Menu. ${CClear}"
fi
#Display VPNMON-R3 Update Notifications
if [ "$UpdateNotify" != "0" ]; then echo -e "$UpdateNotify\n"; else echo -e "${CClear}"; fi
#If WAN Monitoring is enabled, test WAN connection and show the following grid
if [ "$monitorwan" = "1" ] && [ "$firstrun" = "1" ]
then
#Check to see if the WAN is up
checkwan
firstrun=0
fi
if [ "$monitorwan" = "1" ] && [ "$firstrun" = "0" ]
then
#Display WAN ports grid
if [ "$bwdisp" = "1" ]; then
echo -e "${CClear} Port | Mon | IFace | Health | WAN State | Public WAN IP | Ping-->WAN | Rx Avg | Tx Avg | City Exit / Uptime"
else
echo -e "${CClear} Port | Mon | IFace | Health | WAN State | Public WAN IP | Ping-->WAN | Rx Ttl | Tx Ttl | City Exit / Uptime"
fi
echo -e "-------|-----|--------|--------|--------------|-----------------|------------|--------|------------------------------------------"
#Cycle through the WANCheck connection function to display ping/city info
wans=0
for wans in 0 1
do
wancheck "$wans"
done
echo -e "-------|-----|--------|--------|--------------|-----------------|------------|--------|------------------------------------------"
echo ""
fi
if [ "$useovpn" = "1" ]
then
echo -e "${InvDkGray} OpenVPN ${CClear}"
echo ""
#Display VPN client slot grid
if [ "$unboundclient" != "0" ]; then
if [ "$bwdisp" = "1" ]; then
echo -e " Slot | Mon | Svrs | Health | VPN State | Public VPN IP | Ping-->VPN | Rx Avg | Tx Avg | City Exit / Time Connected / UB"
else
echo -e " Slot | Mon | Svrs | Health | VPN State | Public VPN IP | Ping-->VPN | Rx Ttl | Tx Ttl | City Exit / Time Connected / UB"
fi
else
if [ "$bwdisp" = "1" ]; then
echo -e " Slot | Mon | Svrs | Health | VPN State | Public VPN IP | Ping-->VPN | Rx Avg | Tx Avg | City Exit / Time Connected"
else
echo -e " Slot | Mon | Svrs | Health | VPN State | Public VPN IP | Ping-->VPN | Rx Ttl | Tx Ttl | City Exit / Time Connected"
fi
fi
echo -e "-------|-----|--------|--------|--------------|-----------------|------------|--------|------------------------------------------"
if "$firstDataCollection" ; then printf "\r\033[0K${InvYellow} ${CClear} Please wait..." ; sleep 1 ; fi
i=0
for i in $availableslots #loop through the VPN slots
do
#Set variables
citychange=""
ubsync=""
vpnrx1=""
vpntx1=""
vpnrx2=""
vpntx2=""
#determine if the slot is monitored#
if [ "$((VPN$i))" = "1" ]; then
monitored="${CGreen}[X]${CClear}"
else
monitored="[ ]"
fi
#determine the vpn state, and if connected, get vpn IP and city
vpnstate="$(_VPN_GetClientState_ "$i")"
if [ "$vpnstate" = "0" ]
then
vpnstate="Disconnected"
vpnhealth="${CDkGray}[n/a ]${CClear}"
vpnindicator="${InvDkGray} ${CClear}"
vpnip=" ${CDkGray}[n/a]${CClear}"
vpncity="${CDkGray}[n/a]${CClear}"
svrping=" ${CDkGray}[n/a]${CClear}"
vpnrx1="${CDkGray}[n/a ]${CClear}"
vpntx1="${CDkGray}[n/a ]${CClear}"
vpnrx2="${CDkGray}[n/a ]${CClear}"
vpntx2="${CDkGray}[n/a ]${CClear}"
elif [ "$vpnstate" = "-1" ]
then
vpnstate="Error State "
vpnhealth="${CDkGray}[n/a ]${CClear}"
vpnindicator="${InvDkGray} ${CClear}"
vpnip="${CDkGray} [n/a]${CClear}"
vpncity="${CDkGray}[n/a]${CClear}"
svrping=" ${CDkGray}[n/a]${CClear}"
vpnrx1="${CDkGray}[n/a ]${CClear}"
vpntx1="${CDkGray}[n/a ]${CClear}"
vpnrx2="${CDkGray}[n/a ]${CClear}"
vpntx2="${CDkGray}[n/a ]${CClear}"
elif [ "$vpnstate" = "1" ]
then
vpnstate="Connecting "
vpnhealth="${CDkGray}[n/a ]${CClear}"
vpnindicator="${InvYellow} ${CClear}"
vpnip=" ${CDkGray}[n/a]${CClear}"
vpncity="${CDkGray}[n/a]${CClear}"
svrping=" ${CDkGray}[n/a]${CClear}"
vpnrx1="${CDkGray}[n/a ]${CClear}"
vpntx1="${CDkGray}[n/a ]${CClear}"
vpnrx2="${CDkGray}[n/a ]${CClear}"
vpntx2="${CDkGray}[n/a ]${CClear}"
elif [ "$vpnstate" = "2" ]
then
vpnstate="Connected "
checkvpn "$i"
getvpnip "$i"
getvpncity "$i"
if [ -z "$vpnping" ]
then
svrping="${CRed}[PING ERR]${CClear}"
vpnhealth="${CYellow}[UNKN]${CClear}"
vpnindicator="${InvYellow} ${CClear}"
else
## No need to do left-padding with zeros for alignment ##
svrping="$(printf "[%8.3f]" "$vpnping")"
fi
else
vpnstate="Unknown "
vpnhealth="${CDkGray}[n/a ]${CClear}"
vpnindicator="${InvDkGray} ${CClear}"
vpnip=" ${CDkGray}[n/a]${CClear}"
vpncity="${CDkGray}[n/a]${CClear}"
svrping=" ${CDkGray}[n/a]${CClear}"
fi
#Determine how many server entries are in each of the vpn slot alternate server files#
if [ -s "/jffs/addons/vpnmon-r3.d/vr3svr$i.txt" ]
then
servercnt="$(cat "/jffs/addons/vpnmon-r3.d/vr3svr$i.txt" | wc -l)"
if [ -z "$servercnt" ] || [ "$servercnt" -lt 1 ]
then
servercnt="${CRed}[0000]${CClear}"
else
## No need to do left-padding with zeros for alignment ##
servercnt="$(printf "[%4d]" "$servercnt")"
fi
else
servercnt="${CRed}[0000]${CClear}"
fi
#Calculate connected time for current VPN slot
if [ $((VPNTIMER$i)) = "0" ] || [ "$((VPN$i))" = "0" ]
then
sincelastreset=""
else
currtime=$(date +%s)
timediff=$((currtime-VPNTIMER$i))
sincelastreset=$(printf ': %dd %02dh:%02dm\n' $(($timediff/86400)) $(($timediff%86400/3600)) $(($timediff%3600/60)))
fi
if [ -z "$vpnrx1" ]
then
vpnbwrx=""
tmpvpnslot="diffvpn${i}rxbytes"
eval currentvpnslot=\$$tmpvpnslot
vpnbwtx="$(printf '%4s' "$currentvpnslot")"
if [ -z "$currentvpnslot" ] || [ "$currentvpnslot" = "" ] || [ "$currentvpnslot" -lt 0 ]
then
vpnrx1="${CRed}[UNKN]${CClear}"
elif [ "$currentvpnslot" -ge 0 ] && [ "$currentvpnslot" -le "$lowutilspd" ]
then
vpnrx1="${CGreen}[$vpnbwtx]${CClear}"
elif [ "$currentvpnslot" -gt "$lowutilspd" ] && [ "$currentvpnslot" -le "$medutilspd" ]
then
vpnrx1="${CYellow}[$vpnbwtx]${CClear}"
elif [ "$currentvpnslot" -gt "$medutilspd" ]
then
vpnrx1="${CRed}[$vpnbwtx]${CClear}"
fi
fi
if [ -z "$vpnrx2" ]
then
vpntprx=""
tmpvpntpslot="thruvpn${i}rxbytes"
eval currentvpntpslot=\$$tmpvpntpslot
vpntptx="$(printf '%4s' "$currentvpntpslot")"
if [ -z "$currentvpntpslot" ] || [ "$currentvpntpslot" = "" ] || [ "$currentvpntpslot" -lt 0 ]
then
vpnrx2="${CRed}[UNKN]${CClear}"
elif [ "$currentvpntpslot" -ge 0 ] && [ "$currentvpntpslot" -le "$lowutilspd" ]
then
vpnrx2="${CGreen}[$vpntptx]${CClear}"
elif [ "$currentvpntpslot" -gt "$lowutilspd" ] && [ "$currentvpntpslot" -le "$medutilspd" ]
then
vpnrx2="${CYellow}[$vpntptx]${CClear}"
elif [ "$currentvpntpslot" -gt "$medutilspd" ]
then
vpnrx2="${CRed}[$vpntptx]${CClear}"
fi
fi
if [ -z "$vpntx1" ]
then
vpnbwtx=""
tmpvpnslot="diffvpn${i}txbytes"
eval currentvpnslot=\$$tmpvpnslot
vpnbwtx="$(printf '%4s' "$currentvpnslot")"
if [ -z "$currentvpnslot" ] || [ "$currentvpnslot" = "" ] || [ "$currentvpnslot" -lt 0 ]
then
vpntx1="${CRed}[UNKN]${CClear}"
elif [ "$currentvpnslot" -ge 0 ] && [ "$currentvpnslot" -le "$lowutilspdup" ]
then
vpntx1="${CGreen}[$vpnbwtx]${CClear}"
elif [ "$currentvpnslot" -gt "$lowutilspdup" ] && [ "$currentvpnslot" -le "$medutilspdup" ]
then
vpntx1="${CYellow}[$vpnbwtx]${CClear}"
elif [ "$currentvpnslot" -gt "$medutilspdup" ]
then
vpntx1="${CRed}[$vpnbwtx]${CClear}"
fi
fi
if [ -z "$vpntx2" ]
then
vpntptx=""
tmpvpntpslot="thruvpn${i}txbytes"
eval currentvpntpslot=\$$tmpvpntpslot
vpntptx="$(printf '%4s' "$currentvpntpslot")"
if [ -z "$currentvpntpslot" ] || [ "$currentvpntpslot" = "" ] || [ "$currentvpntpslot" -lt 0 ]
then
vpntx2="${CRed}[UNKN]${CClear}"
elif [ "$currentvpntpslot" -ge 0 ] && [ "$currentvpntpslot" -le "$lowutilspdup" ]
then
vpntx2="${CGreen}[$vpntptx]${CClear}"
elif [ "$currentvpntpslot" -gt "$lowutilspdup" ] && [ "$currentvpntpslot" -le "$medutilspdup" ]
then
vpntx2="${CYellow}[$vpntptx]${CClear}"
elif [ "$currentvpntpslot" -gt "$medutilspdup" ]
then
vpntx2="${CRed}[$vpntptx]${CClear}"
fi
fi
if "$firstDataCollection" ; then printf "\r\033[0K" ; firstDataCollection=false ; fi
# Print the results of all data gathered sofar #
if [ "$bwdisp" = "1" ]; then
echo -e "$vpnindicator${InvDkGray}${CWhite} VPN$i${CClear} | $monitored | $servercnt | $vpnhealth | $vpnstate | $vpnip | $svrping | $vpntx1 | $vpnrx1 | $vpncity$sincelastreset $citychange$ubsync"
else
echo -e "$vpnindicator${InvDkGray}${CWhite} VPN$i${CClear} | $monitored | $servercnt | $vpnhealth | $vpnstate | $vpnip | $svrping | $vpntx2 | $vpnrx2 | $vpncity$sincelastreset $citychange$ubsync"
fi
#if a vpn is monitored and disconnected, try to restart it
if [ "$((VPN$i))" = "1" ] && [ "$vpnstate" = "Disconnected" ]
then #reconnect
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: VPN$i has disconnected" >> $logfile
echo ""
printf "\33[2K\r"
#Display a standard timer#
timer=0
while [ $timer -ne 5 ]
do
timer="$((timer+1))"
preparebar 46 "|"
progressbarpause $timer 5 "" "s" "Standard"
done
printf "\33[2K\r"
restartvpn $i
sendmessage 1 "VPN Tunnel Disconnected" $i
restartrouting
resetspdmerlin
exec sh /jffs/scripts/vpnmon-r3.sh -noswitch
fi
#if a vpn is monitored and in error state, try to restart it
if [ "$((VPN$i))" = "1" ] && [ "$vpnstate" = "Error State " ]
then #reconnect
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: VPN$i is in an error state and being reconnected" >> $logfile
echo ""
printf "\33[2K\r"
#display a standard timer#
timer=0
while [ $timer -ne 5 ]
do
timer="$((timer+1))"
preparebar 46 "|"
progressbarpause $timer 5 "" "s" "Standard"
#sleep 1
done
printf "\33[2K\r"
restartvpn $i
sendmessage 1 "VPN Slot In Error State" $i
restartrouting
resetspdmerlin
exec sh /jffs/scripts/vpnmon-r3.sh -noswitch
fi
#if a vpn is monitored and not responsive, try to restart it
if [ "$((VPN$i))" = "1" ] && [ "$resetvpn" != "0" ]
then #reconnect
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: VPN$i is non-responsive and being reconnected" >> $logfile
echo ""
printf "\33[2K\r"
#display a standard timer#
timer=0
while [ $timer -ne 5 ]
do
timer="$((timer+1))"
preparebar 46 "|"
progressbarpause $timer 5 "" "s" "Standard"
#sleep 1
done
printf "\33[2K\r"
restartvpn $resetvpn
sendmessage 1 "VPN Slot Is Non-Responsive" $resetvpn
restartrouting
resetspdmerlin
exec sh /jffs/scripts/vpnmon-r3.sh -noswitch
fi
if [ "$((VPN$i))" = "1" ]; then
# if a vpn connection ping is greater than a certain amount, restart it
maxsvrping=$(awk "BEGIN {printf \"%3.0f\", ${vpnping}}") >/dev/null 2>&1
MP=$?
if [ $MP -ne 0 ]; then
if [ -z "$maxsvrping" ] || [ "$maxsvrping" = "" ]; then
maxsvrping="Null"
fi
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: VPN$i received invalid PING information. Contents: $maxsvrping" >> $logfile
maxsvrping=0
fi
else
maxsvrping=0
fi
if [ "$pingreset" -gt 0 ]
then
if [ "$maxsvrping" -ge "$pingreset" ]
then
echo ""
printf "\33[2K\r"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: VPN$i PING exceeds max allowed ($pingreset ms)" >> $logfile
printf "${CGreen}\r[Maximum PING Exceeded]"
sleep 3
printf "\33[2K\r"
#display a standard timer#
timer=0
while [ $timer -ne 5 ]
do
timer="$((timer+1))"
preparebar 46 "|"
progressbarpause $timer 5 "" "s" "Standard"
#sleep 1
done
printf "\33[2K\r"
restartvpn $i
sendmessage 1 "VPN Slot Exceeded Max Ping" $i
restartrouting
resetspdmerlin
exec sh /jffs/scripts/vpnmon-r3.sh -noswitch
fi
fi
#Reset variables
ubsync=""
sincelastreset=""
done
echo -e "-------|-----|--------|--------|--------------|-----------------|------------|--------|------------------------------------------"
echo ""
fi
#-----------------Wireguard
if [ "$availableslots" = "1 2 3 4 5" ] && [ "$usewg" = "1" ]; then
echo -e "${InvDkGray} Wireguard ${CClear}"
echo ""
#Display WG client slot grid
if [ "$unboundwgclient" != "0" ]; then
if [ "$bwdisp" = "1" ]; then
echo -e " Slot | Mon | Svrs | Health | WG State | Public WG IP | Ping--->WG | Rx Avg | Tx Avg | City Exit / Time Connected / UB"
else
echo -e " Slot | Mon | Svrs | Health | WG State | Public WG IP | Ping--->WG | Rx Ttl | Tx Ttl | City Exit / Time Connected / UB"
fi
else
if [ "$bwdisp" = "1" ]; then
echo -e " Slot | Mon | Svrs | Health | WG State | Public WG IP | Ping--->WG | Rx Avg | Tx Avg | City Exit / Time Connected"
else
echo -e " Slot | Mon | Svrs | Health | WG State | Public WG IP | Ping--->WG | Rx Ttl | Tx Ttl | City Exit / Time Connected"
fi
fi
echo -e "-------|-----|--------|--------|--------------|-----------------|------------|--------|------------------------------------------"
i=0
for i in $availableslots #loop through the VPN slots
do
#Set variables
wgcitychange=""
ubsync=""
wgrx1=""
wgtx1=""
wgrx2=""
wgtx2=""
#determine if the slot is monitored#
if [ "$((WG$i))" = "1" ]; then
wgmonitored="${CGreen}[X]${CClear}"
else
wgmonitored="[ ]"
fi
#determine the vpn state, and if connected, get vpn IP and city
wgstate="$(_WG_GetClientState_ "$i")"
if [ "$wgstate" = "0" ]
then
wgstate="Disconnected"
wghealth="${CDkGray}[n/a ]${CClear}"
wgindicator="${InvDkGray} ${CClear}"
wgip=" ${CDkGray}[n/a]${CClear}"
wgcity="${CDkGray}[n/a]${CClear}"
wgsvrping=" ${CDkGray}[n/a]${CClear}"
wgrx1="${CDkGray}[n/a ]${CClear}"
wgtx1="${CDkGray}[n/a ]${CClear}"
wgrx2="${CDkGray}[n/a ]${CClear}"
wgtx2="${CDkGray}[n/a ]${CClear}"
elif [ "$wgstate" = "2" ]
then
wgstate="Connected "
checkwg "$i"
getwgip "$i"
getwgcity "$i"
if [ -z "$wgping" ]
then
wgsvrping="${CRed}[PING ERR]${CClear}"
wghealth="${CYellow}[UNKN]${CClear}"
wgindicator="${InvYellow} ${CClear}"
else
## No need to do left-padding with zeros for alignment ##
wgsvrping="$(printf "[%8.3f]" "$wgping")"
fi
else
wgstate="Unknown "
wghealth="${CDkGray}[n/a ]${CClear}"
wgindicator="${InvDkGray} ${CClear}"
wgip=" ${CDkGray}[n/a]${CClear}"
wgcity="${CDkGray}[n/a]${CClear}"
wgsvrping=" ${CDkGray}[n/a]${CClear}"
wgrx1="${CDkGray}[n/a ]${CClear}"
wgtx1="${CDkGray}[n/a ]${CClear}"
wgrx2="${CDkGray}[n/a ]${CClear}"
wgtx2="${CDkGray}[n/a ]${CClear}"
fi
#Determine how many server entries are in each of the vpn slot alternate server files#
if [ -s "/jffs/addons/vpnmon-r3.d/vr3wgsvr$i.txt" ]
then
wgservercnt="$(cat "/jffs/addons/vpnmon-r3.d/vr3wgsvr$i.txt" | wc -l)"
if [ -z "$wgservercnt" ] || [ "$wgservercnt" -lt 1 ]
then
wgservercnt="${CRed}[0000]${CClear}"
else
## No need to do left-padding with zeros for alignment ##
wgservercnt="$(printf "[%4d]" "$wgservercnt")"
fi
else
wgservercnt="${CRed}[0000]${CClear}"
fi
#Calculate connected time for current VPN slot
if [ $((WGTIMER$i)) = "0" ] || [ "$((WG$i))" = "0" ]
then
wgsincelastreset=""
else
wgcurrtime=$(date +%s)
wgtimediff=$((wgcurrtime-WGTIMER$i))
wgsincelastreset=$(printf ': %dd %02dh:%02dm\n' $(($wgtimediff/86400)) $(($wgtimediff%86400/3600)) $(($wgtimediff%3600/60)))
fi
if [ -z "$wgrx1" ]
then
wgbwrx=""
tmpwgslot="diffwg${i}rxbytes"
eval currentwgslot=\$$tmpwgslot
wgbwrx="$(printf '%4s' "$currentwgslot")"
if [ -z "$currentwgslot" ] || [ "$currentwgslot" = "" ] || [ "$currentwgslot" -lt 0 ]
then
wgrx1="${CRed}[UNKN]${CClear}"
elif [ "$currentwgslot" -ge 0 ] && [ "$currentwgslot" -le "$lowutilspd" ]
then
wgrx1="${CGreen}[$wgbwrx]${CClear}"
elif [ "$currentwgslot" -gt "$lowutilspd" ] && [ "$currentwgslot" -le "$medutilspd" ]
then
wgrx1="${CYellow}[$wgbwrx]${CClear}"
elif [ "$currentwgslot" -gt "$medutilspd" ]
then
wgrx1="${CRed}[$wgbwrx]${CClear}"
fi
fi
if [ -z "$wgrx2" ]
then
wgtprx=""
tmpwgtpslot="thruwg${i}rxbytes"
eval currentwgtpslot=\$$tmpwgtpslot
wgtprx="$(printf '%4s' "$currentwgtpslot")"
if [ -z "$currentwgtpslot" ] || [ "$currentwgtpslot" = "" ] || [ "$currentwgtpslot" -lt 0 ]
then
wgrx2="${CRed}[UNKN]${CClear}"
elif [ "$currentwgtpslot" -ge 0 ] && [ "$currentwgtpslot" -le "$lowutilspd" ]
then
wgrx2="${CGreen}[$wgtprx]${CClear}"
elif [ "$currentwgtpslot" -gt "$lowutilspd" ] && [ "$currentwgtpslot" -le "$medutilspd" ]
then
wgrx2="${CYellow}[$wgtprx]${CClear}"
elif [ "$currentwgtpslot" -gt "$medutilspd" ]
then
wgrx2="${CRed}[$wgtprx]${CClear}"
fi
fi
if [ -z "$wgtx1" ]
then
wgbwtx=""
tmpwgslot="diffwg${i}txbytes"
eval currentwgslot=\$$tmpwgslot
wgbwtx="$(printf '%4s' "$currentwgslot")"
if [ -z "$currentwgslot" ] || [ "$currentwgslot" = "" ] || [ "$currentwgslot" -lt 0 ]
then
wgtx1="${CRed}[UNKN]${CClear}"
elif [ "$currentwgslot" -ge 0 ] && [ "$currentwgslot" -le "$lowutilspdup" ]
then
wgtx1="${CGreen}[$wgbwtx]${CClear}"
elif [ "$currentwgslot" -gt "$lowutilspdup" ] && [ "$currentwgslot" -le "$medutilspdup" ]
then
wgtx1="${CYellow}[$wgbwtx]${CClear}"
elif [ "$currentwgslot" -gt "$medutilspdup" ]
then
wgtx1="${CRed}[$wgbwtx]${CClear}"
fi
fi
if [ -z "$wgtx2" ]
then
wgtptx=""
tmpwgtpslot="thruwg${i}txbytes"
eval currentwgtpslot=\$$tmpwgtpslot
wgtptx="$(printf '%4s' "$currentwgtpslot")"
if [ -z "$currentwgtpslot" ] || [ "$currentwgtpslot" = "" ] || [ "$currentwgtpslot" -lt 0 ]
then
wgtx2="${CRed}[UNKN]${CClear}"
elif [ "$currentwgtpslot" -ge 0 ] && [ "$currentwgtpslot" -le "$lowutilspdup" ]
then
wgtx2="${CGreen}[$wgtptx]${CClear}"
elif [ "$currentwgtpslot" -gt "$lowutilspdup" ] && [ "$currentwgtpslot" -le "$medutilspdup" ]
then
wgtx2="${CYellow}[$wgtptx]${CClear}"
elif [ "$currentwgtpslot" -gt "$medutilspdup" ]
then
wgtx2="${CRed}[$wgtptx]${CClear}"
fi
fi
# Print the results of all data gathered sofar #
if [ "$bwdisp" = "1" ]; then
echo -e "$wgindicator${InvDkGray}${CWhite} WGC$i${CClear} | $wgmonitored | $wgservercnt | $wghealth | $wgstate | $wgip | $wgsvrping | $wgrx1 | $wgtx1 | $wgcity$wgsincelastreset $wgcitychange$ubsync"
else
echo -e "$wgindicator${InvDkGray}${CWhite} WGC$i${CClear} | $wgmonitored | $wgservercnt | $wghealth | $wgstate | $wgip | $wgsvrping | $wgrx2 | $wgtx2 | $wgcity$wgsincelastreset $wgcitychange$ubsync"
fi
#if a wg connection is monitored and disconnected, try to restart it
if [ "$((WG$i))" = "1" ] && [ "$wgstate" = "Disconnected" ]
then #reconnect
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: WGC$i has disconnected" >> $logfile
echo ""
printf "\33[2K\r"
#Display a standard timer#
timer=0
while [ $timer -ne 5 ]
do
timer="$((timer+1))"
preparebar 46 "|"
progressbarpause $timer 5 "" "s" "Standard"
done
printf "\33[2K\r"
restartwg $i
sendmessage 1 "WG Tunnel Disconnected" $i
restartrouting
resetspdmerlin
exec sh /jffs/scripts/vpnmon-r3.sh -noswitch
fi
#if the wg handshake exceeds 200s, try to restart it
# Inspiration from ZebMcKayHan's WGC Watchdog Script
if [ "$((WG$i))" = "1" ] && [ "$wgstate" = "Connected" ]
then
last_handshake=$(wg show wgc$i latest-handshakes | awk '{print $2}') >/dev/null 2>&1
if [ ! -z $last_handshake ]
then
idle_seconds=$((`date +%s`-${last_handshake}))
if [ "$idle_seconds" -gt "200" ]
then #reconnect
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: WGC$i handshake exceeded 200s" >> $logfile
echo ""
printf "\33[2K\r"
#Display a standard timer#
timer=0
while [ $timer -ne 5 ]
do
timer="$((timer+1))"
preparebar 46 "|"
progressbarpause $timer 5 "" "s" "Standard"
done
printf "\33[2K\r"
restartwg $i
sendmessage 1 "WG Handshake Exceeded" $i
restartrouting
resetspdmerlin
exec sh /jffs/scripts/vpnmon-r3.sh -noswitch
fi
fi
fi
if [ "$((WG$i))" = "1" ]; then
# if a wg connection ping is greater than a certain amount, restart it
maxsvrping=$(awk "BEGIN {printf \"%3.0f\", ${wgping}}") >/dev/null 2>&1
MP=$?
if [ $MP -ne 0 ]; then
if [ -z "$maxsvrping" ] || [ "$maxsvrping" = "" ]; then
maxsvrping="Null"
fi
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: WGC$i received invalid PING information. Contents: $maxsvrping" >> $logfile
maxsvrping=0
fi
else
maxsvrping=0
fi
if [ "$pingreset" -gt 0 ]
then
if [ "$maxsvrping" -ge "$pingreset" ]
then
echo ""
printf "\33[2K\r"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: WGC$i PING exceeds max allowed ($pingreset ms)" >> $logfile
printf "${CGreen}\r[Maximum PING Exceeded]"
sleep 3
printf "\33[2K\r"
#display a standard timer#
timer=0
while [ $timer -ne 5 ]
do
timer="$((timer+1))"
preparebar 46 "|"
progressbarpause $timer 5 "" "s" "Standard"
#sleep 1
done
printf "\33[2K\r"
restartwg $i
sendmessage 1 "WG Slot Exceeded Max Ping" $i
restartrouting
resetspdmerlin
exec sh /jffs/scripts/vpnmon-r3.sh -noswitch
fi
fi
#if a wg is monitored and not responsive, try to restart it
if [ "$((WG$i))" = "1" ] && [ "$resetwg" != "0" ]
then #reconnect
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: WGC$i is non-responsive and being reconnected" >> $logfile
echo ""
printf "\33[2K\r"
#display a standard timer#
timer=0
while [ $timer -ne 5 ]
do
timer="$((timer+1))"
preparebar 46 "|"
progressbarpause $timer 5 "" "s" "Standard"
#sleep 1
done
printf "\33[2K\r"
restartwg $resetwg
sendmessage 1 "WG Slot Is Non-Responsive" $resetwg
restartrouting
resetspdmerlin
exec sh /jffs/scripts/vpnmon-r3.sh -noswitch
fi
#Reset variables
wgsincelastreset=""
done
echo -e "-------|-----|--------|--------|--------------|-----------------|------------|--------|------------------------------------------"
echo ""
#-----------------
fi
#display a standard timer#
timer=0
lastTimerSec=0
updateTimer=true
getifacestats # Grab fresh interface stats
while [ "$timer" -lt "$timerloop" ]
do
if "$updateTimer"
then
updateTimer=false
timer="$((timer+1))"
lastTimerSec="$(date +%s)"
fi
preparebar 46 "|"
progressbaroverride "$timer" "$timerloop" "" "s" "Standard"
lockcheck #Check to see if a reset is currently underway
if [ "$timerreset" = "1" ]; then timer="$timerloop" ; fi
## Prevent repeatedly fast key presses from updating the timer ##
[ "$(date +%s)" -gt "$lastTimerSec" ] && updateTimer=true
done
calcifacestats # Grab new stats after the timer completes for comparison
#Check to see if a reset is currently underway
lockcheck
prevHideOpts=X
#if Unbound is active and out of sync, try to restart it
if [ "$unboundclient" != "0" ] && [ "$ResolverTimer" = "1" ]
then
if [ "$useovpn" = "1" ]
then
printf "\33[2K\r"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: VPN$unboundreset is out of sync with Unbound DNS Resolver" >> $logfile
printf "${CGreen}\r[Unbound is out of sync]"
sleep 3
printf "\33[2K\r"
#display a standard timer
timer=0
while [ $timer -ne 5 ]
do
timer="$((timer+1))"
preparebar 46 "|"
progressbarpause $timer 5 "" "s" "Standard"
done
printf "\33[2K\r"
restartvpn $unboundreset
sendmessage 1 "VPN Slot Not Synced With Unbound" $unboundreset
restartrouting
resetspdmerlin
exec sh /jffs/scripts/vpnmon-r3.sh -noswitch
fi
fi
if [ "$unboundwgclient" != "0" ] && [ "$ResolverTimer" = "1" ]
then
if [ "$usewg" = "1" ]
then
printf "\33[2K\r"
echo -e "$(date +'%b %d %Y %X') $(_GetLAN_HostName_) VPNMON-R3[$$] - WARNING: WGC$unboundreset is out of sync with Unbound DNS Resolver" >> $logfile
printf "${CGreen}\r[Unbound is out of sync]"
sleep 3
printf "\33[2K\r"
#display a standard timer
timer=0
while [ $timer -ne 5 ]
do
timer="$((timer+1))"
preparebar 46 "|"
progressbarpause $timer 5 "" "s" "Standard"
done
printf "\33[2K\r"
restartwg $unboundreset
sendmessage 1 "WG Slot Not Synced With Unbound" $unboundreset
restartrouting
resetspdmerlin
exec sh /jffs/scripts/vpnmon-r3.sh -noswitch
fi
fi
#Check to see if the WAN is up
if [ "$monitorwan" = "1" ] && [ "$bypasswancheck" = "0" ]; then
checkwan
fi
firstrun=0
done
echo -e "${CClear}"
exit 0
#} #2>&1 | tee $LOG | logger -t $(basename $0)[$$] # uncomment/comment to enable/disable debug mode