0. 前言#
分享一下如何监控某个主机上的网卡到指定 ip 的流量大小, 测试环境已安装 tcpdump 并配置了 zabbix_agent
被检测端 ip 为 1.1.1.11, 要检测到 1.1.1.12-17 这些 ip 的出口流量
大致流程为:
- 创建一个监控脚本, 分析 1 分钟内指定网卡发送到指定 ip 的数据包大小并输出到日志文件
- 将该脚本放到 crontab 中, 每分钟执行一次
- 配置 zabbix-agent
- 创建数据采集脚本, 提取日志文件中的内容
- 添加自定义配置, 创建采集的键值
- 配置 zabbix-server
- 添加监控项
- 添加触发器
- 添加仪表盘
1. 监控脚本#
添加 /opt/traffic_monitor.sh
代码语言:javascript复制#!/bin/bash
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
set -e
# 检查是否安装了tcpdump命令
if which tcpdump >/dev/null 2>&1; then
# 如果已安装,则不进行任何提示
:
else
echo "系统中未安装 tcpdump 命令,请先安装 tcpdump。"
exit 1
fi
# 检查是否有 tcpdump 残留进程
existing_tcpdump_pids=$(pgrep -f "tcpdump -i ens32 -nn dst") || true
# 检查 tcpdump 进程数量
tcpdump_count=$(echo "${existing_tcpdump_pids}" | wc -w)
if [ "$tcpdump_count" -gt 6 ]; then
# 如果数量大于 6 视为之前的进程未正确关闭, 杀死所有 tcpdump 进程
kill -9 ${existing_tcpdump_pids}
fi
IPLIST=("1.1.1.12" "1.1.1.13" "1.1.1.14" "1.1.1.15" "1.1.1.16" "1.1.1.17")
LOG_DIRECTORY=/var/log/traffic_monitor
LOG_FILE=${LOG_DIRECTORY}/traffic_monitor.log
[ -d "${LOG_DIRECTORY}" ] || mkdir -p "${LOG_DIRECTORY}"
[ -f "${LOG_FILE}" ] || touch "${LOG_FILE}"
# 获取文件大小(以字节为单位)
log_file_size=$(du -b "$LOG_FILE" | cut -f1)
# 设置100M对应的字节数
limit_size=$((100 * 1024 * 1024))
# 检查文件大小是否大于100M
if [ "$log_file_size" -gt "$limit_size" ]; then
# 清空文件
echo "" > "$LOG_FILE"
fi
start_time=$(date "%Y%m%d-%H%M%S")
for ip in "${IPLIST[@]}"; do
(
# 开始 tcpdump 抓包
output_file=/tmp/monitor-${ip}-${start_time}.output
nohup tcpdump -i ens32 -nn dst ${ip} and not icmp 2>/dev/null > ${output_file} &
# 等待 60 秒后关闭 tcpdump
tcpdump_pid=$!
sleep 60 && kill ${tcpdump_pid}
stop_time=$(date "%Y%m%d-%H%M%S")
# 分析流量大小, 以 KB 为单位
traffic_size=$(cat ${output_file} | awk -F'length ' '{print $2}' | awk '{sum =$1} END {printf "%.2f", sum / 1024}')
# 删除 tcpdump 的输出文件
rm -f ${output_file}
echo "${ip} ==== ${start_time} ----> ${stop_time} ===== (KB) ${traffic_size}" >> ${LOG_FILE}
) &
done
# 等待所有后台任务完成
wait
exit 0
放到 crontab 中
代码语言:javascript复制* * * * * /bin/bash /opt/traffic_monitor.sh >/dev/null 2>&1
日志文件应有类似如下输出
代码语言:javascript复制$ tail -12 /var/log/traffic_monitor/traffic_monitor.log
1.1.1.14 ==== 20230804-154601 ----> 20230804-154701 ===== (KB) 1964.99
1.1.1.12 ==== 20230804-154601 ----> 20230804-154701 ===== (KB) 0.23
1.1.1.17 ==== 20230804-154601 ----> 20230804-154701 ===== (KB) 1029.35
1.1.1.16 ==== 20230804-154601 ----> 20230804-154701 ===== (KB) 1029.35
1.1.1.15 ==== 20230804-154601 ----> 20230804-154701 ===== (KB) 1029.35
1.1.1.13 ==== 20230804-154601 ----> 20230804-154701 ===== (KB) 1029.35
1.1.1.12 ==== 20230804-154701 ----> 20230804-154801 ===== (KB) 1029.49
1.1.1.14 ==== 20230804-154701 ----> 20230804-154801 ===== (KB) 0.00
1.1.1.15 ==== 20230804-154701 ----> 20230804-154801 ===== (KB) 0.00
1.1.1.16 ==== 20230804-154701 ----> 20230804-154801 ===== (KB) 1029.35
1.1.1.13 ==== 20230804-154701 ----> 20230804-154801 ===== (KB) 0.00
1.1.1.17 ==== 20230804-154701 ----> 20230804-154801 ===== (KB) 3086.44
2. 配置 zabbix-agent#
添加 /opt/zabbix_traffic_monitor.sh, 根据 ip 筛选最后一个匹配项的数值
代码语言:javascript复制#!/bin/bash
LOG_DIRECTORY=/var/log/traffic_monitor
LOG_FILE=${LOG_DIRECTORY}/traffic_monitor.log
grep "$1" "${LOG_FILE}" | awk '{last_column=$NF} END {print last_column}'
添加 /etc/zabbix/zabbix_agentd.d/get_traffic_monitor.conf 配置文件
代码语言:javascript复制UserParameter=get_traffic_monitor[*],/opt/zabbix_traffic_monitor.sh $1
重启 zabbix-agent
代码语言:javascript复制systemctl restart zabbix-agent
3. 配置 zabbix-server#
创建监控项, 有几个 ip 创建几个监控项
监控项测试, 此处应有值
创建触发器, 同样的, 有几个 ip 创建几个
仪表盘添加图形
4. 测试#
找一台服务器配置多 ip
代码语言:javascript复制IPADDR=1.1.1.12
NETMASK=255.255.255.0
GATEWAY=1.1.1.254
DNS1=8.8.8.8
DNS2=114.114.114.114
IPADDR1=1.1.1.13
NETMASK1=255.255.255.0
IPADDR2=1.1.1.14
NETMASK2=255.255.255.0
IPADDR3=1.1.1.15
NETMASK3=255.255.255.0
IPADDR4=1.1.1.16
NETMASK4=255.255.255.0
IPADDR5=1.1.1.17
NETMASK5=255.255.255.0
重启 network
配置 1.1.1.11 到 1.1.1.12-17 的免密登录
代码语言:javascript复制ssh-keygen
ssh-copy-id root@1.1.1.12
# 每个 ip 都 ssh 一下, 添加一下 hotkey
ssh root@1.1.1.13
ssh root@1.1.1.14
ssh root@1.1.1.15
ssh root@1.1.1.16
ssh root@1.1.1.17
运行一个脚本模拟网络流量
代码语言:javascript复制#!/bin/bash
# 设置目标IP地址列表
ip_list=("1.1.1.12" "1.1.1.13" "1.1.1.14" "1.1.1.15" "1.1.1.16" "1.1.1.17")
dd if=/dev/zero of=/tmp/test bs=1M count=1
while true; do
# 生成一个随机数,范围为 0 到 5
random_index=$((RANDOM % 6))
# 随机选择一个IP
target_ip="${ip_list[random_index]}"
echo ${target_ip}
/usr/bin/scp /tmp/test root@${target_ip}:/tmp/
# 等待10秒
sleep 10
done
运行脚本, 应有如下输出
过段时间后查看仪表盘, 能看到流量数据
触发器也应正常工作
以上