开发工具

如何循环检测所处网段主机的开关机状态?

以下是一个用于循环检测指定网段主机开关机状态的Shell脚本,支持并行扫描、结果对比和状态变化告警:

#!/bin/bash
# 网段主机状态监控脚本
# 功能:定时扫描指定网段,记录主机状态变化

# 配置参数
NETWORK="192.168.1.0/24"      # 目标网段(可修改)
CHECK_INTERVAL=300            # 检测间隔(秒)
LOG_FILE="/var/log/host_monitor.log"  # 日志文件路径
ALERT_EMAIL="admin@example.com"       # 告警邮箱
SCAN_TIMEOUT=1               # ping超时时间(秒)
MAX_CONCURRENT=50            # 最大并发数

# 初始化状态文件
STATE_FILE="/tmp/network_state.txt"
touch "$STATE_FILE"

# 获取当前时间戳
timestamp() {
  date '+%Y-%m-%d %H:%M:%S'
}

# 并行ping扫描函数
scan_network() {
  # 生成IP列表
  mapfile -t ips < <(nmap -sL -n $NETWORK | awk '/Nmap scan report/{print $NF}')
  
  # 使用fping并行检测(需安装fping)
  fping -c1 -t$((SCAN_TIMEOUT*1000)) "${ips[@]}" 2>/dev/null | \
  awk '/alive$/ {print $1}' | sort > "$STATE_FILE.new"
  
  # 或者使用原生ping(无依赖)
  # for ip in "${ips[@]}"; do
  #   (
  #     if ping -c1 -W$SCAN_TIMEOUT "$ip" &>/dev/null; then
  #       echo "$ip"
  #     fi
  #   ) &
  # done | sort > "$STATE_FILE.new"
  
  # 控制并发数
  wait
}

# 检测状态变化
check_changes() {
  local new_file="$STATE_FILE.new"
  local old_file="$STATE_FILE"
  
  # 新增上线主机
  comm -13 "$old_file" "$new_file" | while read ip; do
    echo "[$(timestamp)] 主机上线: $ip" | tee -a "$LOG_FILE"
    # 发送邮件示例
    # echo "主机 $ip 已上线" | mail -s "网络状态变化" "$ALERT_EMAIL"
  done
  
  # 新增离线主机
  comm -23 "$old_file" "$new_file" | while read ip; do
    echo "[$(timestamp)] 主机离线: $ip" | tee -a "$LOG_FILE"
  done
  
  # 更新状态文件
  mv "$new_file" "$old_file"
}

# 主循环
while true; do
  scan_network
  check_changes
  sleep $CHECK_INTERVAL
done



使用说明

1、安装依赖(可选)

# 安装fping提升扫描效率(Ubuntu/Debian)
sudo apt install fping nmap


2、配置参数

# 编辑脚本设置检测网段
NETWORK="10.0.0.0/24"    # 示例:监控10.0.0.0/24网段
CHECK_INTERVAL=600       # 每10分钟检测一次


3、启动脚本

sudo chmod +x network_monitor.sh
sudo nohup ./network_monitor.sh > /dev/null 2>&1 &


4、查看日志

tail -f /var/log/host_monitor.log



功能特性

1、高效扫描

使用fping或nmap实现并行检测

支持自定义并发数和超时时间


2、智能告警

记录主机上下线时间戳

支持邮件通知(需配置邮件服务)


3、状态对比

每次扫描结果与上次对比

仅报告状态变化的主机


4、日志示例

[2023-10-05 14:30:22] 主机上线: 192.168.1.100
[2023-10-05 14:35:22] 主机离线: 192.168.1.50



扩展功能

1、邮件告警配置

# 安装邮件服务
sudo apt install mailutils

# 在check_changes函数中取消注释邮件发送代码


2、Web界面展示

# 生成HTML状态报告
{
  echo "<html><body>"
  echo "<h2>网络状态报告</h2>"
  echo "<p>更新时间: $(timestamp)</p>"
  echo "<table border=1>"
  echo "<tr><th>IP地址</th><th>状态</th></tr>"
  while read ip; do
    echo "<tr><td>$ip</td><td style='color:green'>在线</td></tr>"
  done < "$STATE_FILE"
  comm -13 "$STATE_FILE" <(nmap -sL -n $NETWORK | awk '/Nmap scan report/{print $NF}') | \
    while read ip; do
      echo "<tr><td>$ip</td><td style='color:red'>离线</td></tr>"
    done
  echo "</table></body></html>"
} > /var/www/html/network_status.html


3、企业微信/钉钉通知

# 在check_changes函数中添加
DING_WEBHOOK="https://oapi.dingtalk.com/robot/send?access_token=xxx"
curl -s "$DING_WEBHOOK" -H 'Content-Type: application/json' -d "{
  'msgtype': 'text',
  'text': {'content': '网络状态变化:主机 $ip 已上线'}
}"


注意事项

1、权限要求

需要root权限运行(ICMP扫描需要特权)

sudo ./network_monitor.sh


2、防火墙影响

目标主机的防火墙可能阻止ping请求

可改用TCP端口扫描(需修改扫描命令):

nmap -p 22 -T5 --open -iL ip_list.txt -oG -


3、性能优化

大网段(如/16)建议使用masscan工具

masscan -p80 192.168.0.0/16 --rate=1000


通过此脚本,您可以实时掌握网络设备状态,快速定位异常主机,建议部署到内网监控服务器长期运行。