tcpdump


一、簡介

tcpdump是一個用於截取網絡分組,並輸出分組內容的工具。

tcpdump 支持針對網絡層、協議、主機、網絡或端口的過濾,並提供and、or、not等邏輯語句來幫助你去掉無用的信息

When tcpdump finishes capturing packets, it will report counts of:

packets ``captured'' (this is the number of packets that  tcpdump has received and processed);
packets ``received by filter'' (the meaning of this depends on the OS on which you're running  tcpdump, and possibly on the way the OS was configured - if a filter was specified on the command line, on some OSes it counts packets regardless of whether they were matched by the filter expression and, even if they were matched by the filter expression, regardless of whether  tcpdump has read and processed them yet, on other OSes it counts only packets that were matched by the filter expression regardless of whether  tcpdump has read and processed them yet, and on other OSes it counts only packets that were matched by the filter expression and were processed by  tcpdump);
packets ``dropped by kernel'' (this is the number of packets that were dropped, due to a lack of buffer space, by the packet capture mechanism in the OS on which  tcpdump is running, if the OS reports that information to applications; if not, it will be reported as 0).

二、語法

完整的英文文檔:https://www.tcpdump.org/tcpdump_man.html

  • -A 以ASCII格式打印出所有分組,並將鏈路層的頭最小化。 

  • -c 在收到指定的數量的分組后,tcpdump就會停止。 

  • -C 在將一個原始分組寫入文件之前,檢查文件當前的大小是否超過了參數file_size 中指定的大小。如果超過了指定大小,則關閉當前文件,然后在打開一個新的文件。參數 file_size 的單位是兆字節(是1,000,000字節,而不是1,048,576字節)。 

  • -d 將匹配信息包的代碼以人們能夠理解的匯編格式給出。 

  • -dd 將匹配信息包的代碼以C語言程序段的格式給出。 

  • -ddd 將匹配信息包的代碼以十進制的形式給出。 

  • -D 打印出系統中所有可以用tcpdump截包的網絡接口。 

  • -e 在輸出行打印出數據鏈路層的頭部信息。 

  • -E 用spi@ipaddr algo:secret解密那些以addr作為地址,並且包含了安全參數索引值spi的IPsec ESP分組。 

  • -f 將外部的Internet地址以數字的形式打印出來。 

  • -F 從指定的文件中讀取表達式,忽略命令行中給出的表達式。 

  • -i 指定監聽的網絡接口。 

  • -l 使標准輸出變為緩沖行形式,可以把數據導出到文件。 

  • -L 列出網絡接口的已知數據鏈路。 

  • -m 從文件module中導入SMI MIB模塊定義。該參數可以被使用多次,以導入多個MIB模塊。 

  • -M 如果tcp報文中存在TCP-MD5選項,則需要用secret作為共享的驗證碼用於驗證TCP-MD5選選項摘要(詳情可參考RFC 2385)。 

  • -b 在數據-鏈路層上選擇協議,包括ip、arp、rarp、ipx都是這一層的。 

  • -n 不把網絡地址轉換成名字。 

  • -nn 不進行端口名稱的轉換。 

  • -N 不輸出主機名中的域名部分。例如,‘nic.ddn.mil‘只輸出’nic‘。 

  • -t 在輸出的每一行不打印時間戳。 

  • -O 不運行分組分組匹配(packet-matching)代碼優化程序。 

  • -P 不將網絡接口設置成混雜模式。 

  • -q 快速輸出。只輸出較少的協議信息。 

  • -r 從指定的文件中讀取包(這些包一般通過-w選項產生)。 

  • -S 將tcp的序列號以絕對值形式輸出,而不是相對值。 

  • -s 從每個分組中讀取最開始的snaplen個字節,而不是默認的68個字節。 

  • -T 將監聽到的包直接解釋為指定的類型的報文,常見的類型有rpc遠程過程調用)和snmp(簡單網絡管理協議;)。 

  • -t 不在每一行中輸出時間戳。 

  • -tt 在每一行中輸出非格式化的時間戳。 

  • -ttt 輸出本行和前面一行之間的時間差。 

  • -tttt 在每一行中輸出由date處理的默認格式的時間戳。 

  • -u 輸出未解碼的NFS句柄。 

  • -v 輸出一個稍微詳細的信息,例如在ip包中可以包括ttl和服務類型的信息。 

  • -vv 輸出詳細的報文信息。 

  • -w 直接將分組寫入文件中,而不是不分析並打印出來。

以太網幀的封包格式為:Frame=Ethernet Header +IP Header +TCP Header +TCP Segment Data

  • Ethernet Header =14 Byte =Dst Physical Address(6 Byte)+ Src Physical Address(6 Byte)+Type(2 Byte),以太網幀頭以下稱之為數據幀。

  • IP Header =20 Byte(without options field),數據在IP層稱為Datagram,分片稱為Fragment。

  • TCP Header = 20 Byte(without options field),數據在TCP層稱為Stream,分段稱為Segment(UDP中稱為Message)。

  • 54個字節后為TCP數據負載部分(Data Portion),即應用層用戶數據。

Ethernet Header以下的IP數據報最大傳輸單位為MTU(Maximum Transmission Unit,Effect of short board),對於大多數使用以太網的局域網來說,MTU=1500。

TCP數據包每次能夠傳輸的最大數據分段為MSS,為了達到最佳的傳輸效能,在建立TCP連接時雙方將協商MSS值——雙方提供的MSS值中的最小值為這次連接的最大MSS值。MSS往往基於MTU計算出來,通常MSS=MTU-sizeof(IP Header)-sizeof(TCP Header)=1500-20-20=1460。

這樣,數據經過本地TCP層分段后,交給本地IP層,在本地IP層就不需要分片了。但是在下一跳路由(Next Hop)的鄰居路由器上可能發生IP分片!因為路由器的網卡的MTU可能小於需要轉發的IP數據報的大小。

這時候,在路由器上可能發生兩種情況:

(1)如果源發送端設置了這個IP數據包可以分片(May Fragment,DF=0),路由器將IP數據報分片后轉發。

(2)如果源發送端設置了這個IP數據報不可以分片(Don’t Fragment,DF=1),路由器將IP數據報丟棄,並發送ICMP分片錯誤消息給源發送端。

    • 過濾主機/IP: 
      • tcpdump -i eth1 host 172.16.7.206
      • 抓取所有經過網卡1,目的IP為172.16.7.206的網絡數據 
    • 過濾端口: 
      • tcpdump -i eth1 dst port 1234
      • 抓取所有經過網卡1,目的端口為1234的網絡數據 
    • 過濾特定協議: 
      • tcpdump -i eth1 udp
      • 抓取所有經過網卡1,協議類型為UDP的網絡數據 
    • 抓取本地環路數據包 
      • tcpdump -i lo udp 抓取UDP數據
      • tcpdump -i lo udp port 1234 抓取端口1234的UDP數據
      • tcpdump -i lo port 1234 抓取端口1234的數據 
    • 特定協議特定端口: 
      • tcpdump udp port 1234
      • 抓取所有經過1234端口的UDP網絡數據 
    • 抓取特定類型的數據包: 
      • tcpdump -i eth1 ‘tcp[tcpflags] = tcp-syn’
      • 抓取所有經過網卡1的SYN類型數據包
      • tcpdump -i eth1 udp dst port 53
      • 抓取經過網卡1的所有DNS數據包(默認端口) 
    • 邏輯語句過濾: 
      • tcpdump -i eth1 ‘((tcp) and ((dst net 172.16) and (not dst host 192.168.1.200)))’
      • 抓取所有經過網卡1,目的網絡是172.16,但目的主機不是192.168.1.200的TCP數據 
    • 抓包存取: 
      • tcpdump -i eth1 host 172.16.7.206 and port 80 -w /tmp/xxx.cap
      • 抓取所有經過網卡1,目的主機為172.16.7.206的端口80的網絡數據並存儲

三、實例

1、默認啟動

1
tcpdump -vv

普通情況下,直接啟動tcpdump將監視第一個網絡接口上所有流過的數據包。

2、過濾主機

1
2
3
tcpdump -i eth1 host 192.168.1.1
tcpdump -i eth1 src host 192.168.1.1
tcpdump -i eth1 dst host 192.168.1.1

抓取所有經過eth1,目的或源地址是192.168.1.1的網絡數據

指定源地址,192.168.1.1

指定目的地址,192.168.1.1

3、過濾端口

1
2
3
tcpdump -i eth1 port 25
tcpdump -i eth1 src port 25
tcpdump -i eth1 dst port 25

抓取所有經過eth1,目的或源端口是25的網絡數據

指定源端口

指定目的端口

4、網絡過濾

1
2
3
tcpdump -i eth1 net 192.168
tcpdump -i eth1 src net 192.168
tcpdump -i eth1 dst net 192.168

5、協議過濾

1
2
3
4
5
tcpdump -i eth1 arp
tcpdump -i eth1 ip
tcpdump -i eth1 tcp
tcpdump -i eth1 udp
tcpdump -i eth1 icmp

6、常用表達式

1
2
3
非 : ! or  "not"  (去掉雙引號) 
且 : && or  "and" 
或 : || or  "or"

抓取所有經過eth1,目的地址是192.168.1.254或192.168.1.200端口是80的TCP數

1
tcpdump -i eth1  '((tcp) and (port 80) and ((dst host 192.168.1.254) or (dst host 192.168.1.200)))'

抓取所有經過eth1,目標MAC地址是00:01:02:03:04:05的ICMP數據

1
tcpdump -i eth1  '((icmp) and ((ether dst host 00:01:02:03:04:05)))'

抓取所有經過eth1,目的網絡是192.168,但目的主機不是192.168.1.200的TCP數據

1
tcpdump -i eth1  '((tcp) and ((dst net 192.168) and (not dst host 192.168.1.200)))'

四、高級過濾方式

首先了解如何從包頭過濾信息

1
2
3
4
5
proto[x:y]          : 過濾從x字節開始的y字節數。比如ip[2:2]過濾出3、4字節(第一字節從0開始排)
proto[x:y] & z = 0  : proto[x:y]和z的與操作為0
proto[x:y] & z !=0  : proto[x:y]和z的與操作不為0
proto[x:y] & z = z  : proto[x:y]和z的與操作為z
proto[x:y] = z      : proto[x:y]等於z

操作符 : >, <, >=, <=, =, !=

1、IP頭(IPV4)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|  IHL  |Type of Service|          Total Length         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Identification        |Flags|      Fragment Offset    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Time to Live |    Protocol   |         Header Checksum       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Source Address                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Destination Address                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    | <-- optional
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            DATA ...                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

  

中文:

 

tcpdump采用命令行方式對接口的數據包進行篩選抓取,其豐富特性表現在靈活的表達式上。

不帶任何選項的tcpdump,默認會抓取第一個網絡接口,且只有將tcpdump進程終止才會停止抓包。

例如:

shell> tcpdump -nn -i eth0 icmp

下面是詳細的tcpdump用法。

1.1 tcpdump選項

它的命令格式為:

 
tcpdump [ -DenNqvX ] [ -c count ] [ -F file ] [ -i interface ] [ -r file ]
        [ -s snaplen ] [ -w file ] [ expression ]

抓包選項:
-c:指定要抓取的包數量。注意,是最終要獲取這么多個包。例如,指定"-c 10"將獲取10個包,但可能已經處理了100個包,只不過只有10個包是滿足條件的包。
-i interface:指定tcpdump需要監聽的接口。若未指定該選項,將從系統接口列表中搜尋編號最小的已配置好的接口(不包括loopback接口,要抓取loopback接口使用tcpdump -i lo),
:一旦找到第一個符合條件的接口,搜尋馬上結束。可以使用'any'關鍵字表示所有網絡接口。 -n:對地址以數字方式顯式,否則顯式為主機名,也就是說-n選項不做主機名解析。 -nn:除了-n的作用外,還把端口顯示為數值,否則顯示端口服務名。 -N:不打印出host的域名部分。例如tcpdump將會打印'nic'而不是'nic.ddn.mil'。 -P:指定要抓取的包是流入還是流出的包。可以給定的值為"in"、"out"和"inout",默認為"inout"。 -s len:設置tcpdump的數據包抓取長度為len,如果不設置默認將會是65535字節。對於要抓取的數據包較大時,長度設置不夠可能會產生包截斷,若出現包截斷,
:輸出行中會出現"[|proto]"的標志(proto實際會顯示為協議名)。但是抓取len越長,包的處理時間越長,並且會減少tcpdump可緩存的數據包的數量,
:從而會導致數據包的丟失,所以在能抓取我們想要的包的前提下,抓取長度越小越好。 輸出選項: -e:輸出的每行中都將包括數據鏈路層頭部信息,例如源MAC和目標MAC。 -q:快速打印輸出。即打印很少的協議相關信息,從而輸出行都比較簡短。 -X:輸出包的頭部數據,會以16進制和ASCII兩種方式同時輸出。 -XX:輸出包的頭部數據,會以16進制和ASCII兩種方式同時輸出,更詳細。 -v:當分析和打印的時候,產生詳細的輸出。 -vv:產生比-v更詳細的輸出。 -vvv:產生比-vv更詳細的輸出。 其他功能性選項: -D:列出可用於抓包的接口。將會列出接口的數值編號和接口名,它們都可以用於"-i"后。 -F:從文件中讀取抓包的表達式。若使用該選項,則命令行中給定的其他表達式都將失效。 -w:將抓包數據輸出到文件中而不是標准輸出。可以同時配合"-G time"選項使得輸出文件每time秒就自動切換到另一個文件。可通過"-r"選項載入這些文件以進行分析和打印。 -r:從給定的數據包文件中讀取數據。使用"-"表示從標准輸入中讀取。
 

所以常用的選項也就這幾個:

  • tcpdump -D
  • tcpdump -c num -i int -nn -XX -vvv

1.2 tcpdump表達式

表達式用於篩選輸出哪些類型的數據包,如果沒有給定表達式,所有的數據包都將輸出,否則只輸出表達式為true的包。在表達式中出現的shell元字符建議使用單引號包圍。

tcpdump的表達式由一個或多個"單元"組成,每個單元一般包含ID的修飾符和一個ID(數字或名稱)。有三種修飾符:

(1).type:指定ID的類型。

可以給定的值有host/net/port/portrange。例如"host foo","net 128.3","port 20","portrange 6000-6008"。默認的type為host。

(2).dir:指定ID的方向。

可以給定的值包括src/dst/src or dst/src and dst,默認為src or dst。例如,"src foo"表示源主機為foo的數據包,"dst net 128.3"表示目標網絡為128.3的數據包,"src or dst port 22"表示源或目的端口為22的數據包。

(3).proto:通過給定協議限定匹配的數據包類型。

常用的協議有tcp/udp/arp/ip/ether/icmp等,若未給定協議類型,則匹配所有可能的類型。例如"tcp port 21","udp portrange 7000-7009"。

所以,一個基本的表達式單元格式為"proto dir type ID"

除了使用修飾符和ID組成的表達式單元,還有關鍵字表達式單元:gateway,broadcast,less,greater以及算術表達式。

表達式單元之間可以使用操作符" and / && / or / || / not / ! "進行連接,從而組成復雜的條件表達式。如"host foo and not port ftp and not port ftp-data",這表示篩選的數據包要滿足"主機為foo且端口不是ftp(端口21)和ftp-data(端口20)的包",常用端口和名字的對應關系可在linux系統中的/etc/service文件中找到。

另外,同樣的修飾符可省略,如"tcp dst port ftp or ftp-data or domain"與"tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain"意義相同,都表示包的協議為tcp且目的端口為ftp或ftp-data或domain(端口53)。

使用括號"()"可以改變表達式的優先級,但需要注意的是括號會被shell解釋,所以應該使用反斜線"\"轉義為"\(\)",在需要的時候,還需要包圍在引號中。

1.3 tcpdump示例

注意,tcpdump只能抓取流經本機的數據包。

(1).默認啟動

tcpdump

默認情況下,直接啟動tcpdump將監視第一個網絡接口(非lo口)上所有流通的數據包。這樣抓取的結果會非常多,滾動非常快。

(2).監視指定網絡接口的數據包

tcpdump -i eth1

如果不指定網卡,默認tcpdump只會監視第一個網絡接口,如eth0。

(3).監視指定主機的數據包,例如所有進入或離開longshuai的數據包

tcpdump host longshuai

(4).打印helios<-->hot或helios<-->ace之間通信的數據包

tcpdump host helios and \( hot or ace \)

(5).打印ace與任何其他主機之間通信的IP數據包,但不包括與helios之間的數據包

tcpdump ip host ace and not helios

(6).截獲主機hostname發送的所有數據

tcpdump src host hostname

(7).監視所有發送到主機hostname的數據包

tcpdump dst host hostname

(8).監視指定主機和端口的數據包

tcpdump tcp port 22 and host hostname

(9).對本機的udp 123端口進行監視(123為ntp的服務端口)

tcpdump udp port 123

(10).監視指定網絡的數據包,如本機與192.168網段通信的數據包,"-c 10"表示只抓取10個包

tcpdump -c 10 net 192.168

(11).打印所有通過網關snup的ftp數據包(注意,表達式被單引號括起來了,這可以防止shell對其中的括號進行錯誤解析)

shell> tcpdump 'gateway snup and (port ftp or ftp-data)'

(12).抓取ping包

 
[root@server2 ~]# tcpdump -c 5 -nn -i eth0 icmp 

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
12:11:23.273638 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id 16422, seq 10, length 64
12:11:23.273666 IP 192.168.100.62 > 192.168.100.70: ICMP echo reply, id 16422, seq 10, length 64
12:11:24.356915 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id 16422, seq 11, length 64
12:11:24.356936 IP 192.168.100.62 > 192.168.100.70: ICMP echo reply, id 16422, seq 11, length 64
12:11:25.440887 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id 16422, seq 12, length 64
5 packets captured
6 packets received by filter
0 packets dropped by kernel
 

如果明確要抓取主機為192.168.100.70對本機的ping,則使用and操作符。

 
[root@server2 ~]# tcpdump -c 5 -nn -i eth0 icmp and src 192.168.100.62

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
12:09:29.957132 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id 16166, seq 1, length 64
12:09:31.041035 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id 16166, seq 2, length 64
12:09:32.124562 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id 16166, seq 3, length 64
12:09:33.208514 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id 16166, seq 4, length 64
12:09:34.292222 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id 16166, seq 5, length 64
5 packets captured
5 packets received by filter
0 packets dropped by kernel
 

注意不能直接寫icmp src 192.168.100.70,因為icmp協議不支持直接應用host這個type。

(13).抓取到本機22端口包

 
[root@server2 ~]# tcpdump -c 10 -nn -i eth0 tcp dst port 22  

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
12:06:57.574293 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 535528834, win 2053, length 0
12:06:57.629125 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 193, win 2052, length 0
12:06:57.684688 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 385, win 2051, length 0
12:06:57.738977 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 577, win 2050, length 0
12:06:57.794305 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 769, win 2050, length 0
12:06:57.848720 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 961, win 2049, length 0
12:06:57.904057 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 1153, win 2048, length 0
12:06:57.958477 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 1345, win 2047, length 0
12:06:58.014338 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 1537, win 2053, length 0
12:06:58.069361 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 1729, win 2052, length 0
10 packets captured
10 packets received by filter
0 packets dropped by kernel
 

(14).解析包數據

 
[root@server2 ~]# tcpdump -c 2 -q -XX -vvv -nn -i eth0 tcp dst port 22
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
12:15:54.788812 IP (tos 0x0, ttl 64, id 19303, offset 0, flags [DF], proto TCP (6), length 40)
    192.168.100.1.5788 > 192.168.100.62.22: tcp 0
        0x0000:  000c 2908 9234 0050 56c0 0008 0800 4500  ..)..4.PV.....E.
        0x0010:  0028 4b67 4000 4006 a5d8 c0a8 6401 c0a8  .(Kg@.@.....d...
        0x0020:  643e 169c 0016 2426 5fd6 1fec 2b62 5010  d>....$&_...+bP.
        0x0030:  0803 7844 0000 0000 0000 0000            ..xD........
12:15:54.842641 IP (tos 0x0, ttl 64, id 19304, offset 0, flags [DF], proto TCP (6), length 40)
    192.168.100.1.5788 > 192.168.100.62.22: tcp 0
        0x0000:  000c 2908 9234 0050 56c0 0008 0800 4500  ..)..4.PV.....E.
        0x0010:  0028 4b68 4000 4006 a5d7 c0a8 6401 c0a8  .(Kh@.@.....d...
        0x0020:  643e 169c 0016 2426 5fd6 1fec 2d62 5010  d>....$&_...-bP.
        0x0030:  0801 7646 0000 0000 0000 0000            ..vF........
2 packets captured
2 packets received by filter
0 packets dropped by kernel
 

總的來說,tcpdump對基本的數據包抓取方法還是較簡單的。只要掌握有限的幾個選項(-nn -XX -vvv -i -c -q),再組合表達式即可。

 

 

tcpdump抓包時,如果-i選項指定為一個網卡地址,那么抓取的數據包數據鏈路層是以太網頭部;如果指定any,則以太網頭部將被替換為linux cooked capture頭部

 
# tcpdump -i any -w linux_sll.pcap
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 96 bytes

 

1
2
# tcpdump -i eth1 -w enet.pcap
tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes

 

tcpdump抓包時可以通過 -y 選項來指定data link type,不過測試發現 -i 選項指定 any 時,不支持抓獲的包的data link type 為以太網 :

1
2
3
4
5
# tcpdump -i any -w test.pcap -y EN10MB
tcpdump: EN10MB is not one of the DLTs supported by  this  device
  # tcpdump -i eth1 -w test.pcap -y EN10MB
tcpdump: data link type EN10MB
  #

 

tcpdump抓包時可以通過 -y 選項來指定data link type,不過測試發現 -i 選項指定 any 時,不支持抓獲的包的data link type 為以太網 :

1
2
3
4
5
# tcpdump -i any -w test.pcap -y EN10MB
tcpdump: EN10MB is not one of the DLTs supported by  this  device
  # tcpdump -i eth1 -w test.pcap -y EN10MB
tcpdump: data link type EN10MB
  #

 

這時,若需要將linux cooked capture格式的包轉換為Ethernet格式,有那么幾種方法:

1. 寫代碼讀出每一個包后再改寫到新文件(使用libpcap或者基於pcap頭部結構體偏移);

2. tcpdump 3.0+ 版本下,可以用tcprewrite直接改寫,這應該是最快捷的方法;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
DLT Plugins
As of 3.0, tcprewrite uses plugins to support different DLT/Layer 2 types. This not only makes the <br>code easier to maintain, but also helps make things clearer  for  users regarding what is and isn't <br>supported. Each plugin may support reading and/or writing packets. By  default , the plugin used to <br>read packets is also used  for  output, but you can override the output plugin  using  the --dlt option. <br>Changing the DLT plugin allows you to convert the packets from one DLT/Layer 2 type to another type. <br>This allows you  for  example to capture traffic on say an Ethernet interface and replay over Cisco <br>HDLC or capture on a BSD Loopback interface and replay over Ethernet.
 
Plugins supported in output mode:
 
Ethernet (enet)
Cisco HDLC (hdlc)
User defined Layer 2 (user)
Plugins supported in input mode:
 
Ethernet
Cisco HDLC
Linux SLL
BSD Loopback
BSD Null
Raw IP
802.11
Juniper Ethernet (version >= 4.0)
Hence,  if  you have a pcap in one of the supported input DLT types, you can convert it to one of the <br>supported output DLT type by  using  the --dlt=<output> option. Depending on the input DLT you may <br>need to provide additional DLT plugin flags.

 

tcprewrite轉換命令如下:

 # tcpdump -r linux_sll.pcap
reading from file linux_sll.pcap, link-type LINUX_SLL (Linux cooked)
 # tcprewrite --dlt=enet --infile=linux_sll.pcap  --outfile=enet.pcap
 # tcpdump -r enet.pcap
reading from file enet.pcap, link-type EN10MB (Ethernet)
 #

 

唯一有點問題的,是轉換后的數據的Destination-Mac為空, 對這個字段有需求的要注意下:

 

可以參考的網址:

https://wiki.wireshark.org/SLL

http://www.tcpdump.org/linktypes.html

http://tcpreplay.synfin.net/wiki/tcprewrite

 

其它:

1
2
# tips 刪除vlan
# tcprewrite --enet-vlan=del --infile=enet.pcap --outfile=output.pcap

 

 

 

 

tcpdump 是一個命令行實用工具,允許你抓取和分析經過系統的流量數據包。它通常被用作於網絡故障分析工具以及安全工具。

tcpdump 是一款強大的工具,支持多種選項和過濾規則,適用場景十分廣泛。由於它是命令行工具,因此適用於在遠程服務器或者沒有圖形界面的設備中收集數據包以便於事后分析。它可以在后台啟動,也可以用 cron 等定時工具創建定時任務啟用它。

本文中,我們將討論 tcpdump 最常用的一些功能。

1、在 Linux 中安裝 tcpdump

tcpdump 支持多種 Linux 發行版,所以你的系統中很有可能已經安裝了它。用下面的命令檢查一下是否已經安裝了 tcpdump

  1. $ which tcpdump
  2. /usr/sbin/tcpdump

如果還沒有安裝 tcpdump,你可以用軟件包管理器安裝它。 例如,在 CentOS 或者 Red Hat Enterprise 系統中,用如下命令安裝 tcpdump

  1. sudo yum install -tcpdump

tcpdump 依賴於 libpcap,該庫文件用於捕獲網絡數據包。如果該庫文件也沒有安裝,系統會根據依賴關系自動安裝它。

現在你可以開始抓包了。

2、用 tcpdump 抓包

使用 tcpdump 抓包,需要管理員權限,因此下面的示例中絕大多數命令都是以 sudo 開頭。

首先,先用 tcpdump -D 命令列出可以抓包的網絡接口:

  1. sudo tcpdump -D
  2. 1.eth0
  3. 2.virbr0
  4. 3.eth1
  5. 4.any (Pseudo-device that captures on all interfaces)
  6. 5.lo [Loopback]

如上所示,可以看到我的機器中所有可以抓包的網絡接口。其中特殊接口 any 可用於抓取所有活動的網絡接口的數據包。

我們就用如下命令先對 any 接口進行抓包:

  1. sudo tcpdump -i any
  2. tcpdump: verbose output suppressed, use -or -vv for full protocol decode
  3. listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
  4. 09:56:18.293641 IP rhel75.localdomain.ssh > 192.168.64.1.56322: Flags [P.], seq 3770820720:3770820916, ack 3503648727, win 309, options [nop,nop,TS val 76577898 ecr 510770929], length 196
  5. 09:56:18.293794 IP 192.168.64.1.56322 > rhel75.localdomain.ssh: Flags [.], ack 196, win 391, options [nop,nop,TS val 510771017 ecr 76577898], length 0
  6. 09:56:18.295058 IP rhel75.59883 > gateway.domain: 2486+ PTR? 1.64.168.192.in-addr.arpa. (43)
  7. 09:56:18.310225 IP gateway.domain > rhel75.59883: 2486 NXDomain* 0/1/0 (102)
  8. 09:56:18.312482 IP rhel75.49685 > gateway.domain: 34242+ PTR? 28.64.168.192.in-addr.arpa. (44)
  9. 09:56:18.322425 IP gateway.domain > rhel75.49685: 34242 NXDomain* 0/1/0 (103)
  10. 09:56:18.323164 IP rhel75.56631 > gateway.domain: 29904+ PTR? 1.122.168.192.in-addr.arpa. (44)
  11. 09:56:18.323342 IP rhel75.localdomain.ssh > 192.168.64.1.56322: Flags [P.], seq 196:584, ack 1, win 309, options [nop,nop,TS val 76577928 ecr 510771017], length 388
  12. 09:56:18.323563 IP 192.168.64.1.56322 > rhel75.localdomain.ssh: Flags [.], ack 584, win 411, options [nop,nop,TS val 510771047 ecr 76577928], length 0
  13. 09:56:18.335569 IP gateway.domain > rhel75.56631: 29904 NXDomain* 0/1/0 (103)
  14. 09:56:18.336429 IP rhel75.44007 > gateway.domain: 61677+ PTR? 98.122.168.192.in-addr.arpa. (45)
  15. 09:56:18.336655 IP gateway.domain > rhel75.44007: 61677* 1/0/0 PTR rhel75. (65)
  16. 09:56:18.337177 IP rhel75.localdomain.ssh > 192.168.64.1.56322: Flags [P.], seq 584:1644, ack 1, win 309, options [nop,nop,TS val 76577942 ecr 510771047], length 1060
  17. ---- SKIPPING LONG OUTPUT -----
  18. 09:56:19.342939 IP 192.168.64.1.56322 > rhel75.localdomain.ssh: Flags [.], ack 1752016, win 1444, options [nop,nop,TS val 510772067 ecr 76578948], length 0
  19. ^C
  20. 9003 packets captured
  21. 9010 packets received by filter
  22. 7 packets dropped by kernel
  23. $

tcpdump 會持續抓包直到收到中斷信號。你可以按 Ctrl+C 來停止抓包。正如上面示例所示,tcpdump 抓取了超過 9000 個數據包。在這個示例中,由於我是通過 ssh 連接到服務器,所以 tcpdump 也捕獲了所有這類數據包。-c 選項可以用於限制 tcpdump 抓包的數量:

  1. sudo tcpdump -i any -5
  2. tcpdump: verbose output suppressed, use -or -vv for full protocol decode
  3. listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
  4. 11:21:30.242740 IP rhel75.localdomain.ssh > 192.168.64.1.56322: Flags [P.], seq 3772575680:3772575876, ack 3503651743, win 309, options [nop,nop,TS val 81689848 ecr 515883153], length 196
  5. 11:21:30.242906 IP 192.168.64.1.56322 > rhel75.localdomain.ssh: Flags [.], ack 196, win 1443, options [nop,nop,TS val 515883235 ecr 81689848], length 0
  6. 11:21:30.244442 IP rhel75.43634 > gateway.domain: 57680+ PTR? 1.64.168.192.in-addr.arpa. (43)
  7. 11:21:30.244829 IP gateway.domain > rhel75.43634: 57680 NXDomain 0/0/0 (43)
  8. 11:21:30.247048 IP rhel75.33696 > gateway.domain: 37429+ PTR? 28.64.168.192.in-addr.arpa. (44)
  9. 5 packets captured
  10. 12 packets received by filter
  11. 0 packets dropped by kernel
  12. $

如上所示,tcpdump 在抓取 5 個數據包后自動停止了抓包。這在有些場景中十分有用 —— 比如你只需要抓取少量的數據包用於分析。當我們需要使用過濾規則抓取特定的數據包(如下所示)時,-c 的作用就十分突出了。

在上面示例中,tcpdump 默認是將 IP 地址和端口號解析為對應的接口名以及服務協議名稱。而通常在網絡故障排查中,使用 IP 地址和端口號更便於分析問題;用 -n 選項顯示 IP 地址,-nn 選項顯示端口號:

  1. sudo tcpdump -i any -c5 -nn
  2. tcpdump: verbose output suppressed, use -or -vv for full protocol decode
  3. listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
  4. 23:56:24.292206 IP 192.168.64.28.22 > 192.168.64.1.35110: Flags [P.], seq 166198580:166198776, ack 2414541257, win 309, options [nop,nop,TS val 615664 ecr 540031155], length 196
  5. 23:56:24.292357 IP 192.168.64.1.35110 > 192.168.64.28.22: Flags [.], ack 196, win 1377, options [nop,nop,TS val 540031229 ecr 615664], length 0
  6. 23:56:24.292570 IP 192.168.64.28.22 > 192.168.64.1.35110: Flags [P.], seq 196:568, ack 1, win 309, options [nop,nop,TS val 615664 ecr 540031229], length 372
  7. 23:56:24.292655 IP 192.168.64.1.35110 > 192.168.64.28.22: Flags [.], ack 568, win 1400, options [nop,nop,TS val 540031229 ecr 615664], length 0
  8. 23:56:24.292752 IP 192.168.64.28.22 > 192.168.64.1.35110: Flags [P.], seq 568:908, ack 1, win 309, options [nop,nop,TS val 615664 ecr 540031229], length 340
  9. 5 packets captured
  10. 6 packets received by filter
  11. 0 packets dropped by kernel

如上所示,抓取的數據包中顯示 IP 地址和端口號。這樣還可以阻止 tcpdump 發出 DNS 查找,有助於在網絡故障排查中減少數據流量。

現在你已經會抓包了,讓我們來分析一下這些抓包輸出的含義吧。

3、理解抓取的報文

tcpdump 能夠抓取並解碼多種協議類型的數據報文,如 TCP、UDP、ICMP 等等。雖然這里我們不可能介紹所有的數據報文類型,但可以分析下 TCP 類型的數據報文,來幫助你入門。更多有關 tcpdump 的詳細介紹可以參考其 幫助手冊tcpdump 抓取的 TCP 報文看起來如下:

  1. 08:41:13.729687 IP 192.168.64.28.22 > 192.168.64.1.41916: Flags [P.], seq 196:568, ack 1, win 309, options [nop,nop,TS val 117964079 ecr 816509256], length 372

具體的字段根據不同的報文類型會有不同,但上面這個例子是一般的格式形式。

第一個字段 08:41:13.729687 是該數據報文被抓取的系統本地時間戳。

然后,IP 是網絡層協議類型,這里是 IPv4,如果是 IPv6 協議,該字段值是 IP6

192.168.64.28.22 是源 ip 地址和端口號,緊跟其后的是目的 ip 地址和其端口號,這里是 192.168.64.1.41916

在源 IP 和目的 IP 之后,可以看到是 TCP 報文標記段 Flags [P.]。該字段通常取值如下:

標志類型 描述
S SYN Connection Start
F FIN Connection Finish
P PUSH Data push
R RST Connection reset
. ACK Acknowledgment

該字段也可以是這些值的組合,例如 [S.] 代表 SYN-ACK 數據包。

接下來是該數據包中數據的序列號。對於抓取的第一個數據包,該字段值是一個絕對數字,后續包使用相對數值,以便更容易查詢跟蹤。例如此處 seq 196:568 代表該數據包包含該數據流的第 196 到 568 字節。

接下來是 ack 值:ack 1。該數據包是數據發送方,ack 值為 1。在數據接收方,該字段代表數據流上的下一個預期字節數據,例如,該數據流中下一個數據包的 ack 值應該是 568。

接下來字段是接收窗口大小 win 309,它表示接收緩沖區中可用的字節數,后跟 TCP 選項如 MSS(最大段大小)或者窗口比例值。更詳盡的 TCP 協議內容請參考 Transmission Control Protocol(TCP) Parameters

最后,length 372 代表數據包有效載荷字節長度。這個長度和 seq 序列號中字節數值長度是不一樣的。

現在讓我們學習如何過濾數據報文以便更容易的分析定位問題。

4、過濾數據包

正如上面所提,tcpdump 可以抓取很多種類型的數據報文,其中很多可能和我們需要查找的問題並沒有關系。舉個例子,假設你正在定位一個與 web 服務器連接的網絡問題,就不必關系 SSH 數據報文,因此在抓包結果中過濾掉 SSH 報文可能更便於你分析問題。

tcpdump 有很多參數選項可以設置數據包過濾規則,例如根據源 IP 以及目的 IP 地址,端口號,協議等等規則來過濾數據包。下面就介紹一些最常用的過濾方法。

協議

在命令中指定協議便可以按照協議類型來篩選數據包。比方說用如下命令只要抓取 ICMP 報文:

  1. sudo tcpdump -i any -c5 icmp
  2. tcpdump: verbose output suppressed, use -or -vv for full protocol decode
  3. listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes

然后再打開一個終端,去 ping 另一台機器:

  1. ping opensource.com
  2. PING opensource.com (54.204.39.132) 56(84) bytes of data.
  3. 64 bytes from ec2-54-204-39-132.compute-1.amazonaws.com (54.204.39.132): icmp_seq=1 ttl=47 time=39.6 ms

回到運行 tcpdump 命令的終端中,可以看到它篩選出了 ICMP 報文。這里 tcpdump 並沒有顯示有關 opensource.com 的域名解析數據包:

  1. 09:34:20.136766 IP rhel75 > ec2-54-204-39-132.compute-1.amazonaws.com: ICMP echo request, id 20361, seq 1, length 64
  2. 09:34:20.176402 IP ec2-54-204-39-132.compute-1.amazonaws.com > rhel75: ICMP echo reply, id 20361, seq 1, length 64
  3. 09:34:21.140230 IP rhel75 > ec2-54-204-39-132.compute-1.amazonaws.com: ICMP echo request, id 20361, seq 2, length 64
  4. 09:34:21.180020 IP ec2-54-204-39-132.compute-1.amazonaws.com > rhel75: ICMP echo reply, id 20361, seq 2, length 64
  5. 09:34:22.141777 IP rhel75 > ec2-54-204-39-132.compute-1.amazonaws.com: ICMP echo request, id 20361, seq 3, length 64
  6. 5 packets captured
  7. 5 packets received by filter
  8. 0 packets dropped by kernel

主機

用 host 參數只抓取和特定主機相關的數據包:

  1. sudo tcpdump -i any -c5 -nn host 54.204.39.132
  2. tcpdump: verbose output suppressed, use -or -vv for full protocol decode
  3. listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
  4. 09:54:20.042023 IP 192.168.122.98.39326 > 54.204.39.132.80: Flags [S], seq 1375157070, win 29200, options [mss 1460,sackOK,TS val 122350391 ecr 0,nop,wscale 7], length 0
  5. 09:54:20.088127 IP 54.204.39.132.80 > 192.168.122.98.39326: Flags [S.], seq 1935542841, ack 1375157071, win 28960, options [mss 1460,sackOK,TS val 522713542 ecr 122350391,nop,wscale 9], length 0
  6. 09:54:20.088204 IP 192.168.122.98.39326 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 122350437 ecr 522713542], length 0
  7. 09:54:20.088734 IP 192.168.122.98.39326 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 122350438 ecr 522713542], length 112: HTTP: GET / HTTP/1.1
  8. 09:54:20.129733 IP 54.204.39.132.80 > 192.168.122.98.39326: Flags [.], ack 113, win 57, options [nop,nop,TS val 522713552 ecr 122350438], length 0
  9. 5 packets captured
  10. 5 packets received by filter
  11. 0 packets dropped by kernel

如上所示,只抓取和顯示與 54.204.39.132 有關的數據包。

端口號

tcpdump 可以根據服務類型或者端口號來篩選數據包。例如,抓取和 HTTP 服務相關的數據包:

  1. sudo tcpdump -i any -c5 -nn port 80
  2. tcpdump: verbose output suppressed, use -or -vv for full protocol decode
  3. listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
  4. 09:58:28.790548 IP 192.168.122.98.39330 > 54.204.39.132.80: Flags [S], seq 1745665159, win 29200, options [mss 1460,sackOK,TS val 122599140 ecr 0,nop,wscale 7], length 0
  5. 09:58:28.834026 IP 54.204.39.132.80 > 192.168.122.98.39330: Flags [S.], seq 4063583040, ack 1745665160, win 28960, options [mss 1460,sackOK,TS val 522775728 ecr 122599140,nop,wscale 9], length 0
  6. 09:58:28.834093 IP 192.168.122.98.39330 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 122599183 ecr 522775728], length 0
  7. 09:58:28.834588 IP 192.168.122.98.39330 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 122599184 ecr 522775728], length 112: HTTP: GET / HTTP/1.1
  8. 09:58:28.878445 IP 54.204.39.132.80 > 192.168.122.98.39330: Flags [.], ack 113, win 57, options [nop,nop,TS val 522775739 ecr 122599184], length 0
  9. 5 packets captured
  10. 5 packets received by filter
  11. 0 packets dropped by kernel

IP 地址/主機名

同樣,你也可以根據源 IP 地址或者目的 IP 地址或者主機名來篩選數據包。例如抓取源 IP 地址為 192.168.122.98 的數據包:

  1. sudo tcpdump -i any -c5 -nn src 192.168.122.98
  2. tcpdump: verbose output suppressed, use -or -vv for full protocol decode
  3. listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
  4. 10:02:15.220824 IP 192.168.122.98.39436 > 192.168.122.1.53: 59332+ A? opensource.com. (32)
  5. 10:02:15.220862 IP 192.168.122.98.39436 > 192.168.122.1.53: 20749+ AAAA? opensource.com. (32)
  6. 10:02:15.364062 IP 192.168.122.98.39334 > 54.204.39.132.80: Flags [S], seq 1108640533, win 29200, options [mss 1460,sackOK,TS val 122825713 ecr 0,nop,wscale 7], length 0
  7. 10:02:15.409229 IP 192.168.122.98.39334 > 54.204.39.132.80: Flags [.], ack 669337581, win 229, options [nop,nop,TS val 122825758 ecr 522832372], length 0
  8. 10:02:15.409667 IP 192.168.122.98.39334 > 54.204.39.132.80: Flags [P.], seq 0:112, ack 1, win 229, options [nop,nop,TS val 122825759 ecr 522832372], length 112: HTTP: GET / HTTP/1.1
  9. 5 packets captured
  10. 5 packets received by filter
  11. 0 packets dropped by kernel

注意此處示例中抓取了來自源 IP 地址 192.168.122.98 的 53 端口以及 80 端口的數據包,它們的應答包沒有顯示出來因為那些包的源 IP 地址已經變了。

相對的,使用 dst 就是按目的 IP/主機名來篩選數據包。

  1. sudo tcpdump -i any -c5 -nn dst 192.168.122.98
  2. tcpdump: verbose output suppressed, use -or -vv for full protocol decode
  3. listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
  4. 10:05:03.572931 IP 192.168.122.1.53 > 192.168.122.98.47049: 2248 1/0/0 A 54.204.39.132 (48)
  5. 10:05:03.572944 IP 192.168.122.1.53 > 192.168.122.98.47049: 33770 0/0/0 (32)
  6. 10:05:03.621833 IP 54.204.39.132.80 > 192.168.122.98.39338: Flags [S.], seq 3474204576, ack 3256851264, win 28960, options [mss 1460,sackOK,TS val 522874425 ecr 122993922,nop,wscale 9], length 0
  7. 10:05:03.667767 IP 54.204.39.132.80 > 192.168.122.98.39338: Flags [.], ack 113, win 57, options [nop,nop,TS val 522874436 ecr 122993972], length 0
  8. 10:05:03.672221 IP 54.204.39.132.80 > 192.168.122.98.39338: Flags [P.], seq 1:643, ack 113, win 57, options [nop,nop,TS val 522874437 ecr 122993972], length 642: HTTP: HTTP/1.1 302 Found
  9. 5 packets captured
  10. 5 packets received by filter
  11. 0 packets dropped by kernel

多條件篩選

當然,可以使用多條件組合來篩選數據包,使用 and 以及 or 邏輯操作符來創建過濾規則。例如,篩選來自源 IP 地址 192.168.122.98 的 HTTP 數據包:

  1. sudo tcpdump -i any -c5 -nn src 192.168.122.98 and port 80
  2. tcpdump: verbose output suppressed, use -or -vv for full protocol decode
  3. listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
  4. 10:08:00.472696 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [S], seq 2712685325, win 29200, options [mss 1460,sackOK,TS val 123170822 ecr 0,nop,wscale 7], length 0
  5. 10:08:00.516118 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [.], ack 268723504, win 229, options [nop,nop,TS val 123170865 ecr 522918648], length 0
  6. 10:08:00.516583 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [P.], seq 0:112, ack 1, win 229, options [nop,nop,TS val 123170866 ecr 522918648], length 112: HTTP: GET / HTTP/1.1
  7. 10:08:00.567044 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [.], ack 643, win 239, options [nop,nop,TS val 123170916 ecr 522918661], length 0
  8. 10:08:00.788153 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [F.], seq 112, ack 643, win 239, options [nop,nop,TS val 123171137 ecr 522918661], length 0
  9. 5 packets captured
  10. 5 packets received by filter
  11. 0 packets dropped by kernel

你也可以使用括號來創建更為復雜的過濾規則,但在 shell 中請用引號包含你的過濾規則以防止被識別為 shell 表達式:

  1. sudo tcpdump -i any -c5 -nn "port 80 and (src 192.168.122.98 or src 54.204.39.132)"
  2. tcpdump: verbose output suppressed, use -or -vv for full protocol decode
  3. listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
  4. 10:10:37.602214 IP 192.168.122.98.39346 > 54.204.39.132.80: Flags [S], seq 871108679, win 29200, options [mss 1460,sackOK,TS val 123327951 ecr 0,nop,wscale 7], length 0
  5. 10:10:37.650651 IP 54.204.39.132.80 > 192.168.122.98.39346: Flags [S.], seq 854753193, ack 871108680, win 28960, options [mss 1460,sackOK,TS val 522957932 ecr 123327951,nop,wscale 9], length 0
  6. 10:10:37.650708 IP 192.168.122.98.39346 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 123328000 ecr 522957932], length 0
  7. 10:10:37.651097 IP 192.168.122.98.39346 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 123328000 ecr 522957932], length 112: HTTP: GET / HTTP/1.1
  8. 10:10:37.692900 IP 54.204.39.132.80 > 192.168.122.98.39346: Flags [.], ack 113, win 57, options [nop,nop,TS val 522957942 ecr 123328000], length 0
  9. 5 packets captured
  10. 5 packets received by filter
  11. 0 packets dropped by kernel

該例子中我們只抓取了來自源 IP 為 192.168.122.98 或者 54.204.39.132 的 HTTP (端口號80)的數據包。使用該方法就很容易抓取到數據流中交互雙方的數據包了。

5、檢查數據包內容

在以上的示例中,我們只按數據包頭部的信息來建立規則篩選數據包,例如源地址、目的地址、端口號等等。有時我們需要分析網絡連接問題,可能需要分析數據包中的內容來判斷什么內容需要被發送、什么內容需要被接收等。tcpdump 提供了兩個選項可以查看數據包內容,-X 以十六進制打印出數據報文內容,-A 打印數據報文的 ASCII 值。

例如,HTTP 請求報文內容如下:

  1. sudo tcpdump -i any -c10 -nn -A port 80
  2. tcpdump: verbose output suppressed, use -or -vv for full protocol decode
  3. listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
  4. 13:02:14.871803 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [S], seq 2546602048, win 29200, options [mss 1460,sackOK,TS val 133625221 ecr 0,nop,wscale 7], length 0
  5. E..<..@.@.....zb6.'....P...@......r............
  6. ............................
  7. 13:02:14.910734 IP 54.204.39.132.80 > 192.168.122.98.39366: Flags [S.], seq 1877348646, ack 2546602049, win 28960, options [mss 1460,sackOK,TS val 525532247 ecr 133625221,nop,wscale 9], length 0
  8. E..<..@./..a6.'...zb.P..o..&...A..q a..........
  9. .R.W.......     ................
  10. 13:02:14.910832 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 133625260 ecr 525532247], length 0
  11. E..4..@.@.....zb6.'....P...Ao..'...........
  12. .....R.W................
  13. 13:02:14.911808 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 133625261 ecr 525532247], length 112: HTTP: GET / HTTP/1.1
  14. E.....@.@..1..zb6.'....P...Ao..'...........
  15. .....R.WGET / HTTP/1.1
  16. User-Agent: Wget/1.14 (linux-gnu)
  17. Accept: */*
  18. Host: opensource.com
  19. Connection: Keep-Alive
  20. ................
  21. 13:02:14.951199 IP 54.204.39.132.80 > 192.168.122.98.39366: Flags [.], ack 113, win 57, options [nop,nop,TS val 525532257 ecr 133625261], length 0
  22. E..4.F@./.."6.'...zb.P..o..'.......9.2.....
  23. .R.a....................
  24. 13:02:14.955030 IP 54.204.39.132.80 > 192.168.122.98.39366: Flags [P.], seq 1:643, ack 113, win 57, options [nop,nop,TS val 525532258 ecr 133625261], length 642: HTTP: HTTP/1.1 302 Found
  25. E....G@./...6.'...zb.P..o..'.......9.......
  26. .R.b....HTTP/1.1 302 Found
  27. Server: nginx
  28. Date: Sun, 23 Sep 2018 17:02:14 GMT
  29. Content-Type: text/html; charset=iso-8859-1
  30. Content-Length: 207
  31. X-Content-Type-Options: nosniff
  32. Location: https://opensource.com/
  33. Cache-Control: max-age=1209600
  34. Expires: Sun, 07 Oct 2018 17:02:14 GMT
  35. X-Request-ID: v-6baa3acc-bf52-11e8-9195-22000ab8cf2d
  36. X-Varnish: 632951979
  37. Age: 0
  38. Via: 1.1 varnish (Varnish/5.2)
  39. X-Cache: MISS
  40. Connection: keep-alive
  41. <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
  42. <html><head>
  43. <title>302 Found</title>
  44. </head><body>
  45. <h1>Found</h1>
  46. <p>The document has moved <a href="https://opensource.com/">here</a>.</p>
  47. </body></html>
  48. ................
  49. 13:02:14.955083 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [.], ack 643, win 239, options [nop,nop,TS val 133625304 ecr 525532258], length 0
  50. E..4..@.@.....zb6.'....P....o..............
  51. .....R.b................
  52. 13:02:15.195524 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [F.], seq 113, ack 643, win 239, options [nop,nop,TS val 133625545 ecr 525532258], length 0
  53. E..4..@.@.....zb6.'....P....o..............
  54. .....R.b................
  55. 13:02:15.236592 IP 54.204.39.132.80 > 192.168.122.98.39366: Flags [F.], seq 643, ack 114, win 57, options [nop,nop,TS val 525532329 ecr 133625545], length 0
  56. E..4.H@./.. 6.'...zb.P..o..........9.I.....
  57. .R......................
  58. 13:02:15.236656 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [.], ack 644, win 239, options [nop,nop,TS val 133625586 ecr 525532329], length 0
  59. E..4..@.@.....zb6.'....P....o..............
  60. .....R..................
  61. 10 packets captured
  62. 10 packets received by filter
  63. 0 packets dropped by kernel

這對定位一些普通 HTTP 調用 API 接口的問題很有用。當然如果是加密報文,這個輸出也就沒多大用了。

6、保存抓包數據

tcpdump 提供了保存抓包數據的功能以便后續分析數據包。例如,你可以夜里讓它在那里抓包,然后早上起來再去分析它。同樣當有很多數據包時,顯示過快也不利於分析,將數據包保存下來,更有利於分析問題。

使用 -w 選項來保存數據包而不是在屏幕上顯示出抓取的數據包:

  1. sudo tcpdump -i any -c10 -nn -w webserver.pcap port 80
  2. [sudo] password for ricardo:
  3. tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
  4. 10 packets captured
  5. 10 packets received by filter
  6. 0 packets dropped by kernel

該命令將抓取的數據包保存到文件 webserver.pcap。后綴名 pcap 表示文件是抓取的數據包格式。

正如示例中所示,保存數據包到文件中時屏幕上就沒有任何有關數據報文的輸出,其中 -c10 表示抓取到 10 個數據包后就停止抓包。如果想有一些反饋來提示確實抓取到了數據包,可以使用 -v 選項。

tcpdump 將數據包保存在二進制文件中,所以不能簡單的用文本編輯器去打開它。使用 -r 選項參數來閱讀該文件中的報文內容:

  1. tcpdump -nn -r webserver.pcap
  2. reading from file webserver.pcap, link-type LINUX_SLL (Linux cooked)
  3. 13:36:57.679494 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [S], seq 3709732619, win 29200, options [mss 1460,sackOK,TS val 135708029 ecr 0,nop,wscale 7], length 0
  4. 13:36:57.718932 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [S.], seq 1999298316, ack 3709732620, win 28960, options [mss 1460,sackOK,TS val 526052949 ecr 135708029,nop,wscale 9], length 0
  5. 13:36:57.719005 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 135708068 ecr 526052949], length 0
  6. 13:36:57.719186 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 135708068 ecr 526052949], length 112: HTTP: GET / HTTP/1.1
  7. 13:36:57.756979 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [.], ack 113, win 57, options [nop,nop,TS val 526052959 ecr 135708068], length 0
  8. 13:36:57.760122 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [P.], seq 1:643, ack 113, win 57, options [nop,nop,TS val 526052959 ecr 135708068], length 642: HTTP: HTTP/1.1 302 Found
  9. 13:36:57.760182 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [.], ack 643, win 239, options [nop,nop,TS val 135708109 ecr 526052959], length 0
  10. 13:36:57.977602 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [F.], seq 113, ack 643, win 239, options [nop,nop,TS val 135708327 ecr 526052959], length 0
  11. 13:36:58.022089 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [F.], seq 643, ack 114, win 57, options [nop,nop,TS val 526053025 ecr 135708327], length 0
  12. 13:36:58.022132 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [.], ack 644, win 239, options [nop,nop,TS val 135708371 ecr 526053025], length 0
  13. $

這里不需要管理員權限 sudo 了,因為此刻並不是在網絡接口處抓包。

你還可以使用我們討論過的任何過濾規則來過濾文件中的內容,就像使用實時數據一樣。 例如,通過執行以下命令從源 IP 地址 54.204.39.132 檢查文件中的數據包:

  1. tcpdump -nn -r webserver.pcap src 54.204.39.132
  2. reading from file webserver.pcap, link-type LINUX_SLL (Linux cooked)
  3. 13:36:57.718932 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [S.], seq 1999298316, ack 3709732620, win 28960, options [mss 1460,sackOK,TS val 526052949 ecr 135708029,nop,wscale 9], length 0
  4. 13:36:57.756979 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [.], ack 113, win 57, options [nop,nop,TS val 526052959 ecr 135708068], length 0
  5. 13:36:57.760122 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [P.], seq 1:643, ack 113, win 57, options [nop,nop,TS val 526052959 ecr 135708068], length 642: HTTP: HTTP/1.1 302 Found
  6. 13:36:58.022089 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [F.], seq 643, ack 114, win 57, options [nop,nop,TS val 526053025 ecr 135708327], length 0

下一步做什么?

以上的基本功能已經可以幫助你使用強大的 tcpdump 抓包工具了。更多的內容請參考 tcpdump 網站 以及它的 幫助文件

tcpdump 命令行工具為分析網絡流量數據包提供了強大的靈活性。如果需要使用圖形工具來抓包請參考 Wireshark

Wireshark 還可以用來讀取 tcpdump 保存的 pcap 文件。你可以使用 tcpdump 命令行在沒有 GUI 界面的遠程機器上抓包然后在 Wireshark 中分析數據包。


via: https://opensource.com/article/18/10/introduction-tcpdump

 


免責聲明!

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



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