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

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

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

不知道你有没有遇到过这种糟心事:服务器跑得好好的,突然就卡得不行,一查监控,好家伙,出站带宽瞬间被拉满,直冲 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小时无死角的"监控摄像头",哪个"内鬼"再敢出来作妖,保证让它有来无回,当场留下证据! 希望这个小脚本能帮你解决同样的烦恼。

相关推荐
止语Lab22 分钟前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活23 分钟前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困28 分钟前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn28 分钟前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
用户2986985301434 分钟前
Python 实现 Excel 与 Markdown 互转的实用指南
后端·python·excel
用户772831049084037 分钟前
krono-job:零侵入、单二进制交付的分布式任务调度平台(开源)
后端
Conan在掘金44 分钟前
鸿蒙报错速查:Function lacks ending return statement,返回路径漏 return 就炸,根因 + 真解法
后端
人间凡尔赛1 小时前
AI-Native 云原生架构:2026 年从容器编排到智能体编排的范式革命
后端·云原生·架构
IT_陈寒1 小时前
Vue的响应式让我加班到凌晨3点,原来问题出在这
前端·人工智能·后端
卷无止境1 小时前
提升 Python 代码健壮性的方法大盘点
后端·python