监测服务器流量并进行限制脚本

当心服务器流量被刷,通过脚本实时监测,流量超过阀值进行限制,并按月归零。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/bin/bash
# Parameter order: LIMIT_GB, reset_day, CHECK_TYPE, INTERFACE
LIMIT_GB=${1:-1024}
reset_day=${2:-1}
CHECK_TYPE=${3:-4}
INTERFACE=${4:-$(ip route | grep default | awk '{print $5}')}
LIMIT=$(echo "$LIMIT_GB * 1024" | bc)
echo "流量限制:$LIMIT MiB"
echo "流量将在每月的第 $reset_day 天重置"
current_day=$(date +'%-d')
last_day_of_month=$(date -d "$(date +'%Y%m01') +1 month -1 day" +%d)
if [ "$current_day" -eq "$reset_day" ] || ([ "$reset_day" -gt "$last_day_of_month" ] && [ "$current_day"
-eq "$last_day_of_month" ]); then
if [ ! -f "/tmp/vnstat_reset" ]; then
touch /tmp/vnstat_reset
rm /var/lib/vnstat/*
sudo systemctl restart vnstat
echo "流量已经重置,下次重置将在下个月的第 $reset_day 天"
else
echo "今天已经进行过流量重置,无需再次重置"
fi
else
if [ -f "/tmp/vnstat_reset" ]; then
rm /tmp/vnstat_reset
fi
if [ "$current_day" -lt "$reset_day" ]; then
days_until_reset=$(($reset_day - $current_day))
echo "还有 $days_until_reset 天流量将会重置"
else
days_until_reset=$(( $last_day_of_month - $current_day + $reset_day ))
echo "还有 $days_until_reset 天流量将会重置"
fi
fi
if [ -z "$INTERFACE" ]; then
echo "错误:无法自动检测网络接口。请手动指定。"
exit 1
fi
echo "正在监控的网络接口:$INTERFACE"
DATA=$(vnstat -i $INTERFACE --oneline)
CURRENT_DATE=$(echo $DATA | cut -d ';' -f 8)
TRAFFIC_RX=$(echo $DATA | cut -d ';' -f 13 | tr -d ' ' | sed 's/MiB//;s/GiB/*1024/;s/KiB/\/1024/' | bc)
TRAFFIC_TX=$(echo $DATA | cut -d ';' -f 14 | tr -d ' ' | sed 's/MiB//;s/GiB/*1024/;s/KiB/\/1024/' | bc)
echo "当前月份:$CURRENT_DATE"
if [ "$CHECK_TYPE" = "1" ]; then
TRAFFIC_TO_CHECK=$TRAFFIC_TX
echo "只检查上传流量。当前上传流量为:$TRAFFIC_TX MiB。"
echo "当前对比项是:上传流量。"
elif [ "$CHECK_TYPE" = "2" ]; then
TRAFFIC_TO_CHECK=$TRAFFIC_RX
echo "只检查下载流量。当前下载流量为:$TRAFFIC_RX MiB。"
echo "当前对比项是:下载流量。"
elif [ "$CHECK_TYPE" = "3" ]; then
TRAFFIC_TO_CHECK=$(echo "$TRAFFIC_TX $TRAFFIC_RX" | awk '{print ($1>$2)?$1:$2}')
if [ "$TRAFFIC_TO_CHECK" = "$TRAFFIC_TX" ]; then
echo "当前上传流量为:$TRAFFIC_TX MiB,下载流量为:$TRAFFIC_RX MiB。"
echo "作为比较的流量是:上传流量。"
else
echo "当前上传流量为:$TRAFFIC_TX MiB,下载流量为:$TRAFFIC_RX MiB。"
echo "作为比较的流量是:下载流量。"
fi
elif [ "$CHECK_TYPE" = "4" ]; then
TRAFFIC_TO_CHECK=$(echo "$TRAFFIC_TX + $TRAFFIC_RX" | bc)
echo "检查上传和下载流量的总和。当前上传流量为:$TRAFFIC_TX MiB,下载流量为:$TRAFFIC_RX MiB。"
echo "作为比较的流量是:上传和下载流量的总和($TRAFFIC_TO_CHECK MiB)。"
else
echo "错误:未提供有效的流量检查参数。参数应为1(只检查上传流量)、2(只检查下载流量)、3(检查上传和下载流量中的最大值)
或4(检查上传和下载流量的总和)。"
exit 1
fi
if (( $(echo "$TRAFFIC_TO_CHECK > $LIMIT" | bc -l) )); then
iptables -F
iptables -X
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
echo "警告:流量已超出限制!除SSH(端口22)外,所有端口已被阻止。"
else
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
echo "流量在设定的限制内,所有流量都被允许。"
fi

此脚本用于监控Linux服务器上的网络流量(出流量和入流量),并根据设定的流量阀值来阻止除SSH(端口22)以外的所有网络流量(通过阻断端口实现)。

这个脚本需要iptables,bc 和 vnstat 这三个软件包。iptables 配置 Linux 内核防火墙的工具,bc(Binary Calculator)用于实现任意精度计算(往往是高精度计算),vnstat 是网络流量监控工具。

安装上述三个软件包,

1
2
sudo apt-get update
sudo apt-get install -y iptables bc vnstat

运行脚本前,给脚本添加执行权限,

1
chmod +x traffic_monitor.sh

运行脚本,

1
bash traffic_monitor.sh 19 1 3 eth0

脚本有四个参数可设定,第一个LIMIT_GB,每月流量阀值,单位GB,默认1024(上面我设定为19GB);第二个reset_day,即每月的哪一天流量会被重置。默认值为1,即每月的第一天;第三个CHECK_TYPE,流量检测类型,默认值为4。1表示只检测入流量,2表示只检测出流量,3表示取入流量和出流量中的较大值,4表示检测入和出流量的总和;第四个INTERFACE:网络接口(上例中为eth0)。

脚本运行结果,

1
2
3
4
5
6
7
8
流量限制:19456 MiB
流量将在每月的第 1 天重置
还有 1 天流量将会重置
正在监控的网络接口:eth0
当前月份:Oct '24
当前上传流量为:29.39 MiB,下载流量为:7.90 MiB。
作为比较的流量是:上传流量。
流量在设定的限制内,所有流量都被允许。

通过crontab设定定时任务,使脚本每五分钟运行一次(即每5分钟监测一次流量,可以按需设定频率),并将脚本的输出重定向到 /root/traffic-log.txt 文件,以便随时查看。

1
(crontab -l ; echo "*/5 * * * * /root/traffic_monitor.sh 19 1 3 eth0 > /root/trafficl-log.txt") | crontab -
岭南园林及中国古代园林 给99元每年的阿里云经济型e实例开启IPv6访问享受大带宽免费流量

  评论

Nickname
Email
Website
0/500
  • 百度表情
  • 新浪微博
  • 脸书表情
12 comments

收藏,备用。

不过我用了宝塔面板,应该是有类似功能~

重庆
Windows 10
Chrome 129.0.0.0

我的博客图片不多,但也都放到又拍云上去,基本上就是0元,其他内容很少流量的。不过你的文章突然这么技术化,有点不习惯

广东
Windows 10
Microsoft Edge 120.0.0.0

这招很厉害。我也是怕别人恶意刷流量,才选择不限流量的主机。

安徽
Windows 10
Firefox 132.0

速度是矛,限流是盾。齐活了。

山东
Windows 10
Chrome 124.0.0.0

服务器被刷就关站,个人博客无所谓!所以不上CDN,有些人被刷得想哭!

加利福尼亚
Windows 10
Microsoft Edge 130.0.0.0

你们玩博客都是玩技术流啊。

湖北
Windows 10
Chrome 123.0.0.0

业余爱好,乱折腾。

加利福尼亚
Android Quince Tart
WeChat 8.0.53.2740

这个设置好,专业。
请教一下,hexo的搜索是通过rss进行的嘛?如果彻底关闭hexo的rss订阅功能,可以在博客内进行搜索嘛?

江苏
Windows 10
Firefox 132.0

不是。hexo的rss跟搜索都是额外功能,相互独立的,之间没关系。以我这个为例,rss是用hexo-generator-feed插件,搜索用的主题自带的,基于hexo-generator-json-content的。

加利福尼亚
Windows 10
Chrome 109.0.0.0
老麦

这个方法不错,非常有效的防止被刷。话说这个CDT后台上不可以设置吗?

广东
Windows 10
Chrome 130.0.0.0
老麦 @老麦

搞错了,弹性IP,带宽设置里能不能设置20G后自动关机?

广东
Windows 10
Chrome 130.0.0.0

没有这么人性化,这么直接的功能。阿里云后台类似功能,是比如成本控制什么的,设置复杂,且不能及时切断。最近阿里云似乎还把按日结算流量,换成了按月结算…

加利福尼亚
Windows 10
Chrome 109.0.0.0
----- Read more

感觉你这个绿很不适应,而且在这种绿色下感觉字体和背景的对比度变低了,看着更费劲。
你服务器不是原来有3M带宽吗?接入CDT后这3M就没有了吗?还是说超过3M带宽才消耗CDT的流量。

陕西
Windows 10
Chrome 130.0.0.0

之前折腾CDT是香港服务器。最近这个99元特价机快到期了,续期时,想到CDT,我把3M包年的宽带给取消了,换成了按流量计费的弹性ip,宽带大小能随意调,每月有20G的免费流量。最重要的是居然给我退了50多块钱,意味着现在这个99元的特价vps只要30多块一年。不过改成弹性ip以后,似乎就回不去了。后续再用99元续费似乎会有问题。

加利福尼亚
Android Quince Tart
WeChat 8.0.53.2740

阿里云的ipv6,弹性公网ip(ipv4)是两个计费项,都可以纳入CDT,统一管理计费。

加利福尼亚
Android Quince Tart
WeChat 8.0.53.2740

那也值了,我看CDT每G 0.8元,用10G收费流量才8元,加上免费的就30G了,配合CDN怎么也够用了。

陕西
Windows 10
Chrome 130.0.0.0

是的。我的博客有多个服务器节点,且图片等静态资源都在其他服务上。这个阿里云99的服务器上,每个月20G流量是足够了的。但以防万一,所以监测下流量,最好防护。:笑哭:

加利福尼亚
Android Quince Tart
WeChat 8.0.53.2740
----- Read more

主题怎么变成这样了

浙江
macOS Catalina
Chrome 130.0.0.0

把背景换成了更护眼的豆沙绿。

广东
Android Quince Tart
Microsoft Edge 130.0.0.0

有效抗刷

山东
macOS Catalina
Chrome 126.0.0.0

很强呀。我可以理解成超流量 = 网站自动关闭 吗?

上海
Windows 10
Microsoft Edge 121.0.0.0

是的。

广东
Android Quince Tart
Microsoft Edge 130.0.0.0