38 | 案例篇:怎么使用 tcpdump 和 Wireshark 分析网络流量?
生活随笔
收集整理的這篇文章主要介紹了
38 | 案例篇:怎么使用 tcpdump 和 Wireshark 分析网络流量?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
通常,需要暴露到公網的服務,都會綁定一個域名,既方便了人們記憶,也避免了后臺服務 IP 地址的變更影響到用戶。 不過要注意,DNS 解析受到各種網絡狀況的影響,性能可能不穩定。比如公網延遲增大,緩存過期導致要重新去上游服務器請求,或者流量高峰時 DNS 服務器性能不足等,都會導致 DNS 響應的延遲增大。 此時,可以借助 nslookup 或者 dig 的調試功能,分析 DNS 的解析過程,再配合 ping 等工具調試 DNS 服務器的延遲,從而定位出性能瓶頸。通常,你可以用緩存、預取、HTTPDNS 等方法,優化 DNS 的性能。 上一節我們用到的 ping,是一個最常用的測試服務延遲的工具。很多情況下,ping 可以幫我們定位出延遲問題,不過有時候, ping 本身也會出現意想不到的問題。這時,就需要我們抓取 ping 命令執行時收發的網絡包,然后分析這些網絡包,進而找出問題根源。 tcpdump 和 Wireshark 就是最常用的網絡抓包和分析工具,更是分析網絡性能必不可少的利器。
- tcpdump 僅支持命令行格式使用,常用在服務器中抓取和分析網絡包。
- Wireshark 除了可以抓包外,還提供了強大的圖形界面和匯總分析工具,在分析復雜的網絡情景時,尤為簡單和實用。
案例準備
本次案例還是基于 Ubuntu 18.04,同樣適用于其他的 Linux 系統。我使用的案例環境是這樣的: 機器配置:2 CPU,8GB 內存。 預先安裝 tcpdump、Wireshark 等工具,如: # Ubuntu apt-get install tcpdump wireshark# CentOS yum install -y tcpdump wireshark 由于 Wireshark 的圖形界面,并不能通過 SSH 使用,所以我推薦你在本地機器(比如 Windows)中安裝。你可以到 https://www.wireshark.org/ 下載并安裝 Wireshark。 跟以前一樣,案例中所有命令,都默認以 root 用戶(在 Windows 中,運行 Wireshark 時除外)運行。如果你是用普通用戶身份登陸系統,請運行 sudo su root 命令切換到 root 用戶。再探 ping
前面講過,ping 是一種最常用的網絡工具,常用來探測網絡主機之間的連通性以及延遲。關于 ping 的原理和使用方法,我在前面的 Linux 網絡基礎篇 已經簡單介紹過,而 DNS 緩慢的案例中,也多次用到了 ping 測試 DNS 服務器的延遲(RTT)。 不過,雖然 ping 比較簡單,但有時候你會發現,ping 工具本身也可能出現異常,比如運行緩慢,但實際網絡延遲卻并不大的情況。 接下來,我們打開一個終端,SSH 登錄到案例機器中,執行下面的命令,來測試案例機器與極客邦科技官網的連通性和延遲。如果一切正常,你會看到下面這個輸出: # ping 3 次(默認每次發送間隔 1 秒) # 假設 DNS 服務器還是上一期配置的 114.114.114.114 $ ping -c3 geektime.org PING geektime.org (35.190.27.188) 56(84) bytes of data. 64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=1 ttl=43 time=36.8 ms 64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=2 ttl=43 time=31.1 ms 64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=3 ttl=43 time=31.2 ms--- geektime.org ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 11049ms rtt min/avg/max/mdev = 31.146/33.074/36.809/2.649 ms ping 的輸出界面, Linux 網絡基礎篇 中我們已經學過,你可以先復習一下,自己解讀并且分析這次的輸出。 不過要注意,假如你運行時發現 ping 很快就結束了,那就執行下面的命令,再重試一下。至于這條命令的含義,稍后我們再做解釋。 # 禁止接收從 DNS 服務器發送過來并包含 googleusercontent 的包 $ iptables -I INPUT -p udp --sport 53 -m string --string googleusercontent --algo bm -j DROP 根據 ping 的輸出,你可以發現,geektime.org 解析后的 IP 地址是 35.190.27.188,而后三次 ping 請求都得到了響應,延遲(RTT)都是 30ms 多一點。 但匯總的地方,就有點兒意思了。3 次發送,收到 3 次響應,沒有丟包,但三次發送和接受的總時間居然超過了 11s(11049ms),這就有些不可思議了吧。 會想起上一節的 DNS 解析問題,你可能會懷疑,這可能是 DNS 解析緩慢的問題。但到底是不是呢? 再回去看 ping 的輸出,三次 ping 請求中,用的都是 IP 地址,說明 ping 只需要在最開始運行時,解析一次得到 IP,后面就可以只用 IP 了。 我們再用 nslookup 試試。在終端中執行下面的 nslookup 命令,注意,這次我們同樣加了 time 命令,輸出 nslookup 的執行時間: $ time nslookup geektime.org Server: 114.114.114.114 Address: 114.114.114.114#53Non-authoritative answer: Name: geektime.org Address: 35.190.27.188real 0m0.044s user 0m0.006s sys 0m0.003s 可以看到,域名解析還是很快的,只需要 44ms,顯然比 11s 短了很多。 到這里,再往后該怎么分析呢?其實,這時候就可以用 tcpdump 抓包,查看 ping 在收發哪些網絡包。 我們再打開另一個終端(終端二),SSH 登錄案例機器后,執行下面的命令: $ tcpdump -nn udp port 53 or host 35.190.27.188 當然,你可以直接用 tcpdump 不加任何參數來抓包,但那樣的話,就可能抓取到很多不相干的包。由于我們已經執行過 ping 命令,知道了 geekbang.org 的 IP 地址是 35.190.27.188,也知道 ping 命令會執行 DNS 查詢。所以,上面這條命令,就是基于這個規則進行過濾。 我來具體解釋一下這條命令。- -nn ,表示不解析抓包中的域名(即不反向解析)、協議以及端口號。
- udp port 53 ,表示只顯示 UDP 協議的端口號(包括源端口和目的端口)為 53 的包。
- host 35.190.27.188 ,表示只顯示 IP 地址(包括源地址和目的地址)為 35.190.27.188 的包。
- 這兩個過濾條件中間的“ or ”,表示或的關系,也就是說,只要滿足上面兩個條件中的任一個,就可以展示出來。
- 36909+ 表示查詢標識值,它也會出現在響應中,加號表示啟用遞歸查詢。
- A? 表示查詢 A 記錄。
- geektime.org. 表示待查詢的域名。
- 30 表示報文長度。
tcpdump
我們知道,tcpdump 也是最常用的一個網絡分析工具。它基于 libpcap ,利用內核中的 AF_PACKET 套接字,抓取網絡接口中傳輸的網絡包;并提供了強大的過濾規則,幫你從大量的網絡包中,挑出最想關注的信息。 tcpdump 為你展示了每個網絡包的詳細細節,這就要求,在使用前,你必須要對網絡協議有基本了解。而要了解網絡協議的詳細設計和實現細節, RFC 當然是最權威的資料。 不過,RFC 的內容,對初學者來說可能并不友好。如果你對網絡協議還不太了解,推薦你去學《TCP/IP 詳解》,特別是第一卷的 TCP/IP 協議族。這是每個程序員都要掌握的核心基礎知識。 再回到 tcpdump 工具本身,它的基本使用方法,還是比較簡單的,也就是 tcpdump [選項] [過濾表達式]。當然,選項和表達式的外面都加了中括號,表明它們都是可選的。 提示:在 Linux 工具中,如果你在文檔中看到,選項放在中括號里,就說明這是一個可選選項。這時候就要留意一下,這些選項是不是有默認值。 查看 tcpdump 的 手冊 ,以及 pcap-filter 的手冊,你會發現,tcpdump 提供了大量的選項以及各式各樣的過濾表達式。不過不要擔心,只需要掌握一些常用選項和過濾表達式,就可以滿足大部分場景的需要了。 為了幫你更快上手 tcpdump 的使用,我在這里也幫你整理了一些最常見的用法,并且繪制成了表格,你可以參考使用。 首先,來看一下常用的幾個選項。在上面的 ping 案例中,我們用過 -nn 選項,表示不用對 IP 地址和端口號進行名稱解析。其他常用選項,我用下面這張表格來解釋。 接下來,我們再來看常用的過濾表達式。剛剛用過的是 udp port 53 or host 35.190.27.188 ,表示抓取 DNS 協議的請求和響應包,以及源地址或目的地址為 35.190.27.188 的包。 其他常用的過濾選項,我也整理成了下面這個表格。 最后,再次強調 tcpdump 的輸出格式,我在前面已經介紹了它的基本格式: 時間戳 協議 源地址. 源端口 > 目的地址. 目的端口 網絡包詳細信息 其中,網絡包的詳細信息取決于協議,不同協議展示的格式也不同。所以,更詳細的使用方法,還是需要你去查詢 tcpdump 的 man 手冊(執行 man tcpdump 也可以得到)。 不過,講了這么多,你應該也發現了。tcpdump 雖然功能強大,可是輸出格式卻并不直觀。特別是,當系統中網絡包數比較多(比如 PPS 超過幾千)的時候,你想從 tcpdump 抓取的網絡包中分析問題,實在不容易。 對比之下,Wireshark 則通過圖形界面,以及一系列的匯總分析工具,提供了更友好的使用界面,讓你可以用更快的速度,擺平網絡性能問題。接下來,我們就詳細來看看它。Wireshark
Wireshark 也是最流行的一個網絡分析工具,它最大的好處就是提供了跨平臺的圖形界面。跟 tcpdump 類似,Wireshark 也提供了強大的過濾規則表達式,同時,還內置了一系列的匯總分析工具。 比如,拿剛剛的 ping 案例來說,你可以執行下面的命令,把抓取的網絡包保存到 ping.pcap 文件中: $ tcpdump -nn udp port 53 or host 35.190.27.188 -w ping.pcap 接著,把它拷貝到你安裝有 Wireshark 的機器中,比如你可以用 scp 把它拷貝到本地來: $ scp host-ip/path/ping.pcap . 然后,再用 Wireshark 打開它。打開后,你就可以看到下面這個界面: 從 Wireshark 的界面里,你可以發現,它不僅以更規整的格式,展示了各個網絡包的頭部信息;還用了不同顏色,展示 DNS 和 ICMP 這兩種不同的協議。你也可以一眼看出,中間的兩條 PTR 查詢并沒有響應包。 接著,在網絡包列表中選擇某一個網絡包后,在其下方的網絡包詳情中,你還可以看到,這個包在協議棧各層的詳細信息。比如,以編號為 5 的 PTR 包為例: 你可以看到,IP 層(Internet Protocol)的源地址和目的地址、傳輸層的 UDP 協議(Uder Datagram Protocol)、應用層的 DNS 協議(Domain Name System)的概要信息。 繼續點擊每層左邊的箭頭,就可以看到該層協議頭的所有信息。比如點擊 DNS 后,就可以看到 Transaction ID、Flags、Queries 等 DNS 協議各個字段的數值以及含義。 當然,Wireshark 的功能遠不止如此。接下來我再帶你一起,看一個 HTTP 的例子,并理解 TCP 三次握手和四次揮手的工作原理。 這個案例我們將要訪問的是 http://example.com/ 。進入終端一,執行下面的命令,首先查出 example.com 的 IP。然后,執行 tcpdump 命令,過濾得到的 IP 地址,并將結果保存到 web.pcap 中。 $ dig +short example.com 93.184.216.34 $ tcpdump -nn host 93.184.216.34 -w web.pcap 實際上,你可以在 host 表達式中,直接使用域名,即 tcpdump -nn host example.com -w web.pcap。 接下來,切換到終端二,執行下面的 curl 命令,訪問 http://example.com: $ curl http://example.com 最后,再回到終端一,按下 Ctrl+C 停止 tcpdump,并把得到的 web.pcap 拷貝出來。 使用 Wireshark 打開 web.pcap 后,你就可以在 Wireshark 中,看到如下的界面: 由于 HTTP 基于 TCP ,所以你最先看到的三個包,分別是 TCP 三次握手的包。接下來,中間的才是 HTTP 請求和響應包,而最后的三個包,則是 TCP 連接斷開時的三次揮手包。 從菜單欄中,點擊 Statistics -> Flow Graph,然后,在彈出的界面中的 Flow type 選擇 TCP Flows,你可以更清晰的看到,整個過程中 TCP 流的執行過程: 這其實跟各種教程上講到的,TCP 三次握手和四次揮手很類似,作為對比, 你通常看到的 TCP 三次握手和四次揮手的流程,基本是這樣的: (圖片來自酷殼) 不過,對比這兩張圖,你會發現,這里抓到的包跟上面的四次揮手,并不完全一樣,實際揮手過程只有三個包,而不是四個。 其實,之所以有三個包,是因為服務器端收到客戶端的 FIN 后,服務器端同時也要關閉連接,這樣就可以把 ACK 和 FIN 合并到一起發送,節省了一個包,變成了“三次揮手”。 而通常情況下,服務器端收到客戶端的 FIN 后,很可能還沒發送完數據,所以就會先回復客戶端一個 ACK 包。稍等一會兒,完成所有數據包的發送后,才會發送 FIN 包。這也就是四次揮手了。 抓包后, Wireshark 中就會顯示下面這個界面(原始網絡包來自 Wireshark TCP 4-times close 示例,你可以點擊 這里 下載): 當然,Wireshark 的使用方法絕不只有這些,更多的使用方法,同樣可以參考官方文檔 以及 WIKI。小結
今天,我們一起學了 tcpdump 和 Wireshark 的使用方法,并通過幾個案例,學會了如何運用這兩個工具來分析網絡的收發過程,并找出潛在的性能問題。 當你發現針對相同的網絡服務,使用 IP 地址快而換成域名卻慢很多時,就要想到,有可能是 DNS 在搗鬼。DNS 的解析,不僅包括從域名解析出 IP 地址的 A 記錄請求,還包括性能工具幫你,“聰明”地從 IP 地址反查域名的 PTR 請求。 實際上,根據 IP 地址反查域名、根據端口號反查協議名稱,是很多網絡工具默認的行為,而這往往會導致性能工具的工作緩慢。所以,通常,網絡性能工具都會提供一個選項(比如 -n 或者 -nn),來禁止名稱解析。 在工作中,當你碰到網絡性能問題時,不要忘記 tcpdump 和 Wireshark 這兩個大殺器。你可以用它們抓取實際傳輸的網絡包,再排查是否有潛在的性能問題。 思考 最后,我想請你來聊一聊,你是如何使用 tcpdump 和 Wireshark 的。你用 tcpdump 或者 Wireshark 解決過哪些網絡問題呢?你又是如何排查、分析并解決的呢?你可以結合今天學到的網絡知識,總結自己的思路。 林沛滿的書都看過,確實寫的相當好,都是案例驅動。 把協議講的生動有趣就數他。 wireshark的使用推薦閱讀林沛滿的《Wireshark網絡分析就這么簡單》和《Wireshark網絡分析的藝術》 老師,這個案例寫的極其生動:D, 就是問一句,現在我們的項目都是https,那么如果抓包https,tcpdump或者wireshark是否可以解密?因為我看到wireshark解密需要private key,但是private key涉及安全問題,肯定都拿不到,那么你們遇到抓包https后解析是怎么做的呢? 作者回復: 嗯,證書解密是最簡單的方法,也可以使用 MitM(Man-in-the-middle)方法 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的38 | 案例篇:怎么使用 tcpdump 和 Wireshark 分析网络流量?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 37 | 案例篇:DNS 解析时快时慢,
- 下一篇: 39 | 案例篇:怎么缓解 DDoS 攻