1. tcpdump的基本原理
1.1 tcpdump starce 的區別
在本機中的進程的系統行爲調用跟蹤,starce 是一個很好的工具;可是在網絡問題的調試中,tcpdump 應該是一個必不可少的工具;能清晰分析網絡通訊的信息。html
默認狀況下,tcpdump 不會抓取本機內部通信的報文 ;根據網絡協議棧的規定,對於報文,即便是目的地是本機(本身和本身通訊),也須要通過本機的網絡協議層,因此本機通信確定是經過API進入內核,而且完成路由選擇。【好比本機的TCP通訊,也必需要socket通訊的基本要素:src ip port dst port】linux
1.2 linux下tcpdump 抓包的基本原理
Linux 的抓包是經過
註冊一種虛擬的底層網絡協議來完成網絡報文(準確的說是:網絡設備)消息的處理權,
當網卡接收到一個網絡報文後,它會遍歷系統中全部已經註冊的網絡協議,例如:以太網協議、x25協議處理模塊來嘗試進行報文的解析處理。這一點和文件系統的掛載類似,就是讓系統中全部已經註冊的文件系統來進行嘗試掛載,若是哪個認爲本身能夠處理,那麼就完成掛載。
當抓包模塊把本身假裝成一個網絡協議的時候,系統在收到報文的時候就會這個僞協議一次機會,讓它來對網卡收到的報文進行一次處理,此時該抓包模塊就會趁機把報文完整的copy一份,而後把這個copy的數據給抓包模塊(tcpdump)
2. tcpdump 命令詳解
2.1 tcpdump 命令的基本簡介
- tcpdump :dump the traffic on a network 根據使用者的定義對網絡上的數據包進行截獲的分析工做;tcpdump 能夠講網絡中傳送的數據包的header徹底截獲下來進行分析;它支持對網絡層(net IP 段)、協議(TCP/UDP)、主機(src/dst host)、網絡或端口(prot)的過濾,並提供and、or、not 等邏輯語句來幫助你去掉無用的信息。
- tcpdump:默認狀況下,sudo /usr/sbin/tcpdump 會監視 第一個網絡接口 通常是eth0 的全部port 全部協議的 數據包
2.2 tcpdump 的主要選項
協議 |
TCP,UDP,IP,ARP,RARP,ETHER,FDDI |
網絡(net) |
192.168.0.0/16 IP網段 |
方向(host) |
src,dst,src or dst,src and dst |
端口(prot) |
80 22 !22 9999 |
邏輯 |
and,or,not &&,||,! |
- 協議:tcp udp ip arp rarp ether fddi 協議這選項要放在 前面,由於要過濾數據包
- 網絡:net ip網段 tcpdump net 192.168.1.0/24 監聽這個網段
- 方向:host 就是主機 src 是源主機、dst 是目的主機 or and 是邏輯 tcpdump host test.hostname
- 端口:port 指定tcpdump 監聽的端口 tcpdump src 192.168.1.11 and port 80 監聽源IP是192.168.1.11 的80端口
- 邏輯:是表示 與 或 即:同時知足或知足之一
前面的四個選項:協議、net 、host、port 若是同時在 tcpdump 裏面 時必須用 邏輯 and 鏈接起來;並且如用() 必定要轉義,不然會包語法錯誤。
- sudo /usr/sbin/tcpdump tcp and srchosttest1.hostnameortest2.hostname and port 3333 and net 172.21.121.0/24 -c 10 -vvv
3. tcpdump 的選項
3.1 主要選項
- -i :指定網卡 默認是 eth0
- -n :線上ip,而不是hostname
- -c :指定抓到多個包後推出
- -A:以ASCII方式線上包的內容,這個選項對文本格式的協議包頗有用
- -x:以16進制顯示包的內容
- -vvv:顯示詳細信息
- -s :按包長截取數據;默認是60個字節;若是包大於60個字節,則抓包會出現丟數據;因此咱們通常會設置 -s 0 ;這樣會按照包的大小截取數據;抓到的是完整的包數據
- -r:從文件中讀取【與 -w 對應,/usr/sbin/tcpdump -r test.out 讀取 tcpdump -w test.out】
- -w:處處指向文件【必定要用,-w t.out ,而後用 -r t.out 來看抓包信息,不然可讀性不好】
3.2 tcpdump 抓包的具體含義
tcpmdump 抓包出來分析包的具體含義
- S:S=SYC :發起鏈接標誌
- P:P=PUSH:傳送數據標誌
- F:F=FIN:關閉鏈接標誌
- ack:表示確認包
- RST=RESET:異常關閉鏈接
- . 表示沒有任何標誌
- server.hostname: sudo /usr/sbin/tcpdump tcp port 80 and host clinet.hostname -c 30 -vvv -w t.out
- sudo /usr/sbin/tcpdump -r t.out
- 13:59:29.012370 IP client.hostname.tbsite.net.50741 > server.hostname.http: S 562843056:562843056(0) win 14480 <mss 1460,sackOK,timestamp 230871413 4035264472,nop,wscale 7>
- 13:59:29.012374 IP server.hostname.http > client.hostname.tbsite.net.50741: S 2306923370:2306923370(0) ack 562843057 win 5792 <mss 1460,sackOK,timestamp 4035271299 230871413,nop,wscale 9>
- 13:59:29.012547 IP client.hostname.tbsite.net.50741 > server.hostname.http: . ack 1 win 114 <nop,nop,timestamp 230871413 4035271299>
- 13:59:29.012582 IP client.hostname.tbsite.net.50741 > server.hostname.http: P 1:1006(1005) ack 1 win 114 <nop,nop,timestamp 230871413 4035271299>
- 13:59:29.012593 IP server.hostname.http > client.hostname.tbsite.net.50741: . ack 1006 win 16 <nop,nop,timestamp 4035271299 230871413>
- 13:59:29.025011 IP client.hostname.tbsite.net.50777 > server.hostname.http: S 2359624339:2359624339(0) win 14480 <mss 1460,sackOK,timestamp 230871425 4035264472,nop,wscale 7>
- 13:59:29.025022 IP server.hostname.http > client.hostname.tbsite.net.50777: S 2305562654:2305562654(0) ack 2359624340 win 5792 <mss 1460,sackOK,timestamp 4035271312 230871425,nop,wscale 9>
- 13:59:29.025197 IP client.hostname.tbsite.net.50777 > server.hostname.http: . ack 1 win 114 <nop,nop,timestamp 230871425 4035271312>
- 13:59:29.025228 IP client.hostname.tbsite.net.50777 > server.hostname.http: P 1:837(836) ack 1 win 114 <nop,nop,timestamp 230871425 4035271312>
- 13:59:29.025240 IP server.hostname.http > client.hostname.tbsite.net.50777: . ack 837 win 15 <nop,nop,timestamp 4035271312 230871425>
- 第一行: S:表示 clinet.hostname 的臨時端口50741向 server.hostname 80 端口發起鏈接,client 的初始包序號是: 562843056 ;滑動窗口(win 14480)的大小是:14480 [14k] 滑動窗口即tcp 接收緩衝區的大小,用於tcp 擁塞控制;mss 1460:能夠接收的最大包長度,一般是MTU - 40 byte;IP頭和TCP頭各20byte
- 第二行: S:表示SYN狀態;是server.hostname 對第一行 clinet.hostname 發起鏈接的請求的迴應;同時帶上client 端 初始包序號 + 1:ack 562843057 ,即server.hostname 下次等待接收這個包序號的包,用於tcp 字節流的順序控制(?). server.hostname 初始包序列號:2306923370
- 第三行:client.hostname 再次確認,tcp鏈接完成三次握手
- 。
- 第四行:P:推送數據 client.hostname 經過 50741 端口向 server.hostname 發送數據包;數據包大小是 1005byte ;第五行是 server.hostname 響應這個數據包發送,接收這個數據包。----> 當完成後會出現一個 server.hostname F 關閉鏈接的數據包,這裏沒有抓取
- 第6行 ---->10行是對 1-5行的重複;由於機器是web服務是併發的。
4. tcpdump的實例:
- 起步1: 抓取指定端口的包
tcpdump -i eth0 -c 100
- 起步2:抓取指定協議的包
tcpdump -i eth0 -c 100 tcp
- 起步3:抓取指定協議,指定port的包【tcp ip port src dst host net】
tcpdump -i eth0 -c 100 tcp port 5440
- 起步4:組合過濾條件【and or not】
tcpdump -i eth0 -c 100 tcp port 5440 and src host 192.1.1.2
- 起步5:抓取指定網段的包
tcpdump -i eth0 -c 100 tcp port 5440 and src net 192.1.1.0/24
- 高級1:寫入文件並用wireshark在windows下分析
tcpdump tcp -i eth1 -t -s 0 -c 100 and dst port ! 22 and src net 192.168.1.0/24 -w ./target.cap
而後用ftp傳輸到windows下面,在用wireshark打開cap文件便可
- 高級2:提取http包
tcpdump -XvvennSs 0 -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854 -c 20 -w ./target.cap
其中-s 0表示不限制包的大小;tcp[20:2]從表示tcp包頭第20個字節開始的2個字節等於0x4745(對應字符GE)或者等於0x4854(對應HT);
這種方法適用於tcp頭中OPTION爲空的狀況,若是不爲空,須要從第24個字節開始。
注意:在linux抓取包後用tcpdump -r 只能看到包的簡單信息;若是須要查詢抓取包的詳細信息須要把抓取的包target.cap 經過 ftp服務器傳輸到windows機器上;藉助wireshark工具來分析數據;wireshark是一款開源的分析網絡抓包的工具;灰常的好用。
5. tcpdump 抓包看rt
- sudo tcpdump -s 0 -w /tmp/a.cap host 10.246.38.44
-
- tcpdump -A -r /tmp/a.cap
- <<<<<<<<<<<<上面 client、server的三次握手省略;下面是三次握手成功後直接push 數據>>>>>>>>>>>>>>
- 17:46:30.138829 IP client.hostname.55445 >server.dns.com: P 1:741(740)
- ack 1 win 46 <nop,nop,timestamp 221364282 177661952>
- E.....@.@...
- ..%
- .&,...P......uH....mG.....
- 1.:
- ...POST /ecpmdsp_bid HTTP/1.1 <<<<<<POST 說明;client 發送query 數據;在上面的的行中找到時間點:【17:46:30.138829】
- User-Agent: Mozilla/5.0 (compatible; Tanx/1.0; Linux)
- Host: server.dns.com <<<<<<<<<<HTTP服務、web (apache、nginx)>>>>>>>>>>
- Accept: */*
- Content-Type:application/octet-stream
- Connection:Keep-Alive
- Content-Length: 524
-
- ...
- 0af62e25315451c420f6000000000001..BpNFCj5dkAgCAQYTS24VMRxz".10.246.157.167*..Mozilla/4.0
- (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR
- 2.0.50727; .NET CLR 3.5.30729; .NET CLR
- 3.0.30722.mcdonalds.com.cn:Ihttp://static.atm.youku.com/Youku2013/201304/0424/22371/600-90-under.html@...H.R.....ad_pid_pid_pid..600x90(.8.@.H.X.`.h...................................................................................................................................................................
- 17:46:30.138927 IP server.dns.com.http >
- client.hostname.55445: . ack 741 win 125 <nop,nop,timestamp
- 177661952 221364282>
- E..4.H@.?.4?
- .&,
- ..%.P....uH.......}.^.....
-
- 1.:
- 17:46:30.219197 IP client.hostname.55445 >
- server.dns.com.http: F 741:741(0) ack 1 win 46
- <nop,nop,timestamp 221364362 177661952>
- E..4..@.@...
- ..%
- .&,...P......uH.....\.....
- 1..
- ...
- 17:46:30.223900 IP server.dns.com.http > client.hostname.55445: P 1:154(153) ack 742 win 125 <nop,nop,timestamp 177662037 221364362>
- E....I@.?.3.
- .&,
- ..%.P....uH.......}Y......
-
- 1..HTTP/1.1 200 OK <<<<<<<<<<<<server.dns.com 的respose 包 200 OK;因此返回數據了;這時找到下面行的時間點【17:46:30.223910】
- Server: Tengine
- Date: Fri, 21 Jun 2013 09:46:30 GMT
- Content-Length: 36
- Connection: keep-alive
-
- ... 0af62e25315451c420f6000000000001
- 17:46:30.223910 IP client.hostname.55445 > server.dns.com.http: R 2868451528:2868451528(0) win 0
- E..(..@.@...
- ..%
- .&,...P........P.......
- 17:46:30.223947 IP server.dns.com.http >client.hostname.55445: F 154:154(0) ack 742 win 125<nop,nop,timestamp 177662037 221364362> <<<<<<<<<<<<這次通訊結束;F = final >>>>>>>>>>
- E..4.J@.?.4=
-
- 因此,咱們能夠計算出從發出query;到收到respose的時間是: 【17:46:30.223910】 - 【17:46:30.138829】 = 0.085081us == 85.08ms