网络分析shell脚本分享(实时流量、连接统计)

一个强大的网络分析shell脚本分享(实时流量、连接统计)linux shell脚本之家
http://www.jb51.net/article/58768.htm

介绍一个强大的分析网络的shell脚本,此脚本是从EZHTTP拆分出来的,觉得有必要单独介绍下。
脚本运行效果截图:

Paste_Image.png
Paste_Image.png

此脚本包含的功能有:
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,用来统计指定网卡的流量。
脚本下载地址:https://www.centos.bz/wp-content/uploads/2014/06/network-analysis.sh
下面贴出完整的脚本:

代码如下:

!/bin/bash

write by zhumaohai(admin#centos.bz)

显示菜单(单选)

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}'`
#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
local regTcpdump=$(ifconfig | grep -A 1 $eth | awk -F'[: ]+' '$0~/inet addr:/{printf $4"|"}' | sed -e 's/|$//' -e 's/^/(/' -e 's/$/)\\\\\.[0-9]+:/')

#新旧版本tcpdump输出格式不一样,分别处理
if awk '/^IP/{print;exit}' /tmp/tcpdump_temp | grep -q ")$";then
    #处理tcpdump文件
    awk '/^IP/{print;getline;print}' /tmp/tcpdump_temp > /tmp/tcpdump_temp2
else
    #处理tcpdump文件
    awk '/^IP/{print}' /tmp/tcpdump_temp > /tmp/tcpdump_temp2
    sed -i -r 's#(.*: [0-9]+\))(.*)#\1\n    \2#' /tmp/tcpdump_temp2
fi

awk '{len=$NF;sub(/\)/,"",len);getline;print $0,len}' /tmp/tcpdump_temp2 > /tmp/tcpdump
#统计每个端口在10s内的平均流量
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 -ne "\033[11A"
echo -ne "\033[50C"
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 -ne "\033[50C"
        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 base on server: \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 -ne "\033[11A"
echo -ne "\033[50C"
echo -e "\033[32mtop 10 ip average traffic in 10s base on client: \033[0m"
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 | \
sort -k 4 -nr | head -n 10 | while read a b c d;do
    echo -ne "\033[50C"
    echo "$a $b $c $(bit_to_human_readable $d)/s"
done
echo
#统计连接状态
local 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 base on server: \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 -ne "\033[11A"
echo -ne "\033[50C"
echo -e "\033[32mconnection state count by port base on client: \033[0m"
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}'   
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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容

  • 简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者...
    保川阅读 5,939评论 1 13
  • 第1章 小试牛刀 $ 是普通用户,# 表示管理员用户 root。 shebang:#!。sharp / hash ...
    巴喬書摘阅读 6,320评论 1 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,566评论 18 139
  • 其实我并没有去学校上课,我在一条偏僻的小巷子里来回溜达,也许是我在逃避她。我不停地回想我与妻子那些曾经美好的时光。...
    见楚阅读 648评论 1 1
  • 庭前,一株幼芽似乎将要萌发,可是,却又在担心着萌芽后的生活,因此,它迟疑了,它默默的问自己,要不要出来呢?…… ...
    红尘夜语阅读 1,346评论 0 1