统计网卡流出比流入高于2倍发出告警
#!/bin/bash
# Function: 统计网卡流出比流入高于2倍发出告警
# auth: meldoyding 2025-3-13
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
source /root/.bash_profile
FILE_DIR="$(cd $(dirname $(readlink -f $0))/ && pwd)"
LOGFILE="$FILE_DIR/net.log"
ECHOLOGFILE="$FILE_DIR/warn.log"
> ${ECHOLOGFILE}.tmp
time="`date +"%Y_%m_%d_%H_%M_%S %s"`"
link="$(ip -o link | grep -v lo | awk '{print $2}' | sed 's/://g' | paste -s -d ' ')"
for i in `echo $link`;
do
cat /proc/net/dev | awk -vtime="$time" -vlink=$i '$0 ~ link{rx=$2;tx=$10;} END{print time,link,rx,tx}' >> $LOGFILE
sleep 60
time="`date +"%Y_%m_%d_%H_%M_%S %s"`"
cat /proc/net/dev | awk -vtime="$time" -vlink=$i '$0 ~ link{rx=$2;tx=$10;} END{print time,link,rx,tx}' >> $LOGFILE
tail -n 2 $LOGFILE | paste -s -d ' ' | awk '{
# 提取两个时间点的数据
time1 = $1;
timestamp1 = $2;
interface1 = $3;
rx1 = $4;
tx1 = $5;
time2 = $6;
timestamp2 = $7;
interface2 = $8;
rx2 = $9;
tx2 = $10;
# 计算流入和流出差值
rx_diff = rx2 - rx1;
tx_diff = tx2 - tx1;
# 计算流出与流入的比例
tx_rx_ratio = (rx_diff > 0) ? tx_diff / rx_diff : 0;
# 只有当流出大于流入两倍时才输出
if (tx_diff > 2 * rx_diff) {
# 计算总流量
total_traffic = rx_diff + tx_diff;
# 计算流入流出比例
rx_percentage = (rx_diff / total_traffic) * 100;
tx_percentage = (tx_diff / total_traffic) * 100;
# 输出结果
printf "时间段: %s (%s) 到 %s (%s)\n", time1, timestamp1, time2, timestamp2;
printf "接口: %s\n", interface1;
printf "流入增量: %d 字节 (%.2f MB) (%.2f%%)\n", rx_diff, rx_diff/1024/1024, rx_percentage;
printf "流出增量: %d 字节 (%.2f MB) (%.2f%%)\n", tx_diff, tx_diff/1024/1024, tx_percentage;
printf "总流量增量: %d 字节 (%.2f MB)\n", total_traffic, total_traffic/1024/1024;
printf "流出/流入比例: %.2f\n", tx_rx_ratio;
printf "警告: 流出流量超过流入流量的两倍!\n";
}
}'
done >> ${ECHOLOGFILE}.tmp
[ -s ${ECHOLOGFILE}.tmp ] && { cat ${ECHOLOGFILE}.tmp >> $ECHOLOGFILE; exit 99; } || exit 0
统计网卡流出比流入高于2倍发出告警+AI优化
#!/bin/bash
# Function: 监控网卡流出流量是否超过流入流量的2倍,并发出告警
# Author: dingdd ai 2025-3-13
# Modified: dingdd 2025-3-17 ①调整为获取当前时间的流量及上一个采集时间的流量做对比,不做等待; ②增加多网卡分析
# 设置环境变量
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
source /root/.bash_profile
# 目录和文件定义
SCRIPT_DIR="$(cd $(dirname $(readlink -f $0))/ && pwd)"
LOG_FILE="${SCRIPT_DIR}/net.log"
WARN_FILE="${SCRIPT_DIR}/warn.log"
TEMP_WARN="${WARN_FILE}.tmp"
#MONITOR_INTERVAL=60 # 监控间隔,单位:秒
# 清空临时文件
> "${TEMP_WARN}"
# 定义日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# 定义告警函数
warn() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "${TEMP_WARN}"
}
# 获取所有网络接口(排除lo接口)
get_interfaces() {
ip -o link | grep -v lo | awk '{print $2}' | sed 's/://g'
}
# 获取指定接口的流量数据
get_interface_traffic() {
local interface="$1"
local timestamp="$(date +"%Y_%m_%d_%H_%M_%S %s")"
cat /proc/net/dev | awk -v time="$timestamp" -v link="$interface" \
'$0 ~ link {rx=$2; tx=$10;} END {print time, link, rx, tx}' >> "$LOG_FILE"
#echo "$timestamp"
}
# 分析流量数据并检测异常
analyze_traffic() {
local interface="$1"
# 根据对应网口做数据分析
tail -n 100 "$LOG_FILE" | grep " $interface " | tail -n 2 | paste -s -d ' ' | awk '{
# 提取两个时间点的数据
time1 = $1;
timestamp1 = $2;
interface1 = $3;
rx1 = $4;
tx1 = $5;
time2 = $6;
timestamp2 = $7;
interface2 = $8;
rx2 = $9;
tx2 = $10;
# 计算流入和流出差值
rx_diff = rx2 - rx1;
tx_diff = tx2 - tx1;
# 防止除零错误
if (rx_diff <= 0) {
if (tx_diff > 0) {
# 只有流出没有流入,肯定告警
ratio = 999999;
} else {
# 无流量或异常情况
ratio = 0;
exit;
}
} else {
ratio = tx_diff / rx_diff;
}
# 只有当流出大于流入两倍时才输出
if (tx_diff > 2 * rx_diff) {
# 计算总流量
total_traffic = rx_diff + tx_diff;
# 计算流入流出比例
rx_percentage = (rx_diff / total_traffic) * 100;
tx_percentage = (tx_diff / total_traffic) * 100;
# 输出结果
printf "时间段: %s (%s) 到 %s (%s)\n", time1, timestamp1, time2, timestamp2;
printf "接口: %s\n", interface1;
printf "流入增量: %d 字节 (%.2f MB) (%.2f%%)\n", rx_diff, rx_diff/1024/1024, rx_percentage;
printf "流出增量: %d 字节 (%.2f MB) (%.2f%%)\n", tx_diff, tx_diff/1024/1024, tx_percentage;
printf "总流量增量: %d 字节 (%.2f MB)\n", total_traffic, total_traffic/1024/1024;
printf "流出/流入比例: %.2f\n", ratio;
printf "警告: 流出流量超过流入流量的两倍!\n";
}
}'
}
# 主程序
main() {
#log "开始网络流量监控"
# 获取所有网络接口
interfaces=$(get_interfaces)
for interface in $interfaces; do
#log "监控接口: $interface"
# 第一次获取流量数据
get_interface_traffic "$interface"
# 等待监控间隔
#sleep "$MONITOR_INTERVAL"
# 第二次获取流量数据
#get_interface_traffic "$interface"
# 分析流量数据
analyze_traffic "$interface" >> "${TEMP_WARN}"
done
# 检查是否有告警
if [ -s "${TEMP_WARN}" ]; then
cat "${TEMP_WARN}" >> "$WARN_FILE"
log "检测到异常流量,已记录告警信息"
cat "${TEMP_WARN}"
exit 99
else
#log "未检测到异常流量"
exit 0
fi
}
# 执行主程序
main
网卡达到一定流量开启网卡抓包
#!/bin/bash
# 网络流量监控脚本
# 监控指定接口的接收流量,当超过阈值时捕获数据包
# 配置参数
INTERFACE="eth0"
SLEEP_INTERVAL=10 # 监控间隔,单位:秒
THRESHOLD=30 # 流量阈值,单位:Mbps
PCAP_COUNT=100000 # 捕获的数据包数量
PCAP_DIR="/tmp/zhuabao" # PCAP文件保存目录
LOG_FILE="/var/log/traffic_monitor.log" # 日志文件
# 确保保存目录存在
mkdir -p "$PCAP_DIR"
# 日志函数
log() {
echo "$(date "+%Y-%m-%d %H:%M:%S") - $1" | tee -a "$LOG_FILE"
}
# 获取接收字节数
get_rx_bytes() {
# 首先尝试新版 ifconfig 格式
rx=$(ifconfig "$INTERFACE" 2>/dev/null | grep -oP 'RX packets \d+ bytes \d+' | grep -oP 'bytes \d+' | awk '{print $2}')
# 如果上面失败,尝试旧版 ifconfig 格式
if [ -z "$rx" ] || ! [[ "$rx" =~ ^[0-9]+$ ]]; then
rx=$(ifconfig "$INTERFACE" 2>/dev/null | grep 'RX bytes' | awk -F: '{print $2}' | awk '{print $1}')
fi
# 如果还是失败,尝试最后一种可能的格式
if [ -z "$rx" ] || ! [[ "$rx" =~ ^[0-9]+$ ]]; then
rx=$(ifconfig "$INTERFACE" 2>/dev/null | grep 'RX packets' | awk '{print $5}')
fi
# 如果还是获取失败,尝试通过 /proc/net/dev 获取
if [ -z "$rx" ] || ! [[ "$rx" =~ ^[0-9]+$ ]]; then
rx=$(cat /proc/net/dev | grep "$INTERFACE" | awk '{print $2}')
fi
echo "$rx"
}
log "开始监控网络接口 $INTERFACE 的流量"
while true
do
# 获取初始接收字节数
rx1=$(get_rx_bytes)
# 检查接收字节数是否有效
if [ -z "$rx1" ] || ! [[ "$rx1" =~ ^[0-9]+$ ]]; then
log "错误: 无法获取接口 $INTERFACE 的接收字节数"
sleep "$SLEEP_INTERVAL"
continue
fi
# 等待指定时间
sleep "$SLEEP_INTERVAL"
# 获取当前接收字节数
rx2=$(get_rx_bytes)
# 检查当前接收字节数是否有效
if [ -z "$rx2" ] || ! [[ "$rx2" =~ ^[0-9]+$ ]]; then
log "错误: 无法获取接口 $INTERFACE 的当前接收字节数"
continue
fi
# 计算流量
flow=$((rx2 - rx1))
# 如果流量为负数(可能是计数器重置)
if [ "$flow" -lt 0 ]; then
log "警告: 检测到流量计数器可能已重置"
continue
fi
# 计算Mbps (兆比特每秒)
# flow (bytes) / 1024 / 1024 * 8 / interval = Mbps
rx_mbps=$(echo "scale=2; $flow / 1048576 * 8 / $SLEEP_INTERVAL" | bc)
log "当前流量: $rx_mbps Mbps"
# 检查是否超过阈值
if (( $(echo "$rx_mbps > $THRESHOLD" | bc -l) )); then
timestamp=$(date "+%Y-%m-%d-%H-%M-%S")
filename="${timestamp}-${INTERFACE}.pcap"
log "流量超过阈值 $THRESHOLD Mbps! 开始捕获数据包..."
# 执行tcpdump捕获
/usr/sbin/tcpdump -i "$INTERFACE" -c "$PCAP_COUNT" -w "$PCAP_DIR/$filename" &
tcpdump_pid=$!
# 等待tcpdump完成或设置超时
wait $tcpdump_pid
log "数据包捕获完成,保存为 $PCAP_DIR/$filename"
# 可选:压缩PCAP文件以节省空间
# gzip "$PCAP_DIR/$filename"
# log "文件已压缩为 $PCAP_DIR/$filename.gz"
fi
# 可选:清理旧文件(保留最近7天的)
find "$PCAP_DIR" -name "*.pcap" -mtime +7 -delete 2>/dev/null
done
0