37_用_Wireshark_研究一个完整的_TCP
网络协议那些事儿
内容简介
-
前言
-
Wireshark,网络扫描仪
-
研究一个完整的 TCP 连接
-
总结
-
前言
上两课我们学习了不少理论知识,了解了 UDP 和 TCP 这两个 OSI 第 4 层最重要的协议。
在学习了理论之后,我们这一课就来实践一下。我们一起来查看在客户端与服务器的通信期间交换的 TCP Segment(报文段)。我们还将进一步学习如何使用嗅探器软件,以监听网络上发生的事情。
- Wireshark,网络扫描仪
工具介绍
Wireshark 是一个极为强大的软件,可以帮助我们监听网络上发生的事情,通常被称为嗅探器(sniffer)。
Wireshark 的官方文档在 这里。你也可以在网上搜到很多 Wireshark 的中文文档和教程。
所以我假设你已经安装好 Wireshark 这个软件了,如果还没有的话,请安装一下。
具体来说,Wireshark 可以捕获到达你的网卡上的网络数据包,并将数据包的内容以清晰易懂的形式呈现给你。Wireshark 能查看到以你的网卡为目标的所有数据包。
我们需要区分几个概念:
- 所有的网络数据包
- 以你的机器为目标的所有数据包
- 以你的网卡为目标的所有数据包
事实上,通过你的网卡的数据包不一定都是以你的机器为目标的。例如,通过广播发送的数据包就属于这种情况,或者如果你是一台路由器,那么数据包将通过你转发,也是属于这种情况。同样,在交换机网络上(机器之间通过交换机相互连接),你不会看到所有网络数据包,只会看到发往你的网卡的数据包(目标 MAC 地址为你的网卡的 MAC 地址的数据包,或者是广播的数据包)。
因此,Wireshark 将收到 0 和 1 的二进制数据,当然了,由于它知道网络协议,因此能够翻译这些数据,并将其很好地呈现给我们!
安装完成之后,我们双击应用程序中 Wireshark 的图标,就会打开 Wireshark 了,首先它会显示各个网络接口,默认显示的是所有的接口:
你可以点击 “显示所有接口” 的那个下拉菜单,就会显示过滤选项了,可以看到默认显示全部接口,接口类型包括 “有线”、“无线” 和 “外部捕获”,你可以点击其中的选项来设置它们的显示与否:
一般我们不需要去调整显示的接口选项。我目前电脑上网用的是 WiFi 无线连接,所以如下图所示,显示有流量的主要是 Wi-Fi: en0 这个接口(还有一个是 Loopback: lo0,表示本地回环,我们不看):
在我的情况下,双击有流量波动的 Wi-Fi: en0 那一行,进入流量捕获窗口:
我们可以看到很多行,很多字符。每一行都有含义和意义,我们现在就来研究这些行。
Wireshark 主要窗口的介绍
Wireshark 的主要窗口(就是一般我们使用的流量捕获窗口)主要包括四个部分:
- 菜单;
- 捕获到的数据包的摘要呈现;
- 指定数据包的详细呈现;
- 数据包的十六进制内容。
菜单
下图显示的菜单主要由我们可以使用 Wireshark 进行的操作组成:
菜单中有一部分很重要,就是过滤器(filter),是上图中 “应用显示过滤器 …” 那个栏目。
你可以在过滤器的框中填入你的过滤选项,比如我们可以根据某些条件(例如 IP 地址或端口)来过滤 Wireshark 显示的信息。
Wireshark 也为我们预设了不少过滤选项,只要点击过滤器栏目最左边的 “书签” 状图标,就会显示如下图的下拉菜单,你可以选择你想要的过滤选项:
过滤器很有用,例如我们要追踪 TCP 连接,就可以设置过滤器只显示 TCP 的数据包(上图中的 TCP only: tcp),而不显示例如 UDP 的数据包或其他会干扰我们的数据包。我们待会就会用到过滤器。
捕获到的数据包的摘要呈现
除了上方的菜单部分,第二部分是捕获到的数据包的摘要列表:
上图中每一行对应了一个捕获到的 packet(数据包),或者称为 message(报文,消息)。
每一行都有 7 列数据,分别是:
-
No. :no 是 number 的缩写,表示 “编号,号码”,就是数据包的编号。编号是从 1 开始递增的。
-
Time :time 表示 “时间”。默认是一个相对时间,就是捕获到此数据包的时间相对于捕获到编号为 1 的第一个数据包的时间的差额,单位是秒,精确到小数点后面六位。
如果用最右边的滚动栏把列表拉到最开始的地方,可以看到 No. 是以 1 开始的,逐渐递增。No. 为 1 的数据包的 Time 是 0。见下图:
-
Source :source 表示 “源”,就是此数据包的源 IP 地址。
-
Destination :destination 表示 “目标,目的地”,就是此数据包的目标 IP 地址。
-
Protocol :protocol 表示 “协议”,就是此数据包最近一层封装的协议。
-
Length :length 表示 “长度”,就是此数据包的长度,单位是 byte(字节)。
-
Info :info 是 information 的缩写,表示 “信息”,就是此数据包的其他相关信息。
以上 7 列的信息的显示格式都是可以在菜单中进行设置的,比如 Time 那列的时间可以设置为绝对时间。
指定数据包的详细呈现
第三部分是指定数据包的详细呈现。默认地,它会显示第 1 个数据包的详细信息。如果你点击第二部分 “捕获到的数据包的摘要列表” 中的某一行,就会显示此数据包的详细信息。Wireshark 将 OSI 模型的每个层的相关信息分开展示:
我们可以看到 OSI 的各层的信息,比如上图中编号为 12710 的这个数据包。通过单击每一层前面的三角形,我们能看到每个层的相关内容:
- Ethernet II :第 2 层数据链路层的以太网帧的头部信息。
-
Internet Protocol Version 4 :第 3 层网络层的 IP 数据包的头部信息。
-
Transmission Control Protocol :第 4 层传输层的数据段的头部信息。此处是 TCP 协议。如果是 UDP 协议,则是 User Datagram Protocol。
- Transport Layer Security :缩写为 TLS,表示 “传输层安全协议”,这是第 7 层应用层的 HTTPS 协议使用的 TLS 协议,因为 HTTPS 协议就是使用 TLS 协议来加密的 HTTP 协议,TLS 的前身是 SSL 协议。现在大部分网站都是用 HTTPS 协议了,很少有网站还在用 HTTP 这样不安全的协议。
上图中,可以看到 http_over_tls,其实就是 HTTPS 的全称。可以看到 Encrypted Application Data,表示 “加密的应用数据”,对应的值就是用 TLS 协议加密了的应用数据。
数据包的十六进制内容
数据包的十六进制内容稍微复杂一点,它是数据包的原始内容,就是没有经过 Wireshark 翻译的。如果你想查看数据包的实际内容,而不仅仅是 Wireshark 翻译的内容,这会很有用。数据包的实际内容和 Wireshark 的翻译结果之间可能会有差异:
好的,介绍了 Wireshark 的基本情况之后,让我们研究一个完整的 TCP 连接吧!
- 研究一个完整的 TCP 连接
我们要用 Wireshark 来研究一个完整的 TCP 连接。
注意,如果你是在 Linux 操作系统中用命令行来启动 Wireshark 的,请确认你具有 root 权限(用 sudo wireshark
来启动),否则 Wireshark 将没有访问网络接口收到的帧的权限。当然了,你也可以用设置用户和群组的方式来达到不需要 root 权限也可以访问的目的,具体怎么做可以去网上搜索文章。
启动一个连接
现在,你的 Wireshark 应该已经启动了,并且你所在的窗口是流量捕获窗口,正在捕获提供你上网的那个网络接口(我的情况是 Wi-Fi: en0 这个网络接口,因为我是用 WiFi 上网的)上的数据包。
为了研究一个完整的 TCP 连接,我们只需要用浏览器打开一个网页即可。例如我们可以打开著名的 Github 的官网(https://github.com):
等待页面显示,并返回 Wireshark,然后按下图中所示的方形红色停止图标来停止 Wireshark 的数据包捕获,为的是不捕获过多的数据包:
你现在应该已经捕获到了一些网络数据包,我们将一起对其进行分析。但是在此之前,我们将尝试对所有收到的数据包进行分类。也许我们监听的网络接口的流量很大,而我们感兴趣的数据包就被其他不相关的数据包给 “淹没” 了。因此,Wireshark 允许我们按规则来过滤出某些特定的数据包。
为此,我们将在之前介绍过的过滤器的栏中填入一个过滤规则。我们将以 Github 官网的服务器的 IP 地址作为要过滤的值。
某个网站的服务器的 IP 地址可以通过在线的一些 IP 地址查询网站来查询,例如:
或者你也可以在终端命令行中用 ping 命令来获知 IP 地址,用 ping github.com
:
可以看到,用在线的 IP 地址查询网站或 ping 命令得到的 Github 官网的服务器地址是一样的,都是 13.250.177.223。当然了,每次查询得到的 IP 地址不一定是一样的,请以你自己查询得到的 IP 地址为准。
所以,我们就只想让 Wireshark 显示包含 IP 地址 13.250.177.223 的数据包。为此,我们将在过滤器栏中写入 ip.addr == 13.250.177.223。ip.addr 是 IP address 的缩写,表示 “IP 地址”。== 是等于符号,表示此规则选项的值等于后面接的那个值。
输入 ip.addr == 13.250.177.223 之后,你可以按下回车,或者可以点击过滤器栏目右边的箭头标志(下图中用红框标出的)“Apply display filter”(表示 “应用显示过滤器”)以应用你指定的基于 IP 地址的过滤器:
现在,你应该只看到与 IP 地址 13.250.177.223 相关的数据包了:
我们可以在 Info 列中看到前三个数据包是依次具有标志位 SYN,SYN + ACK 和 ACK 的 TCP 数据包,这里显示的是 [SYN],[SYN, ACK],[ACK]。因此,连接已被正确建立!
这里的 192.168.0.109 是我电脑上的 en0 这个 WiFi 无线接口的 IP 地址,代表客户端(client)。而 IP 地址 13.250.177.223 就代表服务器(server)。
现在,我们将仔细研究其中一些数据包。
研究数据包
我们将单击第一个具有标志位 SYN 的数据包并观察其内容。在指定数据包的详细呈现中,我们看到了数据包的不同层的信息:
第一行以粗略的方式展示我们的数据包,即 OSI 第 1 层,也就是 0 和 1 这样的二进制数据流!数据包的大小是 78 bytes(字节)。
第二行代表 OSI 第 2 层,我们可以看到 MAC 地址(源 MAC 地址和目标 MAC 地址)。
源 MAC 地址就是我的无线网卡的 MAC 地址。源 MAC 地址的前三个字节是 Apple_ 。如果你还记得的话,我们以前在讲 MAC 地址的那课中说过,MAC 地址的前三个字节代表了网卡的制造商,这里的 Apple 表示 “苹果”,就是指苹果公司,表明我的笔记本电脑是苹果的 MacBook。
第三行代表 OSI 模型的第 3 层,我们可以看到 IP 地址(源 IP 地址和目标 IP 地址)。
最后,第四行代表 OSI 第 4 层,我们可以看到 TCP 端口(源端口号和目标端口号)。
为什么只有四行呢?为什么没有 OSI 第 7 层(应用层)呢?
确实还没有。实际上,在能够交换应用程序的数据之前,必须先建立 TCP 连接。因此,我们的 “三次握手” 过程必须结束。一开始只有三个 TCP 报文段被交换(用于 “三次握手”),从第四个数据包开始才可能包含应用程序数据。
现在,我们将详细介绍每一层的内容。只需点击每一行最左边的小三角箭头即可展开每一层的信息。
让我们从 OSI 第 2 层开始:
正如我们预想的那样,我们看到了那些已经了解的信息,因为我们以前学习第 2 层时已经讲解过了。那时候我们说以太网帧是这样的:
我们首先可以看到目标 MAC 地址(Destination),然后是源 MAC 地址(Source),最后是所使用的第 3 层协议,这里是 IP(IPv4 表示 IP 协议第 4 版)。
这也证明到目前为止,我们所讲的知识点是正确的。
接着,我们来看第 3 层:
OSI 第 3 层的头部比较复杂,因为我们还没有介绍过 IP 数据包头部的全部内容。但是,我们可以在头部的末尾看到源 IP 地址(Source)和目标 IP 地址(Destination)。
最后,让我们看一下第 4 层:
和第 3 层类似,也比较复杂,因为我们也还没有介绍过第 4 层数据包的头部的所有内容,但是我们可以看到位于头部开头的端口(Source Port 和 Destination Port,就是源端口号和目标端口号),以及头部中间的标志位(Flags)。
在标志位(Flags)的信息中,我们看到已设置了 SYN 标志( 0x002 (SYN) ),可以通过单击标志位前面的三角形来展开详细信息:
可以看到我们已经了解过的 6 个标志位:URG,ACK,PSH,RST,SYN 和 FIN。其中,只有 SYN 标志位被设置了。Set 表示 “设置”,Not set 表示 “没有设置”。
因此,连接的第一个 TCP 报文段确实是用于请求建立连接的 SYN 报文段。
在 TCP 报文的头部中还有其他元素(Nonce,Congestion Window Reduced,ENC-Echo,等等),但我们对它们不感兴趣,因为它们涉及 TCP 协议的高级功能,这超出了本专栏的范围。如果你感兴趣,可以去网上搜索它们的相关资料。
同样地,如果查看 “三次握手” 的第 2 个数据包,则可以在第 4 层的信息中看到 SYN 和 ACK 标志位被设置了:
如果查看 “三次握手” 的第 3 个数据包,则可以在第 4 层的信息中看到 ACK 标志位被设置了:
因此,“三次握手” 顺利完成,我们的 TCP 连接已正确建立。
因此,接下来的数据包就可以进行应用程序的数据交换,即第 7 层应用层的 Web 数据交换。
事实上,我们可以看到这样的帧在 TCP 层之后还有一个附加层,是应用层使用的协议。例如我们点击其中一个应用数据包(Info 那列是 Application Data 的):
可以看到第五行是我们之前提过的 TLS(Transport Layer Security)协议,因为 HTTPS 协议简单来说就是使用了 TLS 协议来加密的 HTTP 协议。Github 的官网的完整 URL 是 https://github.com,冒号前的 https 表示使用的是 HTTPS 协议。
我们可以点击第五行的小三角形,来查看详细内容:
不过,Wireshark 只能显示 HTTP 协议传递的应用程序的数据,而 HTTPS 协议传递的应用程序的数据是加密的,Wireshark 显示不了。因此上图中显示的是 Encrypted Application Data,表示 “加密的应用数据”,后面那一串十六进制数据就是加密之后的数据。有的嗅探器软件可以看到 HTTPS 的应用程序的数据。
只要连接保持着,客户端和服务器就可以交换数据包。这些数据包当中,有些是包含应用程序数据的数据包(就是包含要传递的信息的);但也有一些不包含应用程序数据的数据包,这些数据包被称为信令数据包(Signalling Packet)。信令数据包通过不断向另一台机器传达本机的连接状态来保持两台机器之间的连接。这是为了确保在交换过程中不会丢失任何信息。以后我们将会介绍。
浏览器收到所有信息并显示网站后,就需要正确终止 TCP 连接。
这是通过 “四次挥手”,也就是交换以下四个数据包来完成的:
- FIN(或 FIN + ACK)
- ACK
- FIN(或 FIN + ACK)
- ACK
我们可以在数据包列表中查找 FIN 字符串,在菜单栏中点击 “放大镜” 图标:
点击之后,就会出现搜索框,可以选择 “字符串” 为查找目标,然后在搜索栏中填入 FIN :
点击 “查找”,就会查找数据包列表中包含 FIN 的那些行。
例如,我们可以看到类似下面的几行:
对于连接的终止,可能比较难看到完整的 “四次挥手” 的四个数据包按序交换,因为可能被其他数据包打断或有 RST 数据包进行了连接的重置。
不过,我们还是可以看到设置了 [FIN, ACK] 标志位的数据包的详细信息,例如:
我们的 TCP 连接就被终止了。
- 总结
借助 Wireshark 嗅探器(sniffer),我们可以看到网络中流通的数据包,甚至可以详细跟踪连接的进展情况。TCP 连接的进展情况也证实了我们之前所讲的知识是正确的。
如果你遇到网络连接问题,就可以用 Wireshark 等嗅探器来了解到底发生了什么。对于网络管理员来说,嗅探器是必不可少的工具,请学会使用。
很好,
-
你已经知道了机器上应用程序的地址,就是 port(端口)。
-
你也知道了第 4 层包含两个协议,TCP 协议和 UDP 协议。这两个协议是不同的,因为 TCP 是面向连接的协议,而 UDP 不是。
-
最后,借助嗅探器,你可以具体地了解网络上正在传输的内容。
下一课开始,我们将学习当应用程序位于私有网络(Private Network。例如,你自己家里的网络)中时,如何能被外界访问到。
一起加油吧~
}如果您想了解更多技术资源,欢迎加入点击这里钉钉群交流IT技术资源查看“IT技术交流群一”群的钉钉群号: 129605002953