linux命令--tcpdump


tcpdump是一個用於截取網絡分組,並輸出分組內容的工具,簡單說就是數據包抓包工具。tcpdump憑藉強大的功能和靈活的截取策略,使其成爲Linux系統下用於網絡分析和問題排查的首選工具。


tcpdump提供了源代碼,公開了接口,因此具備很強的可擴展性,對於網絡維護和入侵者都是非常有用的工具。tcpdump存在於基本的Linux系統中,由於它需要將網絡界面設置爲混雜模式,普通用戶不能正常執行,但具備root權限的用戶可以直接執行它來獲取網絡上的信息。因此係統中存在網絡分析工具主要不是對本機安全的威脅,而是對網絡上的其他計算機的安全存在威脅。


一、概述
顧名思義,tcpdump可以將網絡中傳送的數據包的“頭”完全截獲下來提供分析。它支持針對網絡層、協議、主機、網絡或端口的過濾,並提供and、or、not等邏輯語句來幫助你去掉無用的信息。


二、選項介紹
-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 直接將分組寫入文件中,而不是不分析並打印出來。



三、指令操作

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

監視指定網絡接口的數據包

tcpdump -i eth1
如果不指定網卡,默認tcpdump只會監視第一個網絡接口,一般是eth0,我的阿里雲是雙網卡,eth0是內網網卡,eth1纔是外網網卡。所以一般要指定 -i eth1


1.過濾主機
抓取所有經過eth1,目的或源地址是192.168.1.1的網絡數據
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


2.過濾端口
抓取所有經過eth1,目的或源端口是25的網絡數據
tcpdump -i eth1 port 25
指定源端口
tcpdump -i eth1 src port 25
指定目的端口
tcpdump -i eth1 dst port 25


3.網絡過濾

tcpdump -i eth1 net 192.168
tcpdump -i eth1 src net 192.168
tcpdump -i eth1 dst net 192.168


4.協議過濾

tcpdump -i eth1 arp
tcpdump -i eth1 ip
tcpdump -i eth1 tcp
tcpdump -i eth1 udp
tcpdump -i eth1 icmp


5.常用表達式

非 : ! or "not" (去掉雙引號)  
且 : && or "and"  
或 : || or "or"
抓取所有經過eth1,目的地址是192.168.1.254或192.168.1.200端口是80的TCP數據
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數據
tcpdump -i eth1 '((icmp) and ((ether dst host 00:01:02:03:04:05)))'
抓取所有經過eth1,目的網絡是192.168,但目的主機不是192.168.1.200的TCP數據
tcpdump -i eth1 '((tcp) and ((dst net 192.168) and (not dst host 192.168.1.200)))'


四、高級包頭過濾

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

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
操作符 : >, <, >=, <=, =, !=


IP頭


本文只針對IPv4。


2.IP選項設置了嗎?

“一般”的IP頭是20字節,但IP頭有選項設置,不能直接從偏移21字節處讀取數據。IP頭有個長度字段可以知道頭長度是否大於20字節。

通常第一個字節的二進制值是:01000101,分成兩個部分:

0100 = 4 表示IP版本 0101 = 5 表示IP頭32 bit的塊數,5 x 32 bits = 160 bits or 20 bytes

如果第一字節第二部分的值大於5,那麼表示頭有IP選項。

下面介紹兩種過濾方法:


a. 比較第一字節的值是否大於01000101,這可以判斷IPv4帶IP選項的數據和IPv6的數據。


01000101十進制等於69


如果設置了IP選項,那麼第一自己是01000110(十進制70),過濾規則:


tcpdump -i eth1 'ip[0] > 69'

當然這種過濾有問題,因爲前四位不確定是0100,ipv6的話是0110。所以用位操作比較好。



b. 位操作


0100 0101 : 第一字節的二進制
0000 1111 : 與操作
<=========
0000 0101 : 結果


正確的過濾方法

tcpdump -i eth1 'ip[0] & 15 > 5'
或者
tcpdump -i eth1 'ip[0] & 0x0f > 5'


3.分片標記


當發送端的MTU大於到目的路徑鏈路上的MTU時就會被分片,這段話有點拗口,權威的請參考《TCP/IP詳解》。


分片信息在IP頭的第七和第八字節:

Bit 0: 保留,必須是0
Bit 1: (DF) 0 = 可能分片, 1 = 不分片
Bit 2: (MF) 0 = 最後的分片, 1 = 還有分片


13位片偏移 字段只有在分片的時候才使用。


要抓帶DF位標記的不分片的包,第七字節的值應該是:


01000000 = 64


tcpdump -i eth1 'ip[6] = 64'


4.抓分片包


匹配MF,分片包
tcpdump -i eth1 'ip[6] = 32'
最後分片包的開始3位是0,但是有Fragment Offset字段。


匹配分片和最後分片
tcpdump -i eth1 '((ip[6:2] > 0) and (not ip[6] = 64))'
測試分片可以用下面的命令:


ping -M want -s 3000 192.168.1.1


5.匹配小TTL


TTL字段在第九字節,並且正好是完整的一個字節,TTL最大值是255,二進制爲11111111。


可以用下面的命令驗證一下:


$ ping -M want -s 3000 -t 256 192.168.1.200
ping: ttl 256 out of range


8位生存時間


在網關可以用下面的命令看看網絡中誰在使用traceroute
tcpdump -i eth1 'ip[8] < 5'


6.抓大於X字節的包


大於600字節
tcpdump -i eth1 'ip[2:2] > 600'



需要對tcp/ip協議頭基本結構及各字段特別瞭解,推薦看《TCP/IP詳解》。


TCP頭

抓取源端口大於1024的TCP數據包
tcpdump -i eth1 'tcp[0:2] > 1024'


只抓SYN包,第十四字節是二進制的00000010,也就是十進制的2

tcpdump -i eth1 'tcp[13] = 2'


抓SYN, ACK (00010010 or 18)

tcpdump -i eth1 'tcp[13] = 18'


抓SYN或者SYN-ACK
tcpdump -i eth1 'tcp[13] & 2 = 2'
用到了位操作,就是不管ACK位是啥。


抓PSH-ACK
tcpdump -i eth1 'tcp[13] = 24'
抓所有包含FIN標記的包
tcpdump -i eth1 'tcp[13] & 1 = 1'
抓RST
tcpdump -i eth1 'tcp[13] & 4 = 4'

所以要抓取帶過濾信息的tcp/ip包還是需要對tcp/ip基本結構比較瞭解纔行。


-c參數對於運維人員來說也比較常用,因爲流量比較大的服務器,靠人工CTRL+C還是抓的太多,甚至導致服務器宕機,於是可以用-c參數指定抓多少個包。


time tcpdump -nn -i eth0 'tcp[tcpflags] = tcp-syn' -c 10000 > /dev/null

上面的命令計算抓10000個SYN包花費多少時間,可以判斷訪問量大概是多少。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章