tcpdump使用實例——基於ip統計流量


自由轉載 ^_^   同時請注明原文出處:http://www.cnblogs.com/wangvsa/archive/2012/07/16/2593551.html

 

tcpdump - dump traffic on a network

 

問題:基於ip統計流量。

硬件:學校集群

resource_04.gif

難點:

  1.當使用高速網卡(千兆或IB)並且網卡滿負荷時丟包率如何

  2.程序的cpu占用率如何

  3.日志文件過大

方案及分析:

  1.抓包的實現方式有多種,如用libpcap庫、采用零拷貝方式、使用PF_RING接口、直接使用系統函數

我看了一些文章並測試了netsniff-ng程序(基於零拷貝),我認為零拷貝方式效率最高,丟包率最低。但是我

測試tcpdump時發現其效率也較高(測試時網卡幾乎滿負荷),並且幾乎沒有丟包,又由於其方便使用等其他

因素最終選用tcpdump。

  2.測試tcpdump抓包時cpu占用率4%左右

  3.tcpdump由於記錄每個數據包,雖然我們可以限制每個包記錄的字節數(-s選項),但是由於網卡滿負荷,

所以包的數量格外大。 如下,60秒已經抓到748168個包,導致pcap文件也格外大

Number of packets: 748168 
File size: 58394582 bytes
Data size: 3900660165 bytes
Capture duration: 59.963470 seconds

   因此,我使用-G選項每分鍾記錄一個pcap文件然后自己統計刪減其中數據,最后刪掉該pcap文件。即每分鍾

生成一個如下的文件(時間間隔可以根據需要改)

File name: /public/home/wangvsa/software/tcp-audit/2012-07-16,12:54:54.pcap
File encapsulation: Ethernet
Number of packets: 748168 
File size: 58394582 bytes
Data size: 3900660165 bytes
Capture duration: 59.963470 seconds
Start time: Mon Jul 16 12:54:53 2012
End time: Mon Jul 16 12:55:53 2012
Data rate: 65050607.75 bytes/s
Data rate: 520404861.98 bits/s


IPv4 total packet:   748037
       source ip  port   dir            dest ip  port	proto	flow
 10. 10. 10. 61:  9090    >     10. 10. 10. 49: 27884	tcp	1793
  0.  0.  0.  0:    68    >    255.255.255.255:    67	UDP	5310
 10. 10. 10. 49:     -    >     10. 10. 10. 62:     -	ICMP	234
 10. 10. 10. 49:    22    >     10. 10. 10. 61: 47051	tcp	117124
 10. 10. 10. 48: 38906    >     10. 10. 10. 49: 16797	tcp	44288974
 10. 10. 10. 48: 64468    >     10. 10. 10. 49: 45094	tcp	171
 10. 10. 10. 61: 47051    >     10. 10. 10. 49:    22	tcp	5406
 10. 10. 10. 49: 27884    >     10. 10. 10. 61:  9090	tcp	2112
 10. 10. 10. 49: 45094    >     10. 10. 10. 48: 64468	tcp	108
 10. 10. 10. 62:     -    >     10. 10. 10. 49:     -	ICMP	234
 10. 10. 10. 49: 16797    >     10. 10. 10. 48: 38906	tcp	3856230180

具體實現:   

  1.編寫針對pcap文件的統計腳本(如果對效率要求高可以寫成c語言程序),共兩個文件tcp-audit.sh 和

tcp-reduce.sh。在tcp-audit.sh中調用了tcp-reduce.sh,自己不要直接調用。

  先看tcp-audit.sh,這個文件從ready.txt中讀取內容,每一行都是一個要統計的pcap文件的文件名,稍后

討論如何得到的ready.txt文件。

 1 #!/bin/bash
 2 # tcp-audit.sh
 3 # 讀取ready.txt文件,每次讀取一行
 4 # 將其內容作為參數傳給tcp-reduce.sh
 5 # 執行完后刪除該行
 6 
 7 DIR="/home/wangchen/shell_ex/"
 8 
 9 while read line
10 do
11     # tcp-reduce.sh處理
12     $DIR/tcp-reduce.sh ${line}
13     # 刪除該pcap文件
14     rm $DIR/${line}
15     # 刪除該行
16     sed -i '1d' $DIR/ready.txt
17 done < $DIR/ready.txt

  再看tcp-reduce.sh,這個腳本完成了所有的統計操作並且輸出到日志文件中。這個腳本中使用了grep和sed命令

來格式話pcap文件的輸出方便之后awk程序的使用。還是用了capinfos這個程序提供的一些分析數據。

注:tcpdump 和 capinfos 版本不同,其參數選項要注意修改。如capinfos 的-x在舊版本中是用-i

 1 #!/bin/bash
 2 # tcp-reduce.sh
 3 DIR="/home/wangchen/shell_ex"
 4 
 5 # 根據pcap文件名構造出日志文件名(以時間命名)
 6 tmp1=$*
 7 tmp2=(${tmp1//./ })
 8 LOG_FILE_NAME=${tmp2[0]}".log"
 9 
10 # 輸出文件信息,即網卡信息
11 capinfos -a -c -d -e -E -s -u -x -y $DIR/$* >> $DIR/$LOG_FILE_NAME
12 
13 # 將tcpdump文件生成可讀文本
14 # 由grep,sed執行過濾、替換處理后交給awk
15 # 使用awk語言處理數據行,統計基於ip的流量信息 
16 tcpdump -q -n -e -t -r $DIR/$* \
17 | grep "IPv4" | sed 's/,/ /g; s/>/ /g; s/://g' \
18 | awk '      
19 
20 BEGIN {
21     printf("\n")
22 }
23 {
24     # $5:packet length
25     # $6:source ip.port
26     # $7:destination ip.port
27     # $8:proto
28 
29     # array_flow是數組記錄每個方向的流量
30     # 其下標是數據傳輸方向(字符串)
31 
32     count++
33     way = $6"."$7"."$8
34     for(x in arr_total_flow)    
35     { 
36     if(way==x)
37     {
38         arr_total_flow[way] += $5
39         next
40     }
41     }
42     arr_total_flow[way] = $5
43 }
44 
45 END {
46     printf("\nIPv4 total packet:   %d\n",NR) 
47     printf("%16s%6s%6s%19s%6s\tproto\tflow\n","source ip","port","dir","dest ip","port")
48     for(x in arr_total_flow)
49     {
50     # 格式化輸出
51     split(x,chunks,".")
52     if(chunks[9]=="ICMP")
53     {
54         printf("%3s.%3s.%3s.%3s:%6s    >    %3s.%3s.%3s.%3s:%6s\t%s\t%d\n",
55         chunks[1],chunks[2],chunks[3],chunks[4],"-",        # 源地址 : 端口
56         chunks[5],chunks[6],chunks[7],chunks[8],"-",        # 目的地址 : 端口
57         chunks[9],arr_total_flow[x])                     # 協議 總流量
58     }
59     else
60     {
61         printf("%3s.%3s.%3s.%3s:%6s    >    %3s.%3s.%3s.%3s:%6s\t%s\t%d\n",
62         chunks[1],chunks[2],chunks[3],chunks[4],chunks[5],     # 源地址 : 端口
63         chunks[6],chunks[7],chunks[8],chunks[9],chunks[10],    # 目的地址 : 端口
64         chunks[11],arr_total_flow[x])                      # 協議 總流量
65     }
66     }
67 }
68 ' >> $DIR/$LOG_FILE_NAME

  2.接下來就是如何運行的問題,首先用root權限執行tcpdump抓包程序,我使用的命令如下:

sudo cpdump -i eth3 -s 84 -G 60 -z ./tcp-add.sh -w %F,%T.pcap

參數分析:-i eth3 在eth3上抓包; -s 84每個包最多記錄84字節; -G 60 每60秒就在打開一個文件記錄;

     -z  ./tcp-add.sh配合-G使用,每次記錄完一個文件后執行./tcp-add.sh腳本(后面講這個腳本)

     -w %F,%T.pcap 輸出,文件名有時間組成%F表示年月日,%T表示時分秒,如2012-07-16,12:54:54.pcap

再來看這個tcp-add.sh,這個腳本十分簡單,實際就是將剛才的記錄完的pcap文件名寫到ready.txt文件中。

1 #!/bin/bash
2 # 作為tcpdump的-z參數使用
3 # 將已經存儲完的pcap文件名加入ready.txt等待處理
4 
5 echo $* >> ready.txt

這樣就會每分鍾生成一個pcap文件,並將其文件名寫到ready.txt文件中。

  3.下面就要用到cron來定時執行我們的統計任務。在開啟crond服務后執行如下命令

1 sudo crontab -e

此命令打開一個文件,在最后一行加入如下,之后保存退出

1 */2 * * * * /home/wangchen/shell_ex/tcp-audit.sh

這一條表示每兩分鍾(時間隨意定)執行一次tcp-audit.sh腳本。

 

到此功能就基本實現,在集群中實測可行。

當然以上方案僅僅是一個我在實驗室的一個練習,肯定有很多的不足,希望高手能不惜賜教。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM