如何修复脚本以准确检测eth1网络接口对应的ISP连接故障
如何修复脚本以准确检测eth1网络接口对应的ISP连接故障
这个问题我之前也碰到过!traceroute的退出码坑就坑在它只告诉你自己能不能正常发送探测包,而不是有没有成功到达目标主机。你现在的情况是,外部路由器挂了,但服务器还能把traceroute的包发出去(所以退出码是0),但收不到任何响应,导致脚本没触发告警。给你几个实用的修复方案:
方案一:检查traceroute输出是否到达目标主机
既然traceroute的退出码不靠谱,我们直接看它的输出结果——如果成功到达目标,输出里一定会出现$isp2_tracehost的IP。我们可以用grep来检测这一点:
/usr/sbin/traceroute -4 -n -m 4 -i $isp2_if -s $isp2_ip $isp2_tracehost > $output 2>&1 # 检查输出中是否包含目标IP,没找到就触发告警 if ! grep -q "$isp2_tracehost" "$output"; then logger -s -t "$0" -p daemon.crit "ISP2 unreachable on $isp2_if" fi
这种方法的好处是能准确判断是否真的连到了ISP的目标主机,哪怕中间跳有超时也没关系(毕竟偶尔中间节点丢包是正常的)。
方案二:直接检测路由器连通性
因为ISP2是通过外部路由器上网的,路由器挂了的话,第一步就会连不上。你可以先ping路由器的内网IP(比如你例子里的192.168.1.1),如果连路由器都不通,那肯定是故障了:
# 先定义ISP2路由器的内网IP isp2_router="192.168.1.1" # 发送2个探测包,超时1秒 ping -I $isp2_if -c 2 -W 1 $isp2_router > /dev/null 2>&1 || { logger -s -t "$0" -p daemon.crit "ISP2 router unreachable on $isp2_if" }
这种方法更直接,毕竟路由器是你能控制的节点,检测它的连通性比检测外部主机更可靠,也更快。
方案三:改用ping代替traceroute
如果你的需求只是检测连通性,不需要追踪路径,ping的退出码会更靠谱——只要没收到响应,ping就会返回非0值:
# 发送3个探测包,每个包超时2秒,绑定到eth1接口 ping -I $isp2_if -c 3 -W 2 $isp2_tracehost > $output 2>&1 || { logger -s -t "$0" -p daemon.crit "ISP2 unreachable on $isp2_if" }
不过要注意,有些ISP可能会过滤ICMP(ping用的协议),如果出现误报,可以微调ping的参数(比如增加探测次数),或者回到方案一。
额外优化建议
- 可以给traceroute加
-w 1参数,减少每个跳的等待时间,让脚本执行更快; - 如果脚本要静默运行,可以把
$output设为/dev/null,避免生成无用日志; - 可以在告警里加上当前时间,方便排查问题,比如
logger ... "ISP2 unreachable on $isp2_if at $(date)"
备注:内容来源于stack exchange,提问作者Ale
相关产品推荐
相关产品推荐

