作為 DBA,你有必要了解一下 tcpdump
一 簡介
tcpdump 是一款強大的網路抓包工具,dump the traffice on anetwork,對網路上的資料包進行截獲的包分析工具。熟練掌握tcpdump 可以方便我們跟蹤解決網路丟包,重傳,資料庫鏈路呼叫等問題。
二 使用tcpdump
2.1 語法
tcpdump的語法如下:
Usage: tcpdump [-aAdDefhIJKlLnNOpqRStuUvxX] [ -B size ] [ -c count ] [ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ] [ -i interface ] [ -j tstamptype ] [ -M secret ] [ -Q|-P in|out|inout ] [ -r file ] [ -s snaplen ] [ -T type ] [ -w file ] [ -W filecount ] [ -y datalinktype ] [ -z command ] [ -Z user ] [ expression ]
我們重點說一下表達式 expression ,tcpdump通過表示式對不同型別的網路流量進行過濾,以獲取到需要的資訊。tcpdump主要支援3種類型的表示式:
Type(型別)選項包括 host,net和port,預設為host
host(預設型別): 指明一臺主機,如: host 10.215.20.13 net: 指定網路地址,net 10.215.20.0 port: 指明埠號,port 3306
Direction(方向)選項包括 src 和 dst 以及它們的組合
確定方向的關鍵字 dst or src(預設值) 指定源或者目標地址是 10.215.20.13的流量包 src: src 10.9.51.13, 指定源地址是10.9.51.13 dst: dst net 172.0.0.0, 指定目標網路地址是172.0.0.0 dst and src比如: src host 10.9.51.13and dst host 10.215.20.13
Proto(協議)包括 tcp 、udp 、ICMP 和 ah 等
協議的關鍵字:預設值是監聽所有協議的資訊包
ip arp tcp udp icmp 其他關鍵字 gateway broadcast less greater
常用表示式:多條件時可以用括號,但是要用轉義
非 : ! 、not 且 : && 、 and 或 : || 、 or 例子: 抓取所有經過 bond0,目的地址是 10.10.1.254 或 10.10.1.200 埠是 80 的 TCP 資料 # tcpdump -i bond0 '((tcp) and (port 80) and ((dst host 10.10.1.254) or (dst host 10.10.1.200)))'
2.2 引數
以一個實際例子說明
tcpdump tcp -i bond0 -tttt -s 0 -c 100 and dst port ! 22 and src net 10.10.1.0/24 -w 20190131.tcpdump
解釋
(1)tcp: 協議型別,用來過濾資料報的協議型別。 (2)-i bond0 : 只抓取經過介面bond0的包 (3) -tttt : 使用格式 2019-02-02 10:37:37.120297,便於分析。 (4)-s 0: 抓取資料包時預設抓取長度為68位元組。加上-s 0 後可以抓到完整的資料包 (5)-c 100: 只抓取100個數據包 (6)dst port ! 22: 不抓取目標埠是22的資料包 (7)src net 10.10.1.0/24:資料包的源網路地址為10.10.1.0/24 (8)-w 20190131.tcpdump:儲存成tcpdump檔案中,方便使用wireshark分析抓包結果。
還有其他常用的引數:
-D:列出所有可用的網路介面 -n:禁用域名解析,讓tcpdump直接輸出IP地址. -X:以16進位制格式輸出資料包的內容,不加該引數,會只輸出iptcp/udp頭部資訊。 加上該選項會將整個資料包輸出。 -vvvv該引數其實是-v與-vvv的組合。 -v會輸出稍微詳細一點的資訊包括校驗和ttl之類的; -vvv會嘗試解析應用層協議,輸出詳細資訊。二者組合就能完整的詳細資訊。 -A:以ASCII值顯示抓到的包,比如和MySQL的互動時,可以通過-A檢視包的文字內容.
tcpdump的功能結合引數排列組合非常多,感興趣的朋友可以自己多動手實踐。畢竟,紙上來得終覺淺,絕知此事要躬行。
三 解析包
知道如何使用tcpdump命令,我們接下來分析抓到的報文。抓包命令:
tcpdump -i bond0 -n -s 0 port 3312 -c 10 -tttt
第一列是時間 2019-02-02 10:46:13.447563
第二列 IP是網路協議名稱。
10.215.20.13.appman-server > 10.9.51.13.25569表示 資料包傳送的源端十進位制地址和接收端的ip地址10.9.51.13和埠號25569。 其中 > 表示資料包的流向。
Flags [P.] 包的狀態標誌,
S=SYN發起連線標誌。 P=PUSH傳送資料標誌。 F=FIN, 關閉連線標誌。 ack,表示確認包。 RST=RESET,異常關閉連線。 .,表示沒有任何標誌。
seq 3771602051:3771602105 請求同步的序列號,注意3771602105-3771602051=54 表示資料包的大小和後面的length的大小一致。
ack 1872251807 確認已經同步的序列號+1
win 1857 當前可用的視窗大小,
註釋:window size:視窗大小,16bits,視窗欄位用來控制對方傳送的資料量,單位為位元組。TCP 連線的一端根據設定的快取空間大小確定自己的接收視窗大小,然後通知對方以確定對方的傳送視窗的上限。
length 54 tcp 包體的長度。
一圖勝千言,tcp結構瞭解一下
圖片來自 https://www.cnblogs.com/the-tops/p/6587498.html
四 案例分析
利用tcpdump和wireshark分析MySQL互動。利用如下命令收集資料包,
# tcpdump -i bond0-n -s 0port 3320-tttt -A-w/tmp/20190202.tcpdump tcpdump: listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes 32 packets captured 36 packets received by filter 0 packets dropped by kernel
同時在通過其他視窗執行sql,進行抓包。
獲取 20190202.tcpdump 使用wrieshark進行分析。忽略三次握手啥的,我們直接分析MySQL互動協議。要檢視MySQL協議,要使用右鍵
設定MySQL協議
確定之後,可以看到協議那部分出現MySQL,info部分有我們比較熟悉的select ,show tables 等語句。
登陸資料庫的
執行查詢的資料流, 其實我們可以通過26 ,27兩個包的時間差計算sql的執行時間,用於效能問題分析或者故障排查。
執行退出命令 exit
上面的舉例只是利用tcpdump簡單分析MySQL的互動,實際生產中可能更復雜,出現問題的場景不一定穩定復現,要抓很多包來分析定位。所以出現問題的時候抓包和分析包是個體力活。
五 推薦閱讀
[1] https://www.tcpdump.org/
[2] https://zhuanlan.zhihu.com/p/33580437