计网 - TCP 实战:如何进行 TCP 抓包调试?
文章目錄
- Pre
- 接口列表
- 開啟捕獲功能
- 觀察 TCP 協(xié)議
- 消息視圖
- 觀察 HTTP 協(xié)議
- 過濾和篩選
- 報文顏色
- 總結(jié)
- QA: 請你用自己最熟悉的語言,寫一個 UDP 連接程序,然后用 Wireshark 抓包。
Pre
Wireshark 是世界上應(yīng)用最廣泛的網(wǎng)絡(luò)協(xié)議分析器,它讓我們在微觀層面上看到整個網(wǎng)絡(luò)正在發(fā)生的事情。
Wireshark 本身是一個開源項目,所以也得到了很多志愿者的支持。同時,Wireshark 具有豐富的功能集,包括:
-
深入檢查數(shù)百個協(xié)議,并不斷添加更多協(xié)議;
-
實時捕獲和離線分析;
-
支持 Windows、Linux、macOS、Solaris、FreeBSD、NetBSD,以及許多其他平臺;
-
提供 GUI 瀏覽,也可以通過 TTY;
-
支持 VOIP;
-
支持 Gzip;
-
支持 IPSec。
……
Wireshark 的主頁:https://www.wireshark.org/download.html下載 Wireshark
那如何通過wireshark進行 TCP 抓包和調(diào)試?
接口列表
Whireshark 可以幫你看到整個網(wǎng)絡(luò)交通情況,也可以幫你深入了解每個封包。而且 Whireshark 在 macOS、Linux、Windows 上的操作都是一致的,打開 Wireshark 會先看到如下圖所示的一個選擇網(wǎng)絡(luò)接口的界面。
我們要做的第一件事情就是選擇一個網(wǎng)絡(luò)接口(Network Interface)。Linux 下可以使用ifconfig指令看到所有的網(wǎng)絡(luò)接口,Windows 下則使用 ipconfig??梢钥吹?#xff0c;上圖中有很多網(wǎng)絡(luò)接口,目前我連接路由器的接口是以太網(wǎng) 2。
開啟捕獲功能
選擇好接口之后,點擊左上角的按鈕就可以開啟捕獲,開啟后看到的是一個個數(shù)據(jù)條目。
因為整個網(wǎng)絡(luò)的數(shù)據(jù)非常多,大量的應(yīng)用都在使用網(wǎng)絡(luò),你會看到非常多數(shù)據(jù)條目,每個條目是一次數(shù)據(jù)的發(fā)送或者接收。如下圖所示:
以下是具體捕獲到的內(nèi)容:
-
序號(No.)是 Wireshark 分配的一個從捕獲開始的編號。
-
時間(Time)是從捕獲開始過去的時間戳,具體可以在視圖中設(shè)置,比如可以設(shè)置成中文的年月日等。這里有很多配置需要你自己摸索一下,我就不詳細介紹了。
-
源地址和目標(biāo)地址(Source 和 Destination)是 IP 協(xié)議,注意這里有 IPv6 的地址,也有 IPV4 的地址。
-
協(xié)議可能有很多種,比如 TCP/UDP/ICMP 等,ICMP 是 IP 協(xié)議之上搭建的一個消息控制協(xié)議(Internet Control Message Protocol),比如 Ping 用的就是 ICMP;還有 ARP 協(xié)議(Address Resolution Protocol)用來在局域網(wǎng)廣播自己的 MAC 地址。
-
Length 是消息的長度(Bytes)。
-
Info 是根據(jù)不同協(xié)議顯示的數(shù)據(jù),比如你可以看到在TCP 協(xié)議上看到Seq 和 ACK。這里的 Seq 和 ACK 已經(jīng)簡化過了,正常情況下是一個大隨機數(shù),Whireshark 幫你共同減去了一個初始值。
觀察 TCP 協(xié)議
如果你具體選擇一個 TCP 協(xié)議的捕獲,可以看到如下圖所示的內(nèi)容:
然后在這下面可以觀察到詳情內(nèi)容:
我們可以從不同的層面來看這次捕獲。從傳輸層看是 TCP 段;從網(wǎng)絡(luò)層來看是 IP 封包;從鏈路層來看是 Frame。
點開不同層面觀察這個 TCP 段,就可以獲得對它更具體的認識,例如下圖是從 TCP 層面理解這次捕獲:
你可以看到這次捕獲是一次 ACK(見 Flags)字段,從端口 58260 發(fā)往 443,那么大概率是 HTTPS 客戶端給服務(wù)器的響應(yīng)。
消息視圖
如果你選中一條消息,下面會出現(xiàn)一個消息視圖。還有一個二進制視圖。二進制視圖里面是數(shù)據(jù)的二進制形式,消息視圖是對二進制形式的解讀。
Whireshark 追溯的是最底層網(wǎng)卡傳輸?shù)?Frame(幀),可以追溯到數(shù)據(jù)鏈路層。因此對二進制形式的解讀,也就是我們的消息視圖也要分層。因為對于同樣的數(shù)據(jù),不同層的解讀是不同的。
-
最上面是 Frame 數(shù)據(jù),主要是關(guān)注數(shù)據(jù)的收發(fā)時間和大小。
-
接著是數(shù)據(jù)鏈路層數(shù)據(jù),關(guān)注的是設(shè)備間的傳遞。你可以在這里看到源 MAC 地址和目標(biāo) MAC 地址。
-
然后是網(wǎng)絡(luò)層數(shù)據(jù),IP 層數(shù)據(jù)。這里有 IP 地址(源 IP 地址和目標(biāo) IP 地址);也有頭部的 Checksum(用來糾錯的)
-
最下面是傳輸層數(shù)據(jù)。 也就是 TCP 協(xié)議。關(guān)注的是源端口,目標(biāo)端口,Seq、ACK 等。
-
有的傳輸層上還有一個 TLS 協(xié)議,這是因為用 HTTPS 請求了數(shù)據(jù)。TLS 也是傳輸層。TLS 是建立在 TCP 之上,復(fù)用了 TCP 的邏輯。
觀察 HTTP 協(xié)議
Wireshark 還可以用來觀察其他的協(xié)議,比如說 HTTP 協(xié)議,下圖是對 HTTP 協(xié)議的一次捕獲:
可以看到,Wireshark 不僅僅捕獲了應(yīng)用層,還可以看到這次 HTTP 捕獲對應(yīng)的傳輸層、網(wǎng)絡(luò)層和鏈路層數(shù)據(jù)。
過濾和篩選
Wireshark 還提供了捕獲的過濾,我們只需要輸入過濾條件,就可以只看符合條件的捕獲。
比如我們想分析一次到百度的握手。首先開啟捕獲,然后在瀏覽器輸入百度的網(wǎng)址,最后通過ping指令看下百度的 IP 地址,如下圖所示:
看到IP 地址之后,我們在 Wireshark 中輸入表達式,如下圖所示:
這樣看到的就是和百度關(guān)聯(lián)的所有連接。上圖中剛好是一次從建立 TCP 連接(3 次握手),到 HTTPS 協(xié)議傳輸握手的完整過程。你可以只看從192.168.1.5到14.215.177.39的請求。
首先是從客戶端(192.168.1.5)發(fā)出的 SYN 和百度返回的 SYN-ACK,如下圖所示:
然后是客戶端返回給百度一個 ACK:
接下來是 HTTPS 協(xié)議開始工作(開始握手):
可以看到 HTTPS 協(xié)議通過 TLSv1.2 發(fā)送了 Client Hello 到服務(wù)端。接下來是 Server 返回給客戶端 ACK,然后再發(fā)送給客戶端一個 Server Hello:
之后百度回傳了證書:
最后開始交換密鑰,直到 HTTPS 握手結(jié)束:
報文顏色
在抓包過程中,黑色報文代表各類報文錯誤;紅色代表出現(xiàn)異常;其他顏色代表正常傳輸。
總結(jié)
Wireshark 是個強大的工具,支持大量的協(xié)議。還有很多關(guān)于 Wireshark 的能力,希望你可以進一步探索,如下圖中鼠標(biāo)右鍵一次捕獲,可以看到很多選項,都是可以深挖的。
QA: 請你用自己最熟悉的語言,寫一個 UDP 連接程序,然后用 Wireshark 抓包。
以 Java 為例,寫了一個回聲服務(wù)(即客戶端發(fā)送什么服務(wù)段返回什么),以下是服務(wù)端程序:
var socket = new DatagramSocket(8888);var buf = new byte[256];while (true) {DatagramPacket packet= new DatagramPacket(buf, buf.length);System.out.println("try receive...");socket.receive(packet);var address = packet.getAddress();int port = packet.getPort();packet = new DatagramPacket(buf, buf.length, address, port);String received= new String(packet.getData(), 0, packet.getLength());socket.send(packet);}以下是客戶端程序:
var buf = "Hello".getBytes();var socket = new DatagramSocket();var address = InetAddress.getByName("localhost");var packet= new DatagramPacket(buf, buf.length, address, 8888);socket.send(packet);socket.receive(packet);String received = new String(packet.getData(), 0, packet.getLength());System.out.format("Server echo : %s\n", received);通過觀察上面兩段程序,你會發(fā)現(xiàn)發(fā)送和接收的都是Datagram報文。而且服務(wù)端和客戶端之間不需要建立連接。服務(wù)端可以通過讀取客戶端的地址區(qū)分客戶端,客戶端通過服務(wù)端地址和端口發(fā)送數(shù)據(jù)到服務(wù)端。
總結(jié)
以上是生活随笔為你收集整理的计网 - TCP 实战:如何进行 TCP 抓包调试?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计网 - IPv4 协议:路由和寻址的区
- 下一篇: 计网 - 流和缓冲区:缓冲区的 flip