概述
man tcpdump 已閱
yum install tcpdump
Downloading Packages:
(1/2): libpcap-1.4.0-1.20130826git2dbcaa1.el6.x86_64.rpm | 130 kB 00:00
(2/2): tcpdump-4.0.0-3.20090921gitdf3cb4.2.el6.x86_64.rpm | 336 kB 00:00
[root@localhost ~]# rpm -qa|grep tcpdump
tcpdump-4.0.0-3.20090921gitdf3cb4.2.el6.x86_64
通俗的說,tcpdump是一個抓包工具,用於抓取互聯網上傳輸的數據包。
形象的說,tcpdump就好比是國家海關,駐扎在出入境的咽喉要道,凡是要入境和出境的集裝箱,海關人員總要打開箱子,看看里面都裝了點啥。
學術的說,tcpdump是一種嗅探器(sniffer),利用以太網的特性,通過將網卡適配器(NIC)置於混雜模式(promiscuous)來獲取傳輸在網絡中的信息包。
要用tcpdump抓包,請記住,一定要切換到root賬戶下,因為只有root才有權限將網卡變更為“混雜模式”。
Linux作為網絡服務器,特別是作為路由器和防火牆時,數據的采集和分析是必不可少的。所以,今天我們就來看看Linux中強大的網絡數據采集分析工具——tcpdump。
顯然為了安全起見,不用作網絡管理用途的計算機上不應該運行這一類的網絡分析軟件,為了屏蔽它們,可以屏蔽內核中的bpfilter偽設備。一般情況下網絡硬件和TCP/IP堆棧不支持接收或發送與本計算機無關的數據包,為了接收這些數據包,就必須使用網卡的混雜模式,並繞過標准的TCP/IP堆棧才行。在FreeBSD下,這就需要內核支持偽設備bpfilter。因此,在內核中取消bpfilter支持,就能屏蔽tcpdump之類的網絡分析工具。並且當網卡被設置為混雜模式時,系統會在控制台和日志文件中留下記錄,提醒管理員留意這台系統是否被用作攻擊同網絡的其他計算機的跳板。
vi /var/log/messages 當捕獲包時,會啟動在混雜模式下,在日志中留下記錄。
Sep 12 08:46:57 localhost kernel: device eth0 entered promiscuous mode
Sep 12 08:47:01 localhost kernel: device eth0 left promiscuous mode
May 15 16:27:20 host1 /kernel: fxp0: promiscuous mode enabled
解釋
總的的輸出格式為:系統時間 來源主機.端口 > 目標主機.端口 數據包參數
tcpdump可以分為三大部分內容,第一是“選項”,第二是“過濾表達式”,第三是“輸出信息”。
選項
tcpdump對截獲的數據並沒有進行徹底解碼,數據包內的大部分內容是使用十六進制的形式直接打印輸出的。顯然這不利於分析網絡故障,通常的解決辦法是先使用帶-w參數的tcpdump截獲數據並保存到文件中,然后再使用其他程序(如Wireshark)進行解碼分析。當然也應該定義過濾規則,以避免捕獲的數據包填滿整個硬盤。
-n 不把網絡地址轉換成名字;
-nn 不進行端口名稱的轉換。
-t 在輸出的每一行不打印時間戳
-vv 輸出詳細的報文信息;
-c 在收到指定的包的數目后,tcpdump就會停止
-e 在輸出行打印出數據鏈路層的頭部信息
-r 從指定的文件中讀取包(這些包一般通過-w選項產生)
-w 直接將包寫入文件中,並不分析和打印出來
-X 直接解包內容
使用-A選項,則tcpdump只會顯示ASCII形式的數據包內容,不會再以十六進制形式顯示;
使用-XX選項,則tcpdump會從以太網部分就開始顯示網絡包內容,而不是僅從網絡層協議開始顯示。
使用-D選項,則tcpdump會列出所有可以選擇的抓包對象。
tcpdump -D
1.eth0
2.nflog (Linux netfilter log (NFLOG) interface)
3.nfqueue (Linux netfilter queue (NFQUEUE) interface)
4.any (Pseudo-device that captures on all interfaces)
5.lo
-e選項的輸出中,會發現有oui Unknown的字樣,這oui是什么東東呢?在這里順便科普一下咯:
OUI,即Organizationally unique identifier,是“組織唯一標識符”,在任何一塊網卡(NIC)中燒錄的6字節MAC地址中,前3個字節體現了OUI,其表明了NIC的制造組織。通常情況下,該標識符是唯一的。
-l選項的作用就是將tcpdump的輸出變為“行緩沖”方式,這樣可以確保tcpdump遇到的內容一旦是換行符即將緩沖的內容輸出到標准輸出,以便於利用管道或重定向方式來進行后續處理。
眾所周知,Linux/UNIX的標准I/O提供了全緩沖、行緩沖和無緩沖三種緩沖方式。標准錯誤是不帶緩沖的,終端設備常為行緩沖,而其他情況默認都是全緩沖的。
大家在使用tcpdump時,有時會有這樣的需求:“對於tcpdump輸出的內容,提取每一行的第一個域,即”時間域”,並輸出出來,為后續統計所用”,這種場景下,我們就需要使用到-l來將默認的全緩沖變為行緩沖了。
如果不加-l選項,那么只有全緩沖區滿,才會輸出一次,這樣不僅會導致輸出是間隔不順暢的,而且當你ctrl-c時,很可能會斷到一行的半截,損壞統計數據的完整性。
做過網絡流量分析的同學,或許都有一個共同的需求,那就是“流量保存”和“流量回放”,這就恰好對應了今天要講解的-w選項和-r選項。
“流量保存”就是把抓到的網絡包能存儲到磁盤上,保存下來,為后續使用。
“流量回放”就是把歷史上的某一時間段的流量,重新模擬回放出來,用於流量分析。
表達式
可以通過手冊頁來詳細閱讀 #man pcap-filter
你會發現,過濾表達式大體可以分成三種過濾條件,“類型”、“方向”和“協議”,這三種條件的搭配組合就構成了我們的過濾表達式。
tcpdump 支持正則表達式
tcpdump利用正則作為過濾報文的條件,如果一個報文滿足表達式的條件,則這個報文將會被捕獲。如果沒有給出任何條件,則網絡上所有的信息包將會被截獲。
或許你會提問“為啥這些協議里沒有應用層協議呢?”,其實理由很簡單,應用層協議非基礎類網絡協議,經常會新增或淘汰,tcpdump不會深入到應用層部分去智能解析。所以,你現在看到的tcpdump支持的protocol都是應用層以下的。
ether – 鏈路層協議
fddi – 鏈路層協議
tr – 鏈路層協議
wlan – 鏈路層協議
ppp – 鏈路層協議
slip – 鏈路層協議
link – 鏈路層協議
tcpdump 'tcp[tcpflags] & tcp-syn != 0 and not dst host qiyi.com'
tcpdump 'ip[2:2] > 576'
tcpdump 'ether[0] & 1 = 0 and ip[16] >= 224'
即proto [ expr : size]語法
expr用來指定數據報偏移量,表示從某個協議的數據報的第多少位開始提取內容,默認的起始位置是0;而size表示從偏移量的位置開始提取多少個字節,可以設置為1、2、4。
如果只設置了expr,而沒有設置size,則默認提取1個字節。比如ip[2:2],就表示提取出第3、4個字節;而ip[0]則表示提取ip協議頭的第一個字節。
在我們提取了特定內容之后,我們就需要設置我們的過濾條件了,我們可用的“比較操作符”包括:>,<,>=,<=,=,!=,總共有6個。
ip[0] & 0xf != 5
IP協議的第0-4位,表示IP版本號,可以是IPv4(值為0100)或者IPv6(0110);第5-8位表示首部長度,單位是“4字節”,如果首部長度為默認的20字節的話,此值應為5,即”0101″。ip[0]則是取這兩個域的合體。0xf中的0x表示十六進制,f是十六進制數,轉換成8位的二進制數是“0000 1111”。而5是一個十進制數,它轉換成8位二進制數為”0000 0101″。
有了上面這些分析,大家應該可以很清楚的知道,這個語句中!=的左側部分就是提取IP包首部長度域,如果首部長度不等於5,就滿足過濾條件。言下之意也就是說,要求IP包的首部中含有可選字段。
大家可能已經有所體會,在寫過濾表達式時,你需要把協議格式完全背在腦子里,才能把表達式寫對。可這對大多數人來說,可能有些困難。為了讓tcpdump工具更人性化一些,有一些常用的偏移量,可以通過一些名稱來代替,比如icmptype表示ICMP協議的類型域、icmpcode表示ICMP的code域,tcpflags則表示TCP協議的標志字段域。
更進一步的,對於ICMP的類型域,可以用這些名稱具體指代:icmp-echoreply, icmp-unreach, icmp-sourcequench, icmp-redirect, icmp-echo, icmp-routeradvert, icmp-routersolicit, icmp-timxceed, icmp-paramprob, icmp-tstamp, icmp-tstampreply, icmp-ireq, icmp-ireqreply, icmp-maskreq, icmp-maskreply。
而對於TCP協議的標志字段域,則可以細分為tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-ack, tcp-urg。
如果一個過濾表達式有多個過濾條件,那么就需要使用邏輯符了,其中,!或not都可以表示“否定”,&&與and都可以表示“與”,而||與or都可以表示“或”。
有關ETHER的,可以參考《計算機網絡協議包頭賞析-以太網》;
有關IP的,可以參考《計算機網絡協議包頭賞析-IP》;
有關TCP的,可以參考《計算機網絡協議包頭賞析-TCP》;
有關UDP的,可以參考《計算機網絡協議包頭賞析-UDP》。
表達式中的關鍵字
第一種是關於類型的關鍵字,主要包括host(默認),net,port
第二種是確定傳輸方向的關鍵字,主要包括src,dst ,dst or src(默認), dst and src
第三種是協議的關鍵字,主要包括fddi,ip,arp,rarp,tcp,udp等類型,默認是監聽所有協議,Fddi指明是在FDDI(分布式光纖數據接口網絡)上的特定的網絡協議,實際上它是"ether"的別名,fddi和ether具有類似的源地址和目的地址,所以可以將fddi協議包當作ether的包進行處理和分析。除了這三種類型的關鍵字之外,其他重要的關鍵字如下:gateway, broadcast,less,
greater,還有三種邏輯運算,取非運算是 'not ' '! ';與運算是'and','&&';或運算是'or' ,'||';
這些關鍵字可以組合起來構成強大的組合條件來滿足人們的需要
下面舉例說明
tcpdump host 192.168.2.101 -c 50 -nn -t
tcpdump host 210.27.48.1 and \(210.27.48.2 or 210.27.48.3 \)
tcpdump ip host 210.27.48.1 and ! 210.27.48.2
tcpdump tcp port 23 host 210.27.48.1
常見表示方法
host 192.168.2.10或者host com1
tcp port 10000,src host 192.168.2.10,
輸出信息
“listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes”
這一句表示我們監聽的是通過eth0這個NIC設備的網絡包,且它的鏈路層是基於以太網的,要抓的包大小限制是65535字節。
包大小限制值可以通過-s選項來設置,如果你要追求高性能,建議把這個值調低,這樣可以有效避免在大流量情況下的丟包現象。
沒有用-s參數指定抓取數據的長度,采用了默認長度為68或96字節;-s0則表示沒有長度的限制。
[root@aster5 ~]# tcpdump -nn host 117.136.25.196
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
[root@aster5 ~]# tcpdump -nn -s0 -c 50 host 117.136.25.196 -w 1007
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
加-X的話,接下來便是IP包的內容了,是除去了以太網之后剩下的內容,其中左側紅色字體部分是十六進制內容,右側天藍色字體部分是相應的ASCII碼內容。
(1) 數據鏈路層頭信息
使用命令#tcpdump -e host ice
ice 是一台裝有linux的主機,她的MAC地址是0:90:27:58:AF:1A
H219是一台裝有SOLARIC的SUN工作站,它的MAC地址是8:0:20:79:5B:46;上一條
命令的輸出結果如下所示:
21:50:12.847509 eth0 ice.telnet 0:0(0) ack 22535 win 8760 (DF)
分析:21:50:12是顯示的時間, 847509是ID號,eth0 表示從網絡接口設備發送數據包, 8:0:20:79:5b:46是主機H219的MAC地址,它
表明是從源地址H219發來的數據包. 0:90:27:58:af:1a是主機ICE的MAC地址,表示該數據包的
目的地址是ICE . ip 是表明該數據包是IP數據包,60 是數據包的長度, h219.33357 > ice.
telnet 表明該數據包是從主機H219的33357端口發往主機ICE的TELNET(23)端口. ack 22535
表明對序列號是222535的包進行響應. win 8760表明發送窗口的大小是8760.
打印以太頭代替默認的ip頭
tcpdump -e -nn
16:04:22.481164 e4:1f:13:80:ed:2b > 00:50:56:a1:5a:11, ethertype IPv4 (0x0800), length 322: 192.168.2.2.22 > 192.168.2.84.34559: P 2231088:2231344(256) ack 577 win 121 <nop,nop,timestamp 987621813 4054453550>
tcpdump -nn
16:05:42.390904 IP 192.168.2.2.22 > 192.168.2.84.34559: P 2169680:2169856(176) ack 913 win 121 <nop,nop,timestamp 987701722 4054533458>
(2) ARP包的輸出信息
[root@109-com1 asterisk]# tcpdump arp -enX
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:26:16.048727 00:50:56:a1:63:0d > Broadcast, ethertype ARP (0x0806), length 60: Request who-has 192.168.2.85 tell 192.168.2.80, length 46
0x0000: 0001 0800 0604 0001 0050 56a1 630d c0a8 .........PV.c...
0x0010: 0250 0000 0000 0000 c0a8 0255 0000 0000 .P.........U....
0x0020: 0000 0000 0000 0000 0000 0000 0000 ..............
使用命令#tcpdump arp
得到的輸出結果是:
22:32:42.802509 eth0 > arp who-has route tell ice (0:90:27:58:af:1a)
22:32:42.802902 eth0 表明從主機發出該數據包, arp表明是
ARP請求包, who-has route tell ice表明是主機ICE請求主機ROUTE的MAC地址。 0:90:27:58:af:1a是主機ICE的MAC地址。
18:56:23.790156 ARP, Request who-has 192.168.2.109 tell 192.168.2.10, length 46
18:56:23.790165 ARP, Reply 192.168.2.109 is-at 00:50:56:a1:04:ea, length 28
18:56:27.279072 ARP, Request who-has 192.168.2.109 tell 192.168.2.210, length 46
18:56:27.279087 ARP, Reply 192.168.2.109 is-at 00:50:56:a1:04:ea, length 28
(3) TCP包的輸出信息 tcp包頭20字節 ip包頭也是20字節
用TCPDUMP捕獲的TCP包的一般輸出信息是:
src > dst: flags data-seqno ack window urgent options
src > dst:表明從源地址到目的地址, flags是TCP包中的標志信息,S 是SYN標志, F (F
IN), P (PUSH) , R (RST) "." (沒有標記); data-seqno是數據包中的數據的順序號, ack是
下次期望的順序號, window是接收緩存的窗口大小, urgent表明數據包中是否有緊急指針.
Options是選項.
18:48:22.036100 IP 192.168.2.109.22 > 192.168.2.80.52721: Flags [P.], seq 120736:121008, ack 161, win 1002, length 272
18:48:22.037106 IP 192.168.2.109.22 > 192.168.2.80.52721: Flags [P.], seq 121008:121184, ack 161, win 1002, length 176
18:48:22.037551 IP 192.168.2.80.52721 > 192.168.2.109.22: Flags [.], ack 121184, win 256, length 0
(4) UDP包的輸出信息 udp包頭8字節
用TCPDUMP捕獲的UDP包的一般輸出信息是:
route.port1 > ice.port2: udp length
UDP十分簡單,上面的輸出行表明從主機ROUTE的port1端口發出的一個UDP數據包到主機
ICE的port2端口,類型是UDP, 包的長度是length
18:52:17.486689 IP 192.168.2.109.41608 > 192.168.2.10.40001: UDP, length 180
18:52:17.486712 IP 192.168.2.109.42275 > 172.16.1.16.9012: UDP, length 180
樣例
-c 計數
-e 鏈路頭
默認 15:30:44.520640
-t 不顯示時間戳
-tt 1429687801.082955
-ttt 00:00:00.000688 與上一次時間作比較
-tttt 2015-04-22 15:30:18.980728
-ttttt 00:00:00.000249 與第一行時間作比較
-v
-vv
-vvv
-r file
-w file Write the raw packets to file rather than parsing and printing them out
in hex
-x 不包括鏈路層頭
-xx 包括鏈路層頭
in hex and ASCII
-X 不包括鏈路層頭
-XX 包括鏈路層頭
tcpdump -i eth0 -n
tcpdump -i eth0 -nn -t -vv -c 500
tcpdump -i eth0 tcp -c 20 -t -nn -e
tcpdump -nn -X 'port 1521' -c 1
只捕獲100個syn包
tcpdump tcp [13] == 2 -nn -c 10
tcpdump 'tcp[13] & 2 == 2' -nn -c 10
tcpdump 'tcp[tcpflags] & tcp-push != 0'
[root@109-com1 asterisk]# tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0' -nn
[root@109-com1 asterisk]# tcpdump host 117.136.3.33 -nn
[root@109-com1 asterisk]# tcpdump host 192.168.2.215 and \(117.136.25.199 or 117.136.25.141 \) -nn
[root@109-com1 asterisk]# tcpdump host 192.168.2.215 and not 117.136.25.199 -nn
[root@222-comecs ~]# tcpdump 'ip[2:2] > 576' -nn
[root@222-comecs ~]# tcpdump 'icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply' -nn
[root@222-comecs ~]# tcpdump -A -c 10 Handy for capturing web pages.以ascii碼顯示,捕獲web頁面非常方便
tcpdump -nn 一般一定要加-nn,這樣不解析主機名與端口名,並且比較快,如果用tcpdump,不加任何參數,會很慢。
[root@coreserv packet]# date
Sat Mar 29 15:13:26 CST 2014
[root@coreserv packet]# tcpdump udp >cc
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
1182828 packets captured
3063818 packets received by filter
1880979 packets dropped by kernel
[root@coreserv packet]# date
Sat Mar 29 15:15:29 CST 2014
其中“captured”的計數指的是應用層捕獲到的數據,“received by filter”和“dropped by kernel”的計數由內核維護,應用層通過getsockopt來獲取。收到一個包,“received by filter”會加1,如果sock的接收buffer被填滿時,則把這個數據包丟棄,將“dropped by kernel”加1。
通過調節/proc/sys/net/core/rmem_default和/proc/sys/net/core/rmem_max能夠改變sk_rcvbuf的大小。
正常“captured”加上“dropped by kernel”應該等於“received by filter”的大小,有的時候出現不等的情況應該是還有一些數據包在sk_rcvbuf中,還沒有被應用層收到的原因。
通過調節發包速率,發包速率調慢,丟包率明顯降低。
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).
http://blog.sina.com.cn/s/blog_67b48ddf0102v1rm.html tcpdump捕獲包內容不全
在linux下用tcpdump抓取http數據包,之后用wireshark打開,發現數據包的內容是不全的
這時,想分析和獲取http包中的內容是不可能的,在圖中可以發現,wireshark給出了“Packet size limited during cap”的提示,和:“HTTP truncated”的提示。這是什么呢?
自己在實際中遇到的是這個錯誤提示:packet size limited during capture: JXTA truncated
對於這個問題,一個“外國朋友的MAIL中”給了非常好的解答,MAIL部分原文如下:
Maynard, Chris wrote:
"Packet Size limited during capture" tells me that the packet was bigger than the snaplen set, so the packet was truncated when captured. In Wireshark, the snaplen is set in the capture options dialog using the "Limit each packet to ___ bytes" option, and with dumpcap, tshark and tcpdump it is set via the "-s " option. If not specified, tcpdump uses a default snaplen of 68 (or 96, depending on the platform).

2)用Tcpdump進行抓包時,沒有用-s參數指定抓取數據的長度,采用了默認長度為68或96字節;-s0則表示沒有長度的限制。
[root@aster5 ~]# tcpdump -nn -s0 -c 50 host 117.136.25.196 -w 1007
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
50 packets captured
50 packets received by filter
0 packets dropped by kernel
eth包頭14字節
ip包頭20字節
tcp包頭20字節
udp包頭8字節
tcpdump -s0 -c 50 -nn host 222.91.97.126 -w 20001.pcap
tcpdump -s0 -c 50 -nn tcp port 10000 -w 10000.pcap
[root@84-monitor packet]# pwd
/root/packet
[root@84-monitor packet]# scp -P 8164 124.115.106.234:/root/10009.pcap ./
10009.pcap 100% 2943 2.9KB/s 00:00
[root@84-monitor packet]# scp 192.168.2.221:/root/10001.pcap ./
10001.pcap 100% 12KB 12.1KB/s 00:00