自动检测流量关闭网络接口、次月自动恢复网络

原文地址:https://www.nodeseek.com/post-127477-1

一、环境安装

这个脚本需要在Linux系统上运行,并需要vnstat和iptables这两个工具。如果你的系统上没有这两个工具,你可以通过以下命令来安装:

对于基于Debian的系统(如Ubuntu):

1
2
3
4
apt-get update -y
apt-get install vnstat iptables bc -y
systemctl start vnstat
systemctl enable vnstat

对于基于RPM的系统(如CentOS):

1
2
3
4
yum update -y
yum install vnstat iptables bc -y.
systemctl start vnstat
systemctl enable vnstat

这个命令用于安装 iptables​,bc​ 和 vnstat​ 这三个软件包。iptables​ 是用于配置 Linux 内核防火墙的工具,bc​ 是一个任意精度的计算器语言,vnstat​ 是一个控制台下的网络流量监控工具。-y 参数表示在安装过程中自动回答所有提示为 ‘yes’

二、脚本编写

编写监控脚本 /root/monitor_traffic.sh:

1
vim /root/monitor_traffic.sh

将下列代码粘贴:

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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/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以外的所有网络流量。脚本接受四个参数,但是所有参数都是可选的,如果没有提供,脚本会使用默认值。这四个参数分别是:

  1. LIMIT_GB​:流量限制,单位为GB。默认值为1024GB。

  2. reset_day​:流量重置日,即每月的哪一天流量会被重置。默认值为1,即每月的第一天。

  3. CHECK_TYPE​:流量检查类型。默认值为4。这个参数有四个可选值:

    1:只检查上传流量

    2:只检查下载流量

    3:检查上传和下载流量中的最大值

    4:检查上传和下载流量的总和

  4. INTERFACE​:网络接口。默认值为系统的默认网络接口。

三、使用教程

monitor_traffic.sh​ 脚本添加执行权限。chmod 是用于改变文件权限的命令,+x 表示添加执行权限

1
chmod +x monitor_traffic.sh
  • 使用所有默认参数运行脚本:

    1
    ./traffic_monitor.sh

    这将会设置流量限制为1024GB,每月的第一天重置流量,检查上传和下载流量的总和,并使用系统的默认网络接口。

  • 设置流量限制为500GB,其他参数使用默认值:

    1
    ./traffic_monitor.sh 500
  • 设置流量限制为500GB,流量在每月的10号重置,其他参数使用默认值:

    1
    ./traffic_monitor.sh 500 10
  • 设置流量限制为500GB,流量在每月的10号重置,只检查下载流量,其他参数使用默认值:

    1
    ./traffic_monitor.sh 500 10 2
  • 设置流量限制为500GB,流量在每月的10号重置,只检查下载流量,并指定网络接口为eth0:

    1
    ./traffic_monitor.sh 500 10 2 eth0

monitor_traffic.sh​ 脚本添加到 crontab,使其每分钟运行一次,并将脚本的输出重定向到 /root/脚本日志.txt​ 文件

设置流量限制为190GB,流量在每月的10号重置,每分钟运行一次任务检查上传和下载流量中的最大值:

1
(crontab -l ; echo "* * * * * /root/monitor_traffic.sh 190 10 3 > /root/脚本日志.txt")  | crontab -