1. #!/bin/bash
  2. #write by zhumaohai(admin#centos.bz)
  3. #author blog: www.centos.bz
  4. #显示菜单(单选)
  5. display_menu(){
  6. local soft=$1
  7. local prompt="which ${soft} you'd select: "
  8. eval local arr=(\${${soft}_arr[@]})
  9. while true
  10. do
  11. echo -e "#################### ${soft} setting ####################\n\n"
  12. for ((i=1;i<=${#arr[@]};i++ )); do echo -e "$i) ${arr[$i-1]}"; done
  13. echo
  14. read -p "${prompt}" $soft
  15. eval local select=\$$soft
  16. if [ "$select" == "" ] || [ "${arr[$soft-1]}" == "" ];then
  17. prompt="input errors,please input a number: "
  18. else
  19. eval $soft=${arr[$soft-1]}
  20. eval echo "your selection: \$$soft"
  21. break
  22. fi
  23. done
  24. }
  25. #把带宽bit单位转换为人类可读单位
  26. bit_to_human_readable(){
  27. #input bit value
  28. local trafficValue=$1
  29. if [[ ${trafficValue%.*} -gt 922 ]];then
  30. #conv to Kb
  31. trafficValue=`awk -v value=$trafficValue 'BEGIN{printf "%0.1f",value/1024}'`
  32. if [[ ${trafficValue%.*} -gt 922 ]];then
  33. #conv to Mb
  34. trafficValue=`awk -v value=$trafficValue 'BEGIN{printf "%0.1f",value/1024}'`
  35. echo "${trafficValue}Mb"
  36. else
  37. echo "${trafficValue}Kb"
  38. fi
  39. else
  40. echo "${trafficValue}b"
  41. fi
  42. }
  43. #判断包管理工具
  44. check_package_manager(){
  45. local manager=$1
  46. local systemPackage=''
  47. if cat /etc/issue | grep -q -E -i "ubuntu|debian";then
  48. systemPackage='apt'
  49. elif cat /etc/issue | grep -q -E -i "centos|red hat|redhat";then
  50. systemPackage='yum'
  51. elif cat /proc/version | grep -q -E -i "ubuntu|debian";then
  52. systemPackage='apt'
  53. elif cat /proc/version | grep -q -E -i "centos|red hat|redhat";then
  54. systemPackage='yum'
  55. else
  56. echo "unkonw"
  57. fi
  58. if [ "$manager" == "$systemPackage" ];then
  59. return 0
  60. else
  61. return 1
  62. fi
  63. }
  64. #实时流量
  65. realTimeTraffic(){
  66. local eth=""
  67. local nic_arr=(`ifconfig | grep -E -o "^[a-z0-9]+" | grep -v "lo" | uniq`)
  68. local nicLen=${#nic_arr[@]}
  69. if [[ $nicLen -eq 0 ]]; then
  70. echo "sorry,I can not detect any network device,please report this issue to author."
  71. exit 1
  72. elif [[ $nicLen -eq 1 ]]; then
  73. eth=$nic_arr
  74. else
  75. display_menu nic
  76. eth=$nic
  77. fi
  78. local clear=true
  79. local eth_in_peak=0
  80. local eth_out_peak=0
  81. local eth_in=0
  82. local eth_out=0
  83. while true;do
  84. #移动光标到0:0位置
  85. printf "\033[0;0H"
  86. #清屏并打印Now Peak
  87. [[ $clear == true ]] && printf "\033[2J" && echo "$eth--------Now--------Peak-----------"
  88. traffic_be=(`awk -v eth=$eth -F'[: ]+' '{if ($0 ~eth){print $3,$11}}' /proc/net/dev`)
  89. sleep 2
  90. traffic_af=(`awk -v eth=$eth -F'[: ]+' '{if ($0 ~eth){print $3,$11}}' /proc/net/dev`)
  91. #计算速率
  92. eth_in=$(( (${traffic_af[0]}-${traffic_be[0]})*8/2 ))
  93. eth_out=$(( (${traffic_af[1]}-${traffic_be[1]})*8/2 ))
  94. #计算流量峰值
  95. [[ $eth_in -gt $eth_in_peak ]] && eth_in_peak=$eth_in
  96. [[ $eth_out -gt $eth_out_peak ]] && eth_out_peak=$eth_out
  97. #移动光标到2:1
  98. printf "\033[2;1H"
  99. #清除当前行
  100. printf "\033[K"
  101. printf "%-20s %-20s\n" "Receive: $(bit_to_human_readable $eth_in)" "$(bit_to_human_readable $eth_in_peak)"
  102. #清除当前行
  103. printf "\033[K"
  104. printf "%-20s %-20s\n" "Transmit: $(bit_to_human_readable $eth_out)" "$(bit_to_human_readable $eth_out_peak)"
  105. [[ $clear == true ]] && clear=false
  106. done
  107. }
  108. #流量和连接概览
  109. trafficAndConnectionOverview(){
  110. if ! which tcpdump > /dev/null;then
  111. echo "tcpdump not found,going to install it."
  112. if check_package_manager apt;then
  113. apt-get -y install tcpdump
  114. elif check_package_manager yum;then
  115. yum -y install tcpdump
  116. fi
  117. fi
  118. local reg=""
  119. local eth=""
  120. local nic_arr=(`ifconfig | grep -E -o "^[a-z0-9]+" | grep -v "lo" | uniq`)
  121. local nicLen=${#nic_arr[@]}
  122. if [[ $nicLen -eq 0 ]]; then
  123. echo "sorry,I can not detect any network device,please report this issue to author."
  124. exit 1
  125. elif [[ $nicLen -eq 1 ]]; then
  126. eth=$nic_arr
  127. else
  128. display_menu nic
  129. eth=$nic
  130. fi
  131. echo "please wait for 10s to generate network data..."
  132. echo
  133. #当前流量值
  134. local traffic_be=(`awk -v eth=$eth -F'[: ]+' '{if ($0 ~eth){print $3,$11}}' /proc/net/dev`)
  135. #tcpdump监听网络
  136. tcpdump -v -i $eth -tnn > /tmp/tcpdump_temp 2>&1 &
  137. sleep 10
  138. clear
  139. kill `ps aux | grep tcpdump | grep -v grep | awk '{print $2}'`
  140. #10s后流量值
  141. local traffic_af=(`awk -v eth=$eth -F'[: ]+' '{if ($0 ~eth){print $3,$11}}' /proc/net/dev`)
  142. #打印10s平均速率
  143. local eth_in=$(( (${traffic_af[0]}-${traffic_be[0]})*8/10 ))
  144. local eth_out=$(( (${traffic_af[1]}-${traffic_be[1]})*8/10 ))
  145. echo -e "\033[32mnetwork device $eth average traffic in 10s: \033[0m"
  146. echo "$eth Receive: $(bit_to_human_readable $eth_in)/s"
  147. echo "$eth Transmit: $(bit_to_human_readable $eth_out)/s"
  148. echo
  149. local regTcpdump=$(ifconfig | grep -A 1 $eth | awk -F'[: ]+' '$0~/inet addr:/{printf $4"|"}' | sed -e 's/|$//' -e 's/^/(/' -e 's/$/)\\\\\.[0-9]+:/')
  150. #新旧版本tcpdump输出格式不一样,分别处理
  151. if awk '/^IP/{print;exit}' /tmp/tcpdump_temp | grep -q ")$";then
  152. #处理tcpdump文件
  153. awk '/^IP/{print;getline;print}' /tmp/tcpdump_temp > /tmp/tcpdump_temp2
  154. else
  155. #处理tcpdump文件
  156. awk '/^IP/{print}' /tmp/tcpdump_temp > /tmp/tcpdump_temp2
  157. sed -i -r 's#(.*: [0-9]+\))(.*)#\1\n \2#' /tmp/tcpdump_temp2
  158. fi
  159. awk '{len=$NF;sub(/\)/,"",len);getline;print $0,len}' /tmp/tcpdump_temp2 > /tmp/tcpdump
  160. #统计每个端口在10s内的平均流量
  161. echo -e "\033[32maverage traffic in 10s base on server port: \033[0m"
  162. 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 | \
  163. sort -k 4 -nr | head -n 10 | while read a b c d;do
  164. echo "$a $b $c $(bit_to_human_readable $d)/s"
  165. done
  166. echo -ne "\033[11A"
  167. echo -ne "\033[50C"
  168. echo -e "\033[32maverage traffic in 10s base on client port: \033[0m"
  169. 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 | \
  170. sort -k 4 -nr | head -n 10 | while read a b c d;do
  171. echo -ne "\033[50C"
  172. echo "$a $b $c $(bit_to_human_readable $d)/s"
  173. done
  174. echo
  175. #统计在10s内占用带宽最大的前10个ip
  176. echo -e "\033[32mtop 10 ip average traffic in 10s base on server: \033[0m"
  177. 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 | \
  178. sort -k 4 -nr | head -n 10 | while read a b c d;do
  179. echo "$a $b $c $(bit_to_human_readable $d)/s"
  180. done
  181. echo -ne "\033[11A"
  182. echo -ne "\033[50C"
  183. echo -e "\033[32mtop 10 ip average traffic in 10s base on client: \033[0m"
  184. awk -F'[ .:]+' -v regTcpdump=$regTcpdump '{if ($0 ~ regTcpdump){line=$2"."$3"."$4"."$5":"$6" > "$8"."$9"."$10"."$11}else{line=$2"."$3"."$4"."$5" > "$8"."$9"."$10"."$11":"$12};sum[line]+=$NF*8/10}END{for (line in sum){printf "%s %d\n",line,sum[line]}}' /tmp/tcpdump | \
  185. sort -k 4 -nr | head -n 10 | while read a b c d;do
  186. echo -ne "\033[50C"
  187. echo "$a $b $c $(bit_to_human_readable $d)/s"
  188. done
  189. echo
  190. #统计连接状态
  191. local regSS=$(ifconfig | grep -A 1 $eth | awk -F'[: ]+' '$0~/inet addr:/{printf $4"|"}' | sed -e 's/|$//')
  192. ss -an | grep -v -E "LISTEN|UNCONN" | grep -E "$regSS" > /tmp/ss
  193. echo -e "\033[32mconnection state count: \033[0m"
  194. awk 'NR>1{sum[$(NF-4)]+=1}END{for (state in sum){print state,sum[state]}}' /tmp/ss | sort -k 2 -nr
  195. echo
  196. #统计各端口连接状态
  197. echo -e "\033[32mconnection state count by port base on server: \033[0m"
  198. 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
  199. echo -ne "\033[11A"
  200. echo -ne "\033[50C"
  201. echo -e "\033[32mconnection state count by port base on client: \033[0m"
  202. awk 'NR>1{sum[$(NF-4),$(NF)]+=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 | awk '{print "\033[50C"$0}'
  203. echo
  204. #统计端口为80且状态为ESTAB连接数最多的前10个IP
  205. echo -e "\033[32mtop 10 ip ESTAB state count at port 80: \033[0m"
  206. 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
  207. echo
  208. #统计端口为80且状态为SYN-RECV连接数最多的前10个IP
  209. echo -e "\033[32mtop 10 ip SYN-RECV state count at port 80: \033[0m"
  210. 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
  211. }
  212. main(){
  213. while true; do
  214. echo -e "1) real time traffic.\n2) traffic and connection overview.\n"
  215. read -p "please input your select(ie 1): " select
  216. case $select in
  217. 1) realTimeTraffic;break;;
  218. 2) trafficAndConnectionOverview;break;;
  219. *) echo "input error,please input a number.";;
  220. esac
  221. done
  222. }
  223. main
文档更新时间: 2019-01-08 15:22   作者:张尚