新聞中心
Linux中有很多抓包工具,如ngrep、tcpdump與tshark等,它們有很多用法與使用場(chǎng)景,下面我將結(jié)合例子講解各工具的用法以及它們的使用場(chǎng)景。

成都創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站制作、做網(wǎng)站、嘉禾網(wǎng)絡(luò)推廣、小程序開發(fā)、嘉禾網(wǎng)絡(luò)營銷、嘉禾企業(yè)策劃、嘉禾品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供嘉禾建站搭建服務(wù),24小時(shí)服務(wù)熱線:18980820575,官方網(wǎng)址:www.cdcxhl.com
ngrep
ngrep是一款抓包工具,它將抓到的包數(shù)據(jù)以文本形式直接顯示出來,非常適用于包數(shù)據(jù)包含文本的抓包分析(如HTTP、MySQL),如下:
抓HTTP請(qǐng)求
有時(shí)我們會(huì)遇到這種場(chǎng)景,服務(wù)方提供http接口給調(diào)用方使用,調(diào)用方傳遞一個(gè)參數(shù)值,服務(wù)方收到的結(jié)果不一樣!
這種情況,有可能是調(diào)用方的請(qǐng)求方式有問題,也有可能是服務(wù)方有請(qǐng)求攔截器導(dǎo)致問題,如何辨別問題是在哪一方呢?這時(shí)用ngrep抓包工具確認(rèn)一下包內(nèi)容再合適不過了,如下:
# -d any表示抓取所有網(wǎng)卡的數(shù)據(jù)包
# -W byline 一般用于HTTP抓包,方便查看
$ ngrep -d any -W byline port 8080
如上,ngrep會(huì)將非可見字符顯示為.,所以上面http請(qǐng)求每行后都有個(gè).,指的是HTTP協(xié)議換行符\r\n中的\r,而最前面的T代表這是TCP協(xié)議的包。
抓取SQL
# 抓取3961端口,過濾出包數(shù)據(jù)中帶select的網(wǎng)絡(luò)包,即查詢SQL
# -A 2 匹配包之后的2個(gè)包也顯示出來
$ ngrep -d any -A 2 'select' port 3961
可以發(fā)現(xiàn),mysql回包都有.def.這樣的字樣,我們可以根據(jù)這個(gè)來判斷mysql響應(yīng)包。
ngrep帶上-T參數(shù),可以額外打印出前后兩個(gè)包的間隔時(shí)間,這樣我們根據(jù)回包的間隔時(shí)間,就能大概看到SQL查詢的耗時(shí)了,如下:
# -W single讓包數(shù)據(jù)在一行上顯示,便于awk等文本工具處理
# -s 200 包大小最多抓200字節(jié),多余數(shù)據(jù)不顯示
# -T 打印出兩個(gè)包之間的間隔時(shí)間,單位秒
# awk部分腳本邏輯是,一直抓包直到發(fā)現(xiàn)回包慢于1秒時(shí)停止
$ ngrep -d any -W single -s 200 -T 'select|def' port 3961 \
| awk '{print} $1~/T/ && /.def./ && $2>1 && $2<1000 {exit(0)}'
tcpdump
tcpdump是一個(gè)通用抓包工具,一般用它來抓各種協(xié)議的網(wǎng)絡(luò)包數(shù)據(jù),然后再使用wireshark分析,如下:
抓取3961端口網(wǎng)絡(luò)包
# -c 10000表示最多抓1萬個(gè)包
$ tcpdump -i any -s 0 -c 10000 tcp and port 3961 -w ./target.cap
# -G 600 表示600s保存一個(gè)抓包文件,避免單文件太大
$ tcpdump -i any -s 0 -G 600 tcp and port 3961 -w ./target_%Y_%m%d_%H%M_%S.pcap
wireshark分析
抓取的target.cap是mysql的網(wǎng)絡(luò)包數(shù)據(jù),它是二進(jìn)制的,無法直接查看,需要使用wireshark分析,下載地址如下:
https://www.wireshark.org/download.html
默認(rèn)情況下,wireshark認(rèn)為3306端口的數(shù)據(jù)包是MySQL協(xié)議的,而上面我們mysql端口是3961,導(dǎo)致wireshark無法將包數(shù)據(jù)識(shí)別為MySQL協(xié)議,顯示的是TCP原始數(shù)據(jù),不方便查看,所以我們需要告訴wireshark使用MySQL協(xié)議解析3961端口數(shù)據(jù)包,如下:
a. 先decode as...相應(yīng)端口使用MySQL協(xié)議解析:
...
b. 輸入mysql.query contains "id=24218",查看SQL中包含id=24218的數(shù)據(jù)包,如下:
網(wǎng)絡(luò)慢還是后端處理慢?
為方便分析耗時(shí),一般建議在wireshark上再添加如下兩列:
- tcpDelta = tcp.time_delta,表示在當(dāng)前tcp連接中,當(dāng)前包相對(duì)上一個(gè)包的時(shí)間差。
- ack_rtt = tcp.analysis.ack_rtt,表示tcp中的ack包,相對(duì)其數(shù)據(jù)包的時(shí)間差。
如下,找耗時(shí)最大的包:
...
...
...
發(fā)現(xiàn)對(duì)于select sleep(2.0)這條SQL,服務(wù)端回復(fù)ack很快,而在回復(fù)數(shù)據(jù)包時(shí)變慢,說明是慢在MySQL處理上,而非網(wǎng)絡(luò)里,因?yàn)槿绻W(wǎng)絡(luò)慢的話,ack應(yīng)該也會(huì)變慢的。
tshark
tshark是wireshark工具的命令行版本,使用的方法與wireshark是類似的,如下:
# -i any 任意網(wǎng)卡的數(shù)據(jù)都抓取
# -f 指定抓什么協(xié)議,什么端口
# -d 類似wireshark的decode as,將3961解析為mysql協(xié)議
# -Y 類似wireshark上面的顯示過濾器
# -T 指定數(shù)據(jù)輸出格式,fields表示tab分隔格式
# -e 指定輸出的字段
# -E header=y 指定輸出標(biāo)題行
$ sudo tshark -ni any -f 'tcp and port 3961' -d 'tcp.port==3961,mysql' \
-T fields -e frame.number -e frame.time_epoch -e frame.time_delta_displayed \
-e ip.src -e tcp.srcport -e tcp.dstport -e ip.dst -e tcp.stream -e tcp.len -e tcp.nxtseq \
-e tcp.time_delta -e tcp.analysis.ack_rtt \
-e _ws.col.Info -e mysql.query -E header=y > packets.tsv
# 查看抓包數(shù)據(jù)
$ csvlook -It packets.tsv | less -iSFX
| frame.number | frame.time_epoch | frame.time_delta_displayed | ip.src | tcp.srcport | tcp.dstport | ip.dst | tcp.stream | tcp.len | tcp.nxtseq | tcp.time_delta | tcp.analysis.ack_rtt | _ws.col.Info | mysql.query |
| ------------ | -------------------- | -------------------------- | --------- | ----------- | ----------- | --------- | ---------- | ------- | ---------- | -------------- | -------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| 1 | 1639287428.374886956 | 0.000000000 | 127.0.0.1 | 39262 | 3961 | 127.0.0.1 | 0 | 5 | 6 | 0.000000000 | | Request Ping | |
| 2 | 1639287428.375043740 | 0.000156784 | 127.0.0.1 | 3961 | 39262 | 127.0.0.1 | 0 | 0 | 1 | 0.000156784 | 0.000156784 | 3961 → 39262 [ACK] Seq=1 Ack=6 Win=512 Len=0 TSval=696789627 TSecr=696789627 | |
| 3 | 1639287428.375268878 | 0.000225138 | 127.0.0.1 | 3961 | 39262 | 127.0.0.1 | 0 | 11 | 12 | 0.000225138 | | Response OK | |
| 4 | 1639287428.375289961 | 0.000021083 | 127.0.0.1 | 39262 | 3961 | 127.0.0.1 | 0 | 0 | 6 | 0.000021083 | 0.000021083 | 39262 → 3961 [ACK] Seq=6 Ack=12 Win=512 Len=0 TSval=696789627 TSecr=696789627 | |
| 5 | 1639287428.375886139 | 0.000596178 | 127.0.0.1 | 39262 | 3961 | 127.0.0.1 | 0 | 55 | 61 | 0.000596178 | | Request Query | select id from app_log al order by id desc limit 1 |
| 6 | 1639287428.375906403 | 0.000020264 | 127.0.0.1 | 3961 | 39262 | 127.0.0.1 | 0 | 0 | 12 | 0.000020264 | 0.000020264 | 3961 → 39262 [ACK] Seq=12 Ack=61 Win=512 Len=0 TSval=696789628 TSecr=696789628 | |
| 7 | 1639287428.377206294 | 0.001299891 | 127.0.0.1 | 3961 | 39262 | 127.0.0.1 | 0 | 76 | 88 | 0.001299891 | | Response | |
| 8 | 1639287428.377226652 | 0.000020358 | 127.0.0.1 | 39262 | 3961 | 127.0.0.1 | 0 | 0 | 61 | 0.000020358 | 0.000020358 | 39262 → 3961 [ACK] Seq=61 Ack=88 Win=512 Len=0 TSval=696789629 TSecr=696789629 | |
| 9 | 1639287428.378921659 | 0.001695007 | 127.0.0.1 | 39262 | 3961 | 127.0.0.1 | 0 | 84 | 145 | 0.001695007 | | Request Query | select id,log_info,create_time,update_time,add_time from app_log where id=27371 |
| 10 | 1639287428.378942384 | 0.000020725 | 127.0.0.1 | 3961 | 39262 | 127.0.0.1 | 0 | 0 | 88 | 0.000020725 | 0.000020725 | 3961 → 39262 [ACK] Seq=88 Ack=145 Win=512 Len=0 TSval=696789631 TSecr=696789631 | |
| 11 | 1639287428.380450661 | 0.001508277 | 127.0.0.1 | 3961 | 39262 | 127.0.0.1 | 0 | 412 | 500 | 0.001508277 | | Response | |
| 12 | 1639287428.380471636 | 0.000020975 | 127.0.0.1 | 39262 | 3961 | 127.0.0.1 | 0 | 0 | 145 | 0.000020975 | 0.000020975 | 39262 → 3961 [ACK] Seq=145 Ack=500 Win=509 Len=0 TSval=696789633 TSecr=696789633 | |
| 13 | 1639287430.051942681 | 1.671471045 | 127.0.0.1 | 39262 | 3961 | 127.0.0.1 | 0 | 22 | 167 | 1.671471045 | | Request Query | select sleep(2.0) |
| 14 | 1639287430.051972761 | 0.000030080 | 127.0.0.1 | 3961 | 39262 | 127.0.0.1 | 0 | 0 | 500 | 0.000030080 | 0.000030080 | 3961 → 39262 [ACK] Seq=500 Ack=167 Win=512 Len=0 TSval=696791304 TSecr=696791304 | |
| 15 | 1639287432.053394353 | 2.001421592 | 127.0.0.1 | 3961 | 39262 | 127.0.0.1 | 0 | 65 | 565 | 2.001421592 | | Response | |
| 16 | 1639287432.053520674 | 0.000126321 | 127.0.0.1 | 39262 | 3961 | 127.0.0.1 | 0 | 0 | 167 | 0.000126321 | 0.000126321 | 39262 → 3961 [ACK] Seq=167 Ack=565 Win=512 Len=0 TSval=696793306 TSecr=696793305 |
并且,tshark也可以直接分析tcpdump抓到的包數(shù)據(jù),如下:
# -Y 類似于wireshark中的顯示過濾器
$ tshark -d 'tcp.port==3961,mysql' -Y 'mysql.query contains "id=21"' -r target.cap -T fields -e frame.number -e mysql.query
5 select id,log_info,create_time,update_time,add_time from app_log where id=21527
13 select id,log_info,create_time,update_time,add_time from app_log where id=21518
25 select id,log_info,create_time,update_time,add_time from app_log where id=21007
52 select id,log_info,create_time,update_time,add_time from app_log where id=21505
# tshark包還附帶一個(gè)editcap命令
# 可用于截取抓包數(shù)據(jù)的一段時(shí)間范圍
$ editcap -F libpcap -A "2013-07-20 23:00:00" -B "2013-07-20 23:20:00" input.pcap output.pcap
pcap-filter與wireshark-filter
像ngrep、tcpdump和tshark -f使用的都是pcap-filter語法,用于抓取網(wǎng)絡(luò)包時(shí),對(duì)抓到的網(wǎng)絡(luò)包進(jìn)行過濾,如下是tcpdump使用pcap-filter的一些常見語法。
# 抓取指定主機(jī)的數(shù)據(jù)包
$ tcpdump -ni any host 210.27.48.1
# 抓取來自210.27.48.1主機(jī)和23端口的tcp包
$ tcpdump -ni any tcp src host 210.27.48.1 and port 23
# 抓取來自網(wǎng)絡(luò)10.234.10.0/24的主機(jī)發(fā)來的目的端口是80或8080的tcp包
$ tcpdump -ni any tcp src net 10.234.10.0/24 and dst port '(80 or 8080)'
# 抓tcp協(xié)議的rst包
$ tcpdump -ni any -s0 tcp and 'tcp[13] & 4 != 0 ' -vvv
# 抓tcp協(xié)議的fin包
$ tcpdump -ni any -s0 tcp and 'tcp[13] & 1 != 0 ' -vvv
詳細(xì)語法可以man pcap-filter查看,或訪問:https://wiki.wireshark.org/CaptureFilters
而wireshark界面上的顯示過濾器,以及tshark -Y使用的都是wireshark-filter語法,用于對(duì)已抓取的數(shù)據(jù)包進(jìn)行進(jìn)一步過濾分析,如下是tshark使用wireshark-filter的一些常見語法。
# 過濾指定主機(jī)與指定端口數(shù)據(jù)包
$ tshark -Y 'ip.addr==127.0.0.1 and tcp.port==3961'
# 解析為http協(xié)議,并使用http協(xié)議字段過濾
$ tshark -d 'tcp.port==8080,http' -Y 'http.request.uri contains "/get"'
# 解析為mysql協(xié)議,并使用mysql協(xié)議字段過濾
$ tshark -d 'tcp.port==3961,mysql' -Y 'mysql.query contains "id=21"'
詳細(xì)語法可以man wireshark-filter查看,或訪問:https://wiki.wireshark.org/DisplayFilters
總結(jié)
可見,使用ngrep、tcpdump、tshark分析網(wǎng)絡(luò)問題是非常有幫助的,一定要在工作中多多嘗試使用,熟悉它們的各種用法。
新聞名稱:Linux網(wǎng)絡(luò)抓包工具
瀏覽路徑:http://www.dlmjj.cn/article/dpcjjjp.html


咨詢
建站咨詢
