如何实现base shell监控网络设备?
- By : Will
- Category : Debian-Like
1 前言
一个问题,一篇文章,一出故事。
笔者家里有一堆网络设备,如果使用Zabbix监控貌似有点大材小用,于是决定写一个监控脚本解决此问题。
2 最佳实践
2.1 设置邮件推送
2.2 设置免密码登录路由
2.3 创建监视脚本
vim ~/scripts/monitorHosts.sh
加入如下配置,
#!/bin/bash
routerAddress="192.168.0.1"
routerUser="admin"
routerKey="/home/will/.ssh/id_rsa"
monitorHosts="EZVIZ"
monitorAddress="192.168.0.1 192.168.0.250"
monitorHostAlias="/etc/monitorHostAlias.conf"
monitorHistoryLog="/var/log/monitorHistory.log"
monitorStatusLog="/var/log/monitorStatus.log"
mailFrom="will@cmdschool.org"
mailTo="tanzhenchao@qq.com"
mailHost="smtp.exmail.qq.com"
mailPort="465"
mailSubject="Host Status Alert"
mailBody=""
dataTime="$(date +'%Y-%m-%d %H:%M:%S')"
autocmd() {
cmd="$1"
sshInfo=$(ssh -n -o ConnectTimeout=10 -o PubkeyAcceptedAlgorithms=+ssh-rsa -i "$routerKey" "$routerUser"@"$routerAddress" "$cmd")
echo "$sshInfo"
}
getRouterHostAddress() {
hostname="$1"
hostAddress=$(autocmd "/ip dhcp-server lease print where host-name~\"$hostname\"" | grep -E '^[[:space:]]*[0-9]' | awk -F' ' '{print $3}')
echo "$hostAddress"
}
isPingReachable() {
address=$1
if ping -c 3 -W 1 "$address" &> /dev/null; then
return 0
else
return 1
fi
}
isRouterPingReachable() {
address=$1
pingSum=$(autocmd "/ping count=3 $address" | grep "packet-loss=100%" | wc -l)
if [[ $pingSum -eq 0 ]]; then
return 0
else
return 1
fi
}
isConnectionReachable() {
address=$1
connectionSum=$(autocmd "/ip firewall connection print where src-address~\"$address\" and (orig-rate>0 or repl-rate>0)" | grep -E '^[[:space:]]*[0-9]' | wc -l)
if [[ $connectionSum -gt 0 ]]; then
return 0
else
return 1
fi
}
isMacReachable() {
address=$1
macSum=$(autocmd "/ip arp print where address=\"$address\" and complete" | grep -E '^[[:space:]]*[0-9]' | grep -E '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | wc -l)
if [[ $macSum -gt 0 ]]; then
return 0
else
return 1
fi
}
for host in $monitorHosts; do
for address in $(getRouterHostAddress "$host"); do
if [ "$address" == "" ]; then
continue
fi
if echo "$monitorAddress" | grep -q "$address"; then
continue
fi
monitorAddress="$monitorAddress $address"
done
done
sendMail="false"
count=0
for address in $monitorAddress; do
if isPingReachable "$address"; then
addressStatus="online"
elif isRouterPingReachable "$address"; then
addressStatus="online"
elif isConnectionReachable "$address"; then
addressStatus="online"
elif isMacReachable "$address"; then
addressStatus="online"
else
addressStatus="offline"
fi
flage="K"
hostAlias=$(grep "$address" "$monitorHostAlias" | awk -F' ' '{print $2}')
if [[ -z "$hostAlias" ]]; then
hostAlias="NULL"
fi
lastHistoryLog=$(grep -F "$address" "$monitorHistoryLog" 2>/dev/null | tail -n 1)
lastHistoryLogMessage=$(echo "$lastHistoryLog" | awk '{$1=$2=""; print substr($0,3)}')
lastHistoryStatus=$(echo "$lastHistoryLogMessage" | awk -F' ' '{print $2}')
message="$address $addressStatus"
echo "$dataTime $message" >> "$monitorHistoryLog"
lastStatusLog=$(grep -F "$address" "$monitorStatusLog" 2>/dev/null | tail -n 1)
if [[ "$lastStatusLog" == "" ]]; then
echo "$lastHistoryLog" >> "$monitorStatusLog"
fi
last3HistoryLog=$(grep -F "$address" "$monitorHistoryLog" 2>/dev/null | tail -n 3)
last3HistoryMessage=$(echo "$last3HistoryLog" | awk '{$1=$2=""; print substr($0,3)}')
if [[ $(echo "$last3HistoryMessage" | wc -l) -eq 3 ]]; then
onlineMsg=$(echo "$last3HistoryMessage" | grep online)
offlineMsg=$(echo "$last3HistoryMessage" | grep offline)
if [[ $(echo "$onlineMsg" | wc -l) -gt $(echo "$offlineMsg" | wc -l) ]]; then
countStatus="online"
else
countStatus="offline"
fi
lastStatusLog=$(grep -F "$address" "$monitorStatusLog" 2>/dev/null | tail -n 1)
lastStatusMeg=$(echo "$lastStatusLog" | awk '{$1=$2=""; print substr($0,3)}')
lastStatus=$(echo "$lastStatusMeg" | awk -F' ' '{print $2}')
if [[ "$countStatus" != "$lastStatus" ]]; then
if [[ -z "$lastHistoryLogMessage" ]]; then
flage="A"
else
flage="U"
fi
sendMail="true"
echo "$last3HistoryLog" | grep "$countStatus" | tail -n 1 >> "$monitorStatusLog"
fi
fi
if [ $count -eq 0 ]; then
mailBody="Flags: A - Add, U - Update, K - Keep"
mailBody="$mailBody\n\n # ADDRESS STATUS ALIAS"
fi
mailBody="$mailBody\n $count $flage $address $addressStatus $hostAlias"
((count++))
done
if [[ "$sendMail" == "true" ]]; then
echo -e "$mailBody" | s-nail -s "$mailSubject $dataTime" -r "$mailFrom" \
-S "mta=smtp://$mailHost:$mailPort" -S "charset=UTF-8" -S "content-type=text/plain" "$mailTo"
fi
需要注意的是,
– 函数“autocmd”用于自动登录路由并执行命令
– 函数“isPingReachable”ping检查IP地址连通性,返回0表示用户ping通即在线,返回1表示用户不能ping通即不在线。
– 函数“isRouterPingReachable”通过路由ping检查IP地址连通性,返回0表示用户ping通即在线,返回1表示用户不能ping通即不在线。
– 函数“isConnectionReachable”检查IP地址的连接数,返回0表示用户有连接且即在线,返回1表示用户无连接即不在线。
– 函数“isMacReachable”检查arp列表中的MAC地址是否活跃,返回0表示用户有连接且即在线,返回1表示用户无连接即不在线。
– 函数“getRouterHostAddress”用于登录路由并获取host-name对应的IP Address
– 循环“for host in $monitorHosts; do”逐个从变量monitorHosts取得IP地址并与变量monitorAddress中的IP地址合并。
– 循环“for address in $monitorAddress; do”逐个检查变量monitorAddress中的地址状态并创建日志和生成邮件主体。
– 命令s-nail向用户推送设备变更通知的邮件
2.4 设置设备别名
cat /etc/monitorHostAlias.conf
加入如下配置,
192.168.0.1 route 192.168.0.250 ser 192.168.0.254 EZVIZ 192.168.0.253 EZVIZ 192.168.0.252 EZVIZ 192.168.0.245 EZVIZ
2.5 测试脚本
bash ~/scripts/monitorHosts.sh
2.6 设置自动执行
crontab -e
加入如下配置,
*/3 * * * * bash ~/scripts/monitorHosts.sh
参阅文档
====================
没有评论