我家里有两个不同的互联网连接(来自两个不同的 ISP)。我使用 TP-Link ER605 Multi-Wan 路由器来管理这两个连接,并为我的有线家庭网络提供单一互联网连接。
该路由器只有一个任务:当主连接中断时,它会将所有流量重定向到备份连接,而当这种情况发生时,我根本没有注意到任何中断。
问题是:当我的主连接无法工作时,我希望收到某种通知,以便我可以检查我这边是否有问题,如果这种情况持续一段时间,我可以致电我的 ISP 寻求技术支持。
我可以使用“traceroute”(在 Linux 上)或“tracert”(在 Windows 上)来跟踪我的网络上的计算机和 Google 公共 DNS()之间的路由,8.8.8.8
以确定我正在使用哪个互联网连接。
tracert -h 2 -4 -d 8.8.8.8
traceroute -4 -n -m 2 8.8.8.8
如果第二跳是192.168.15.1
,则意味着我的路由器正在使用主连接访问互联网,但如果 IP 地址是192.168.0.1
,则意味着主连接处于离线状态,路由器正在通过备份连接重定向流量。(在这个特定情况下,它位于 Linux 示例的第三跳上,因为它是另一个 NAT 网络上的 VM)。
问题是:我不知道如何自动执行该验证,并根据正在使用的连接获取某种通知。它可能是一封电子邮件,例如“主连接已关闭”和“主连接已恢复”。
我的笔记本电脑运行 Windows 10,全天候运行,我还有一个 Raspberry Pi(装有 Raspian Linux),我可以一直保持连接状态以完成这项特定任务。因此,Windows 和 Linux 解决方案都适合我。
答案1
用于监控 WAN 的 Bash 脚本
此脚本将写入日志文件。您可以添加或替换一个函数以从命令行集成 sendmail。我建议将其作为额外的单独论坛问题。您可能希望将日志中的一些行附加到您最终发送给自己的任何电子邮件中。
- 脚本将持续运行,直到被终止
- 仅当连接发生变化(UP/DOWN)时,脚本才会写入日志文件。
- 启动时,如果两个连接都断开,则会记录下来。
- 日志文件与脚本创建在同一目录中。
- 日志文件遵循脚本名称,但带有 .log 扩展名。
- 新的日志文件条目写在旧条目上方。
- 当连接建立时,脚本将会记录。
- 如果该连接中断,脚本将会记录。
- 脚本将每 x 秒检查一次连接是否仍然处于开启状态(当前为 5 秒)。
- 如果两个连接都处于 DOWN 状态,脚本将每 x 秒(当前为 5 秒)检查一次是否处于 UP 状态。
- 记住创建 bash 脚本时使其可执行(chmod +x file.sh)
- 如果您想在 x 次成功测试(当前为 5 次)后模拟连接断开,可以取消注释第 47 行
- 为了保持日志条目列对齐,在填充“isp[]”和“state[]”时填充较短的字符串,以便同一数组中的值具有相同的字符长度(例如“Vivo”“Claro”而不是“Vivo”“Claro”)。
- 如果需要调试到控制台,请在第一行末尾添加选项“-x”(“#!/bin/bash -x”)
- 许多其他帖子都针对此脚本进行了改编,稍后我需要参考其中的一些。
#!/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
注意:
虽然我测试了代码并试图专注于您的用例,但请注意,我绝对没有资格为任何人编写代码,没有经过适当的培训,并且在编写代码时可能违反了比我所知道的更多的最佳实践。