2

I have two different internet connections on my house (from two different ISPs). And I use a TP-Link ER605 Multi-Wan router to manage both connections and deliver a single internet connection to my wired home network.

Network Diagram

This router has a single job: When the main connection goes down, it redirects all the traffic to the backup connection, and I just don't notice any outage at all when it happens.

The thing is: I would like to get some kind of notification when my main connection is not working so I can check if something is wrong on my end, and if this situation persists for some time, I can call my ISP to ask for technical support.

I can use "traceroute" (on Linux) or "tracert" (on Windows) to trace the route between a computer on my network and the Google Public DNS (8.8.8.8) to determine which Internet connection I'm using.

Windows tracert

tracert -h 2 -4 -d 8.8.8.8

Linux traceroute

traceroute -4 -n -m 2 8.8.8.8

If the second hop is 192.168.15.1, it means that my router is using the main connection to get to the Internet, but if the IP address is 192.168.0.1, it means that the main connection is offline and router is redirecting the traffic over the backup connection. (On this specific case, it's on the third hop on the linux example, because it's a VM on another NAT network).

The problem is: I don't know how to automate that verification, and get some kind of notification depending on which connection is in use. It could be an e-mail like "Main connection is down" and "Main connection restored".

I have my Laptop running Windows 10 running 24/7 and I also have a Raspberry Pi (with Raspian Linux) that I could just leave connected all the time for this specific task. So both Windows and Linux solutions would work for me.

9
  • The fact that the router doesn't manage that is a big dealbreaker. You want to duplicate the router's monitoring functionality but off the router? Merely determining what constitutes up or down is complex. FYI the router supports syslog upload which you could use to create email notification locally, but from a cursory read, users report it to be GIGO. It is a more simple matter to detect the WAN IP switchover using a local script (icanhazip.com)or dyndns client.
    – Blindspots
    Commented Aug 2, 2022 at 22:16
  • Thanks for replying @BlindSpots. A simple way I can imagine (for checking which connection is in use) is by running tracert -d -h 2 -4 8.8.8.8 (on Windows) or traceroute -4 -n -m 2 8.8.8.8 (on Linux). It'll return the IP address of the modem used to reach the internet. If it's 192.168.15.1 I know the main link is in use, but if it's 192.168.0.1, I know the main connection is down and the backup connection is in use. I just don't know how to automate this verifications and get notifications for that. Commented Aug 5, 2022 at 23:18
  • You have at least two ways already. Mine and yours. You should edit your question to focus in on the actual problem which is how to run that from a script and parse the result and send an email based on the change. Be as clear as possible and let us know what you have done and what you don't know how to do. OS involved. Your knowledge of scripting etc.
    – Blindspots
    Commented Aug 8, 2022 at 17:34
  • Alright @BlindSpots, thanks for the feedback. I just edited the question. Thank you for taking the time to watch over my problem. Commented Aug 9, 2022 at 18:40
  • About your first comment @BlindSpots, It's a gigabit multi-wan router that works fine and I paid 50 USD. It works fine for it's price. I don't know exactly how can it determine if a connection is down or not. It has 3 settings for that: "Automatic", "Ping" and "DNS". I just leave it in "Automatic" and it works just fine. It in fact has SYSLOG functionality, but unfortunately it doesn't has any event when it switches the connections or when it detects a connection is down or up. Commented Aug 9, 2022 at 18:54

1 Answer 1

0

Bash Script to Monitor WAN

This script will write to a log file. You can add or substitute a function to integrate sendmail from a command line. I would recommend that as an additional separate forum question. You will likely want to have some number of lines from the logs to attach to any email you ultimately send yourself.

  1. Script will run continuously until killed
  2. Script writes to a log file only when the connection changes (UP/DOWN).
  3. At startup if both connections are down that will be logged.
  4. Log file is created in the same directory as the script.
  5. Log file follows script name but with a .log extension.
  6. New log file entries are written above old ones.
  7. Script will log when a connection comes UP.
  8. Script will log if that connection goes DOWN.
  9. Script will check a connection is still UP every x seconds (currently 5).
  10. If both connections are DOWN script will check for UP every x seconds (currently 5).
  11. Remember when creating the bash script to make it executable (chmod +x file.sh)
  12. You can uncomment line 47 if you want to simulate your connection dropping after x successful tests (currently 5)
  13. To maintain log entry column alignment, when populating 'isp[]' and 'state[]' pad shorter strings so the values in the same array have the same character lengths (e.g. 'Vivo ' 'Claro' instead of 'Vivo' 'Claro').
  14. If you need to debug to console, add the option '-x' at the end of the first line ('#!/bin/bash -x')
  15. Lots of other posts were adapted for this script, I'll need to reference some of them later.
#!/bin/bash

host='8.8.8.8'
wanip=('192.168.15.1' '192.168.0.1')
isp=('Vivo ' 'Claro')
state=('UP  ' 'DOWN')

scriptpath="$(realpath "${BASH_SOURCE[-1]}")"
scriptdir="$(dirname "$scriptpath")"
logfile="$scriptdir/$(basename "${scriptpath##*/}" .sh).log"
len="${#wanip[@]}"
touch "$logfile"

function addtolog () {
  dates="$(date '+%s')"
  datel="$(date -d@"$dates" '+%Y-%m-%d %T')"
  logentry="$dates: $datel  ${isp[$1]} ${state[$2]} ${wanip[$1]}"

  echo "$logentry" | cat - "$logfile" > "$dates" \
    && mv -f "$dates" "$logfile"
}

function tracert () {
  arr=("$@")
  for i in "${arr[@]}"
  do
    traceroute -n "$host" | \
      grep -F -f <(printf "%s\n" "$i") \
      >/dev/null 2>&1
    (( "$?" == 0 )) && return 0;
}

if ! (tracert "${wanip[@]}"); then
  for (( i=0; i<len; i++ ))
  do
    addtolog "${i}" 1
  done
fi

while :
do
  if (tracert "${wanip[@]}"); then
    for (( i=0; i<len; i++ ))
    do
      c='1'
      while (tracert "${wanip[i]}")
      do
        (( c < 2 )) && addtolog "${i}" 0
        c=$(( c + 1 ))
        sleep 5
#        (( c > 4 )) && echo "Simulating Dropped Connection" && break
      done

      addtolog "${i}" 1
    done

  else sleep 5; fi
done

NB

While I tested the code and tried to focus on your use case, please note that I am not, by any stretch, qualified to be writing code for anyone, am not properly trained, and have likely broken more best practices than I know while coding this.

3
  • Thanks for taking the time to answer my question. I tested your script and it works... But not so well. It writes to a log file instead of sending me an email. Also, it writes two lines to the log file before actually testing the connections (Vivo DOWN, Claro DOWN, Vivo UP). Also, looks like it writes the log backwards (newer line always on top of the file)... Which is odd. But It's a good starting point. I will just add an wget call to a email sender API and I think it'll be perfect for me. Commented Aug 12, 2022 at 22:34
  • Per my note #6 in the answer: "New log file entries are written above old ones." When I open a log file I want to see the most relevant/recent entries at the top, not go to the end of a file and work backwards.
    – Blindspots
    Commented Aug 16, 2022 at 22:33
  • Per your note that you were getting two DOWNs on script start. I have now modified the function tracert to accept data in an array (Bash syntax) and updated the code in the answer. Good catch. Solution courtesy of user A.B. in this answer from 2015: "How to pass an array as function argument? askubuntu.com/a/674347/1021186"
    – Blindspots
    Commented Aug 16, 2022 at 23:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .