我的服务器带宽被“偷”了,于是我写了个脚本来抓现行

我的服务器带宽被"偷"了,于是我写了个脚本来抓现行

前言:总有"内鬼"在搞事情

不知道你有没有遇到过这种糟心事:服务器跑得好好的,突然就卡得不行,一查监控,好家伙,出站带宽瞬间被拉满,直冲 50MB/s! 等你手忙脚乱地登上服务器,想用 iftop 看看到底是哪个孙子在搞事时,流量又"嗖"地一下没了,恢复正常。 这种瞬时高峰,就像个幽灵,想抓个现行比登天还难。手动守着?不可能,咱又不是没有生活。 行吧,既然你玩阴的,那我就写个脚本,24小时盯着你,看你能躲到几时!

目标:自动抓贼,还得留证据

我的需求很简单:

  1. 盯着服务器的出站流量。
  2. 一旦超过我设定的线(比如 30MB/s),立刻报警!
  3. 最重要的是,把当时是哪个内网IP、哪个端口在疯狂"偷流量"给我记下来,形成铁证!
  4. 脚本得靠谱,能一直在后台默默干活。

第一次踩坑:脚本是个"睁眼瞎"

很快,第一版脚本就写好了。思路很简单:每秒读一下系统网卡的总发送字节数,算个差值,不就知道速度了吗?

bash 复制代码
# 伪代码
last_bytes = 读取网卡字节数()
sleep(1)
this_bytes = 读取网卡字节数()
speed = (this_bytes - last_bytes) / 1024 / 1024 # MB/s

结果一运行,傻眼了。iftop 明明显示 50MB,我的脚本却固执地显示 0.00 MB/s为啥? 后来才想明白,bash 默认是个整数选手,小于 1 的数它直接给你抹零!比如 0.8,它直接告诉你 0。真是个实诚的孩子。 解决办法 :找个会算小数的工具。awk 就很棒。

bash 复制代码
# 用 awk 来算小数
TX_MBPS=$(awk "BEGIN {printf \"%.2f\", ($CURRENT_TX_BYTES - $LAST_TX_BYTES) / 1024 / 1024}")

第二次踩坑:只报警,不留证

修复了计算问题,脚本总算能喊"抓贼"了!每次流量一超,它就老老实实地打印 "HIGH TRAFFIC DETECTED!"。 但是......证据呢?说好的日志文件呢?我跑去日志目录一看,文件是创建了,但里面空空如也,干净得像张白纸。 这就离谱了,贼都喊抓住了,现场记录(iftop 的输出)去哪了? 后来琢磨半天,发现是 iftop 在后台运行时,它的输出重定向有点"个性",用 > 这个符号愣是抓不住它。 解决办法 :换个方式请君入瓮。不用 > 了,直接把 iftop 扔到后台跑,然后用 wait 命令在门口等着它跑完,这样它的所有输出就都能被 nohup 抓到了。

bash 复制代码
# 让 iftop 在后台跑,等它跑完
iftop ... &
IFTOP_PID=$!
wait $IFTOP_PID

最终版:一个完美的"监控摄像头"

经过两次踩坑,最终版的脚本终于成型了。它现在非常完美:

  • 平时静默:没贼的时候,它一句话不说,绝不刷屏。
  • 贼来报警:流量一超,立刻打印带时间戳的警报。
  • 全程录像iftop 的输出直接塞进日志,贼的IP、端口、速度,一清二楚。
  • 统一管理:所有日志都记在一个文件里,查起来方便。

终极脚本代码

bash 复制代码
#!/bin/bash
# --- 配置区 ---
INTERFACE="eth0"              # 监控的网卡
INTERNAL_NET="10.9.0.0/16"     # 内网网段
THRESHOLD_MB=30               # 告警阈值
# --- 配置区结束 ---
# 初始化上一次的字节数
LAST_TX_BYTES=$(cat /sys/class/net/$INTERFACE/statistics/tx_bytes)
while true; do
    sleep 1
    # 获取当前字节数并计算速率
    CURRENT_TX_BYTES=$(cat /sys/class/net/$INTERFACE/statistics/tx_bytes)
    TX_MBPS=$(awk "BEGIN {printf \"%.2f\", ($CURRENT_TX_BYTES - $LAST_TX_BYTES) / 1024 / 1024}")
    # 检查是否超过阈值
    if (( $(echo "$TX_MBPS > $THRESHOLD_MB" | bc -l) )); then
        TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
        
        # 带时间戳的告警信息
        echo "$(date '+%Y-%m-%d %H:%M:%S') ========================================="
        echo "$(date '+%Y-%m-%d %H:%M:%S') [$TIMESTAMP] HIGH TRAFFIC DETECTED: ${TX_MBPS} MB/s!"
        echo "$(date '+%Y-%m-%d %H:%M:%S') Capturing traffic details for 60 seconds..."
        echo "$(date '+%Y-%m-%d %H:%M:%S') -----------------------------------------"
        
        # 运行 iftop 捕获流量,输出将被 nohup 重定向
        iftop -i $INTERFACE -n -P -t -s 60 -f "src net $INTERNAL_NET" -L 100
        
        echo "$(date '+%Y-%m-%d %H:%M:%S') -----------------------------------------"
        echo "$(date '+%Y-%m-%d %H:%M:%S') Capture finished. Continuing to monitor..."
    fi
    # 更新上一次的字节数
    LAST_TX_BYTES=$CURRENT_TX_BYTES
done

怎么用?

  1. 把代码存为 monitor.sh

  2. 给它执行权:chmod +x monitor.sh

  3. 甩到后台让它自己玩去:

    bash 复制代码
    nohup ./monitor.sh >> bandwidth_monitor.log 2>&1 &
  4. 想看监控录像了,就:

    bash 复制代码
    tail -f bandwidth_monitor.log

现在,我的服务器上装了个24小时无死角的"监控摄像头",哪个"内鬼"再敢出来作妖,保证让它有来无回,当场留下证据! 希望这个小脚本能帮你解决同样的烦恼。

相关推荐
踏浪无痕2 小时前
MySQL 脏读、不可重复读、幻读?一张表+3个例子彻底讲清!
后端·面试·架构
温宇飞2 小时前
Neon 数据库入门指南
后端
中国胖子风清扬2 小时前
Spring AI 深度实践:在 Java 项目中统一 Chat、RAG、Tools 与 MCP 能力
java·人工智能·spring boot·后端·spring·spring cloud·ai
零一科技2 小时前
Spring AOP 底层实现:JDK 动态代理与 CGLIB 代理的那点事儿
java·后端·spring
用户69371750013842 小时前
27.Kotlin 空安全:安全转换 (as?) 与非空断言 (!!)
android·后端·kotlin
3秒一个大2 小时前
从后端模板到响应式驱动:界面开发的演进之路
前端·后端
是阿漂啊2 小时前
vscode运行springboot项目
java·spring boot·后端
ghfdgbg2 小时前
13. 配置优先级 + Bean的管理 + SpringBoot核心原理
java·spring boot·后端
Moe4882 小时前
Elasticsearch 8.1 Java API Client 客户端使用指南(索引、文档操作篇)
java·后端·面试