检查网口流量与前10名流量大IP

本博客提供了一个实时监控网络流量与连接状态的脚本,包括实时流量、10秒平均流量、端口流量、最大带宽占用IP、连接状态统计及端口状态详细分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

此脚本包含的功能有:

  • 1、实时监控任意网卡的流量

  • 2、统计10秒内平均流量

  • 3、统计每个端口在10秒内的平均流量,基于客户端和服务端端口统计。可以看出哪些端口占流量比较大,对于web服务器,一般是80端口。其它端口受到攻击时,也有可能其它端口流量比较大。所以此功能可以帮助我们端口流量是否正常。

  • 4、统计在10s内占用带宽最大的前10个ip。此项功能可以帮助我们来查出是否有恶意占用带宽的ip。

  • 5、统计连接状态。此项功能可以让我们看出哪些连接状态比较大。如果SYN-RECV状态比较多的话,有可以受到半连接攻击。如果ESTABLISED非常大,但通过日志发现没有那么多请求,或者通过tcpdump发现大量ip只建立连接不请求数据的话,可能是受到了全连接攻击,这时候如果你使用的是nginx服务器,可以在配置文件增加listen 80 deferred来防止。

  • 6、统计各端口连接状态。当可能受到攻击时,此项功能可以帮助我们发现是哪个端口受到攻击。

  • 7、统计端口为80且状态为ESTAB连接数最多的前10个IP。此项功能可以帮助我们来找出创建连接过多的Ip,进而屏蔽。

  • 8、统计端口为80且状态为SYN-RECV连接数最多的前10个IP。当受到半连接攻击时,此项功能可以帮助我们找到恶意ip

 

用到的网络分析工具:

  • 1、tcpdump:此脚本用tcpdump来统计基于ip或基于端口的流量。

  • 2、ss: 此脚本用ss命令来统计连接状态,实际使用发现ss比netstat高效得多。

  • 3、/proc/net/dev,用来统计指定网卡的流量。

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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#!/bin/bash
  
  
#显示菜单(单选)
display_menu(){
local  soft=$1
local  prompt= "which ${soft} you'd select: "
eval  local  arr=(\${${soft}_arr[@]})
while  true
do
     echo  -e  "#################### ${soft} setting ####################\n\n"
     for  ((i=1;i<=${ #arr[@]};i++ )); do echo -e "$i) ${arr[$i-1]}"; done
     echo
     read  -p  "${prompt}"  $soft
     eval  local  select =\$$soft
     if  "$select"  ==  ""  ] || [  "${arr[$soft-1]}"  ==  ""   ]; then
         prompt= "input errors,please input a number: "
     else
         eval  $soft=${arr[$soft-1]}
         eval  echo  "your selection: \$$soft"             
         break
     fi
done
}
  
#把带宽bit单位转换为人类可读单位
bit_to_human_readable(){
     #input bit value
     local  trafficValue=$1
  
     if  [[ ${trafficValue%.*} -gt 922 ]]; then
         #conv to Kb
         trafficValue=` awk  - v  value=$trafficValue  'BEGIN{printf "%0.1f",value/1024}' `
         if  [[ ${trafficValue%.*} -gt 922 ]]; then
             #conv to Mb
             trafficValue=` awk  - v  value=$trafficValue  'BEGIN{printf "%0.1f",value/1024}' `
             echo  "${trafficValue}Mb"
         else
             echo  "${trafficValue}Kb"
         fi
     else
         echo  "${trafficValue}b"
     fi
}
  
#判断包管理工具
check_package_manager(){
     local  manager=$1
     local  systemPackage= ''
     if  cat  /etc/issue  grep  -q -E -i  "ubuntu|debian" ; then
         systemPackage= 'apt'
     elif  cat  /etc/issue  grep  -q -E -i  "centos|red hat|redhat" ; then
         systemPackage= 'yum'
     elif  cat  /proc/version  grep  -q -E -i  "ubuntu|debian" ; then
         systemPackage= 'apt'
     elif  cat  /proc/version  grep  -q -E -i  "centos|red hat|redhat" ; then
         systemPackage= 'yum'
     else
         echo  "unkonw"
     fi
  
     if  "$manager"  ==  "$systemPackage"  ]; then
         return  0
     else
         return  1
     fi   
}
  
  
#实时流量
realTimeTraffic(){
     local  eth= ""
     local  nic_arr=(` ifconfig  grep  -E -o  "^[a-z0-9]+"  grep  - v  "lo"  uniq `)
     local  nicLen=${ #nic_arr[@]}
     if  [[ $nicLen - eq  0 ]];  then
         echo  "sorry,I can not detect any network device,please report this issue to author."
         exit  1
     elif  [[ $nicLen - eq  1 ]];  then
         eth=$nic_arr
     else
         display_menu nic
         eth=$nic
     fi   
  
     local  clear = true
     local  eth_in_peak=0
     local  eth_out_peak=0
     local  eth_in=0
     local  eth_out=0
  
     while  true ; do
         #移动光标到0:0位置
         printf  "\033[0;0H"
         #清屏并打印Now Peak
         [[ $ clear  ==  true  ]] &&  printf  "\033[2J"  &&  echo  "$eth--------Now--------Peak-----------"
         traffic_be=(` awk  - v  eth=$eth -F '[: ]+'  '{if ($0 ~eth){print $3,$11}}'  /proc/net/dev `)
         sleep  2
         traffic_af=(` awk  - v  eth=$eth -F '[: ]+'  '{if ($0 ~eth){print $3,$11}}'  /proc/net/dev `)
         #计算速率
         eth_in=$(( (${traffic_af[0]}-${traffic_be[0]})*8 /2  ))
         eth_out=$(( (${traffic_af[1]}-${traffic_be[1]})*8 /2  ))
         #计算流量峰值
         [[ $eth_in -gt $eth_in_peak ]] && eth_in_peak=$eth_in
         [[ $eth_out -gt $eth_out_peak ]] && eth_out_peak=$eth_out
         #移动光标到2:1
         printf  "\033[2;1H"
         #清除当前行
         printf  "\033[K"   
         printf  "%-20s %-20s\n"  "Receive:  $(bit_to_human_readable $eth_in)"  "$(bit_to_human_readable $eth_in_peak)"
         #清除当前行
         printf  "\033[K"
         printf  "%-20s %-20s\n"  "Transmit: $(bit_to_human_readable $eth_out)"  "$(bit_to_human_readable $eth_out_peak)"
         [[ $ clear  ==  true  ]] &&  clear = false
     done
}
  
#流量和连接概览
trafficAndConnectionOverview(){
     if  which  tcpdump >  /dev/null ; then
         echo  "tcpdump not found,going to install it."
         if  check_package_manager apt; then
             apt-get -y  install  tcpdump
         elif  check_package_manager yum; then
             yum -y  install  tcpdump
         fi
     fi
  
     local  reg= ""
     local  eth= ""
     local  nic_arr=(` ifconfig  grep  -E -o  "^[a-z0-9]+"  grep  - v  "lo"  uniq `)
     local  nicLen=${ #nic_arr[@]}
     if  [[ $nicLen - eq  0 ]];  then
         echo  "sorry,I can not detect any network device,please report this issue to author."
         exit  1
     elif  [[ $nicLen - eq  1 ]];  then
         eth=$nic_arr
     else
         display_menu nic
         eth=$nic
     fi
  
     echo  "please wait for 10s to generate network data..."
     echo
     #当前流量值
     local  traffic_be=(` awk  - v  eth=$eth -F '[: ]+'  '{if ($0 ~eth){print $3,$11}}'  /proc/net/dev `)
     #tcpdump监听网络
     tcpdump - v  -i $eth -tnn >  /tmp/tcpdump_temp  2>&1 &
     sleep  10
     clear
     kill  ` ps  aux |  grep  tcpdump |  grep  - v  grep  awk  '{print $2}' `
     #处理tcpdump文件
     awk  '/^IP/{print;getline;print}'  /tmp/tcpdump_temp  /tmp/tcpdump_temp2
     awk  '{len=$NF;sub(/\)/,"",len);getline;print $0,len}'  /tmp/tcpdump_temp2  /tmp/tcpdump
     #10s后流量值
     local  traffic_af=(` awk  - v  eth=$eth -F '[: ]+'  '{if ($0 ~eth){print $3,$11}}'  /proc/net/dev `)
     #打印10s平均速率
     local  eth_in=$(( (${traffic_af[0]}-${traffic_be[0]})*8 /10  ))
     local  eth_out=$(( (${traffic_af[1]}-${traffic_be[1]})*8 /10  ))
     echo  -e  "\033[32mnetwork device $eth average traffic in 10s: \033[0m"
     echo  "$eth Receive: $(bit_to_human_readable $eth_in)/s"
     echo  "$eth Transmit: $(bit_to_human_readable $eth_out)/s"
     echo
     #统计每个端口在10s内的平均流量
     regTcpdump=$( ifconfig  grep  -A 1 $eth |  awk  -F '[: ]+'  '$0~/inet addr:/{printf $4"|"}'  sed  -e  's/|$//'  -e  's/^/(/'  -e  's/$/)\\\\\.[0-9]+:/' )
     echo  -e  "\033[32maverage traffic in 10s base on server port: \033[0m"
     awk  -F '[ .:]+'  - v  regTcpdump=$regTcpdump  '{if ($0 ~ regTcpdump){line="clients > "$8"."$9"."$10"."$11":"$12}else{line=$2"."$3"."$4"."$5":"$6" > clients"};sum[line]+=$NF*8/10}END{for (line in sum){printf "%s %d\n",line,sum[line]}}'  /tmp/tcpdump  | \
     sort  -k 4 -nr |  head  -n 10 |  while  read  a b c d; do
         echo  "$a $b $c $(bit_to_human_readable $d)/s"
     done
     echo
     echo  -e  "\033[32maverage traffic in 10s base on client port: \033[0m"
     awk  -F '[ .:]+'  - v  regTcpdump=$regTcpdump  '{if ($0 ~ regTcpdump){line=$2"."$3"."$4"."$5":"$6" > server"}else{line="server > "$8"."$9"."$10"."$11":"$12};sum[line]+=$NF*8/10}END{for (line in sum){printf "%s %d\n",line,sum[line]}}'  /tmp/tcpdump  | \
     sort  -k 4 -nr |  head  -n 10 |  while  read  a b c d; do
             echo  "$a $b $c $(bit_to_human_readable $d)/s"
     done   
         
     echo
     #统计在10s内占用带宽最大的前10个ip
     echo  -e  "\033[32mtop 10 ip average traffic in 10s : \033[0m"
     awk  -F '[ .:]+'  - v  regTcpdump=$regTcpdump  '{if ($0 ~ regTcpdump){line=$2"."$3"."$4"."$5" > "$8"."$9"."$10"."$11":"$12}else{line=$2"."$3"."$4"."$5":"$6" > "$8"."$9"."$10"."$11};sum[line]+=$NF*8/10}END{for (line in sum){printf "%s %d\n",line,sum[line]}}'  /tmp/tcpdump  | \
     sort  -k 4 -nr |  head  -n 10 |  while  read  a b c d; do
         echo  "$a $b $c $(bit_to_human_readable $d)/s"
     done
     echo
     #统计连接状态
     regSS=$( ifconfig  grep  -A 1 $eth |  awk  -F '[: ]+'  '$0~/inet addr:/{printf $4"|"}'  sed  -e  's/|$//' )
     ss -an |  grep  - v  -E  "LISTEN|UNCONN"  grep  -E  "$regSS"  /tmp/ss
     echo  -e  "\033[32mconnection state count: \033[0m"
     awk  'NR>1{sum[$(NF-4)]+=1}END{for (state in sum){print state,sum[state]}}'  /tmp/ss  sort  -k 2 -nr
     echo
     #统计各端口连接状态
     echo  -e  "\033[32mconnection state count by port: \033[0m"
     awk  'NR>1{sum[$(NF-4),$(NF-1)]+=1}END{for (key in sum){split(key,subkey,SUBSEP);print subkey[1],subkey[2],sum[subkey[1],subkey[2]]}}'  /tmp/ss  sort  -k 3 -nr |  head  -n 10   
     echo
     #统计端口为80且状态为ESTAB连接数最多的前10个IP
     echo  -e  "\033[32mtop 10 ip ESTAB state count at port 80: \033[0m"
     cat  /tmp/ss  grep  ESTAB |  awk  -F '[: ]+'  '{sum[$(NF-2)]+=1}END{for (ip in sum){print ip,sum[ip]}}'  sort  -k 2 -nr |  head  -n 10
     echo
     #统计端口为80且状态为SYN-RECV连接数最多的前10个IP
     echo  -e  "\033[32mtop 10 ip SYN-RECV state count at port 80: \033[0m"
     cat  /tmp/ss  grep  -E  "$regSS"  grep  SYN-RECV |  awk  -F '[: ]+'  '{sum[$(NF-2)]+=1}END{for (ip in sum){print ip,sum[ip]}}'  sort  -k 2 -nr |  head  -n 10
}
  
main(){
     while  true do
         echo  -e  "1) real time traffic.\n2) traffic and connection overview.\n"
         read  -p  "please input your select(ie 1): "  select
         case   $ select  in
             1) realTimeTraffic; break ;;
             2) trafficAndConnectionOverview; break ;;
             *)  echo  "input error,please input a number." ;;
         esac
     done   
}
  
main

 

转载:http://jin771998569.blog.51cto.com/2147853/1587726

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值