Wireshark实验
文章目录
数据链路层
实作一 熟悉 Ethernet 帧结构
使用 Wireshark 任意进行抓包,熟悉 Ethernet 帧的结构,如:目的 MAC、源 MAC、类型、字段等。
✎ 问题
你会发现 Wireshark 展现给我们的帧中没有校验字段,请了解一下原因。
网卡接收到一个帧,第一步就是计算FCS,并与接收到的帧尾的FCS进行对比,如果一致,则接收,如果不一致则丢弃。而Wireshark抓到的帧,是FCS校验通过的帧,而帧尾的FCS会被硬件去掉,所以没有FCS。另一方面,wireshark也不会抓到FCS校验失败的帧。
实作二 了解子网内/外通信时的 MAC 地址
ping 你旁边的计算机(同一子网),同时用 Wireshark 抓这些包(可使用 icmp 关键字进行过滤以利于分析),记录一下发出帧的目的 MAC 地址以及返回帧的源 MAC 地址是多少?这个 MAC 地址是谁的?
发出帧的目的MAC地址:34:4b:50:00:00:00 返回帧的源MAC地址:34:4b:50:00:00:00 这个 MAC地址:是ping的那个同一个子网内的计算机MAC地址
然后 ping qige.io (或者本子网外的主机都可以),同时用 Wireshark 抓这些包(可 icmp 过滤),记录一下发出帧的目的 MAC 地址以及返回帧的源 MAC 地址是多少?这个 MAC 地址是谁的?
发出帧的目的 MAC 地址:00:74:9c:9f:40:13 返回帧的源 MAC 地址:00:74:9c:9f:40:13
这个MAC地址是网关的
再次 ping www.cqjtu.edu.cn (或者本子网外的主机都可以),同时用 Wireshark 抓这些包(可 icmp 过滤),记录一下发出帧的目的 MAC 地址以及返回帧的源 MAC 地址又是多少?这个 MAC 地址又是谁的?
发出帧的目的 MAC 地址:00:74:9c:9f:40:13 返回帧的源 MAC 地址:00:74:9c:9f:40:13
这个MAC地址是网关的
✎ 问题
通过以上的实验,你会发现:
访问本子网的计算机时,目的 MAC 就是该主机的
访问非本子网的计算机时,目的 MAC 是网关的
请问原因是什么?
本机接收到的本子网以外的信息必定经由网关到本机,本机发送信息到子网外经过的下个地址必定是网关的mac地址。而本子网内的可以直接到达,不经过网关。发送帧的目的mac地址是下一跳的mac地址。
实作三 掌握 ARP 解析过程
为防止干扰,先使用 arp -d * 命令清空 arp 缓存
出错:ARP项删除失败:请求的操作需要提升。 以管理员的身份执行此命令即可。
ping 你旁边的计算机(同一子网),同时用 Wireshark 抓这些包(可 arp 过滤),查看 ARP 请求的格式以及请求的内容,注意观察该请求的目的 MAC 地址是什么。再查看一下该请求的回应,注意观察该回应的源 MAC 和目的 MAC 地址是什么。
请求的目的MAC是ping的那个同一子网的主机的。
返回的源MAC是ping的那个同一子网的主机的,目的MAC是本机的。
再次使用 arp -d * 命令清空 arp 缓存
然后 ping qige.io (或者本子网外的主机都可以),同时用 Wireshark 抓这些包(可 arp 过滤)。查看这次 ARP 请求的是什么,注意观察该请求是谁在回应。
向不在同一子网的主机发送ARP请求,目的MAC是网关,回应的源MAC也是网关。
✎ 问题
通过以上的实验,你应该会发现,
ARP 请求都是使用广播方式发送的
如果访问的是本子网的 IP,那么 ARP 解析将直接得到该 IP 对应的 MAC;如果访问的非本子网的 IP, 那么 ARP 解析将得到网关的 MAC。
请问为什么?
因为ARP代理,访问非子网IP时是通过路由器访问的,路由器再把发出去,目标IP收到请求后,再通过路由器端口IP返回回去,那么ARP解析将会得到网关的MAC。
网络层
实作一 熟悉 IP 包结构
使用 Wireshark 任意进行抓包(可用 ip 过滤),熟悉 IP 包的结构,如:版本、头部长度、总长度、TTL、协议类型等字段。
版本(version):IP所使用的版本
首部长度(Header Length):IP头的长度
服务类型(Type of Service):优先级标志位和服务类型标志位,被路由器用来进行流量的优先排序
总长度(Total Length):IP头与数据包中数据的长度
标识符(Identification):一个唯一的标识数字,用来识别一个数据包或者被分片数据包的次序
标志(FLags):用来识别一个数据包是否是一组分片数据包的一部分
片偏移(Fragment Offset):一个数据包是一个分片,这个域中的值就会被用来将数据包以正确的顺序重新组装
生存时间(Time to Live):用来定义数据包的生存周期,以经过路由器的跳数/秒数进行描述
协议(Protocol):用来识别在数据包序列中上层协议数据包的类型
首部校验和(Header Checksum):一个错误检测机制,用来确认IP头的内容没有被损坏或者篡改
源地址(Source IP Address): 发出数据包的主机的IP地址
目的地址(Destination IP Address):数据包目的地的IP地址
✎ 问题
为提高效率,我们应该让 IP 的头部尽可能的精简。但在如此珍贵的 IP 头部你会发现既有头部长度字段,也有总长度字段。请问为什么?
便于传输时的识别IP总长度,当长度超过1500B时就会被返回链路层进行分段,节省时间
实作二 IP 包的分段与重组
根据规定,一个 IP 包最大可以有 64K 字节。但由于 Ethernet 帧的限制,当 IP 包的数据超过 1500 字节时就会被发送方的数据链路层分段,然后在接收方的网络层重组。
缺省的,ping 命令只会向对方发送 32 个字节的数据。我们可以使用 ping 202.202.240.16 -l 2000 命令指定要发送的数据长度。此时使用 Wireshark 抓包(用 ip.addr == 202.202.240.16 进行过滤),了解 IP 包如何进行分段,如:分段标志、偏移量以及每个包的大小等
ping 202.202.240.16 -l 2000,可以看到第一个IP包总长度为1500,偏移量(Fragment
Offset)为0,分段标志(Flags)为0x20表示还有更多分段;第二个IP包总长度为548,偏移量为1480,分段标志为0x00表示后面没有分段了。
分片偏移的意义为:较长的分组在分片后,某片在原分组中的相对位置。也就是说,相对用户数据字段的起点,该片从何处开始。片偏移以8个字节为偏移单位。这就是说,每个分片的长度一定是8字节(64位)的整数倍
✎ 问题
分段与重组是一个耗费资源的操作,特别是当分段由传送路径上的节点即路由器来完成的时候,所以 IPv6 已经不允许分段了。那么 IPv6 中,如果路由器遇到了一个大数据包该怎么办?
直接丢弃该数据包,在 IPv6中分段只能在源与目的地上执行,不能在路由器上进行。因此当数据包过大时,路由器就会直接丢弃该数据包,并向发送端发回一个"分组太大"的ICMP差错报文,之后发送端就会使用较小长度的IP数据报重发数据。。
实作三 考察 TTL 事件
在 IP 包头中有一个 TTL 字段用来限定该包可以在 Internet上传输多少跳(hops),一般该值设置为 64、128等。
在验证性实验部分我们使用了 tracert 命令进行路由追踪。其原理是主动设置 IP 包的 TTL 值,从 1 开始逐渐增加,直至到达最终目的主机。
请使用 tracert www.baidu.com 命令进行追踪,此时使用 Wireshark 抓包(用 icmp 过滤),分析每个发送包的 TTL 是如何进行改变的,从而理解路由追踪原理。
tracert www.baidu.com
TTL字段指定IP包被路由器丢弃之前允许通过的最大网段数量
通过分析每个包的TTL值可知:
Tracert 先发送 TTL 为 1的回应数据包,并随后的每次发送过程将 TTL 递增 1,直到目标响应或 TTL 达到最大值,从而确定路由
✎ 问题
在 IPv4 中,TTL 虽然定义为生命期即 Time To Live,但现实中我们都以跳数/节点数进行设置。如果你收到一个包,其 TTL 的值为 50,那么可以推断这个包从源点到你之间有多少跳?
经过14跳,一般TTL的设置为与其最靠近的2的n次幂,每经过一跳TTL减1。
传输层
实作一 熟悉 TCP 和 UDP 段结构
用 Wireshark 任意抓包(可用 tcp 过滤),熟悉 TCP 段的结构,如:源端口、目的端口、序列号、确认号、各种标志位等字段。
源端口(Source Port):16位的源端口其中包含初始化通信的端口。源端口和源IP地址的作用是标示报问的返回地址。
目的端口(Destination Port):16位的目的端口域定义传输的目的。这个端口指明报文接收计算机上的应用程序地址接口。
序列号(Sequence number):表示本报文段所发送数据的第一个字节的编号。在 TCP 连接中所传送的字节流的每一个字节都会按顺序编号。由于序列号由 32位表示,所以每 2^32 个字节,就会出现序列号回绕,再次从 0 开始。
确认号(Acknowledgment number):表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。
报头长度(Header Length):表示报文段到底有多长。
标识位 (Flags):包括紧急标志、有意义的应答标志、推、重置连接标志、同步序列号标志、完成发送数据标志。按照顺序排列是:URG、ACK、PSH、RST、SYN、FIN。
窗口大小(Window size value):表示现在运行对方发送的数据量。也就是告诉对方,从本报文段的确认号开始允许对方发送的数据量。
校验和(Checksum):提供额外的可靠性。
用 Wireshark 任意抓包(可用 udp 过滤),熟悉 UDP 段的结构,如:源端口、目的端口、长度等。
源端口(Source Port):源端口号。在需要对方回信时选用。不需要时可用全0。
目的端口(Destination Port):目的端口号。这在终点交付报文时必须要使用到。
长度(Length): UDP用户数据报的长度,其最小值是8(仅有首部)。
校验和(Checksum):检测UDP用户数据报在传输中是否有错,有错就丢弃。
✎ 问题
由上大家可以看到 UDP 的头部比 TCP 简单得多,但两者都有源和目的端口号。请问源和目的端口号用来干什么?
源端口就是指本地端口,目的端口就是远程端口
源端口就是本机程序用来发送数据的端口,目的端口就是对方主机用哪个端口接收
端口号用来标识网络进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理;
IP地址+端口号能够标识网络上的某一台主机的某一个进程;
一个端口号只能被一个进程占用
实作二 分析 TCP 建立和释放连接
打开浏览器访问 qige.io 网站,用 Wireshark 抓包(可用 tcp 过滤后再使用加上 Follow TCP Stream),不要立即停止 Wireshark 捕获,待页面显示完毕后再多等一段时间使得能够捕获释放连接的包。
请在你捕获的包中找到三次握手建立连接的包,并说明为何它们是用于建立连接的,有什么特征。
请在你捕获的包中找到四次挥手释放连接的包,并说明为何它们是用于释放连接的,有什么特征。
三次握手建立连接:只有第一次握手时ACK标志位才为0。三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。
四次挥手释放连接:FIN标志位为1时表示要释放连接。因为TCP是全双工的,因此,每个方向都要单独关闭当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着一方向不会再收到数据了但是这个TCP连接上仍然能够发送数据,直到这一方也发送了FIN.首先进行关闭的一方执行主动关闭,另一方执行被动关闭.第一个关闭的最后等待2MSL
✎ 问题一
去掉 Follow TCP Stream,即不跟踪一个 TCP 流,你可能会看到访问 qige.io 时我们建立的连接有多个。请思考为什么会有多个连接?作用是什么?
通过建立多个连接,可以实现实现多个用户进行访问,可以达到节省通道使用的作用,提高利用率,因为是属于短连接,一旦数据发送完成后,就会断开连接。但是即使断开连接,缓存依旧存在。
✎ 问题二
我们上面提到了释放连接需要四次挥手,有时你可能会抓到只有三次挥手。原因是什么?
中间的两个被合成为一个。例如,如果客户端发送一个断开与服务器连接的请求,那么它就是第一个挥手。服务器回复客户端,第二次同意断开连接。然后服务器发送断开连接请求给客户端进行第三次挥手,客户端对服务器进行第四次应答。第三种是将服务器发送到客户端断开连接,并回复同意断开连接。另外两波保持不变。
应用层
应用层的协议非常的多,我们只对 DNS 和 HTTP 进行相关的分析。
实作一 了解 DNS 解析
先使用 ipconfig /flushdns 命令清除缓存,再使用 nslookup qige.io 命令进行解析,同时用 Wireshark 任意抓包(可用 dns 过滤)。
你应该可以看到当前计算机使用 UDP,向默认的 DNS 服务器的 53 号端口发出了查询请求,而 DNS 服务器的 53 号端口返回了结果。
可了解一下 DNS 查询和应答的相关字段的含义
事务 ID(Transaction ID):DNS 报文的 ID 标识。对于请求报文和其对应的应答报文,该字段的值是相同的。通过它可以区分 DNS 应答报文是对哪个请求进行响应的。
标志(Flags):DNS 报文中的标志字段。
问题计数(Questions):DNS 查询请求的数目。
回答资源记录数(Answer RRs):DNS 响应的数目。
权威名称服务器计数(Authority RRs):权威名称服务器的数目。
附加资源记录数(Additional RRs):额外的记录数目(权威名称服务器对应 IP 地址的数目)。
✎ 问题
你可能会发现对同一个站点,我们发出的 DNS 解析请求不止一个,思考一下是什么原因?
为了使服务器的负载得到平衡(因为每天访问站点的次数非常多)网站就设有好几个计算机,每一个计算机都运行同样的服务器软件。这些计算机的IP地址不一样,但它们的域名却是相同的。这样,第一个访问该网址的就得到第一个计算机的IP地址,而第二个访问者就得到第二个计算机的IP地址等等。这样可使每一个计算机的负荷不会太大。
实作二 了解 HTTP 的请求和应答
打开浏览器访问 qige.io 网站,用 Wireshark 抓包(可用http 过滤再加上 Follow TCP Stream),不要立即停止 Wireshark 捕获,待页面显示完毕后再多等一段时间以将释放连接的包捕获。
请在你捕获的包中找到 HTTP 请求包,查看请求使用的什么命令,如:GET, POST。并仔细了解请求的头部有哪些字段及其意义。
GET:
POST:
Accept:告诉WEB服务器自己接受什么介质类型,/ 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type。
Accept-Encoding: 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate)
Accept-Language::浏览器申明自己接收的语言语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等。
Cache-Control:请求:no-cache(不要缓存的实体,要求现在从WEB服务器去取)
Connection:请求:close(告诉WEB服务器或者代理服务器,在完成本次请求的响应 后,断开连接,不要等待本次连接的后续请求了)。
Content-Length: WEB 服务器告诉浏览器自己响应的对象的长度。
Host:客户端指定自己想访问的WEB服务器的域名/IP
地址和端口号。 User-Agent:浏览器信息。
请在你捕获的包中找到 HTTP 应答包,查看应答的代码是什么,如:200, 304, 404 等。并仔细了解应答的头部有哪些字段及其意义。
该应答代码是302
Date:当前的GMT时间。
Content- Type:表示后面的文档属于什么MIME类型。
Content-Length: WEB 服务器告诉浏览器自己响应的对象的长度。
Connection:请求:close(告诉WEB服务器或者代理服务器,在完成本次请求的响应 后,断开连接,不要等待本次连接的后续请求了)。
Location:WEB 服务器告诉浏览器,试图访问的对象已经被移到别的位置了, 到该头部指定的位置去取。
Via: 列出从客户端到 OCS 或者相反方向的响应经过了哪些代理服务器,他们用 什么协议(和版本)发送的请求。
✍ 建议:
HTTP 请求和应答的头部字段值得大家认真的学习,因为基于 Web 的编程中我们将会大量使用。如:将用户认证的令牌信息放到头部,或者把 cookie 放到头部等。
✎ 问题
刷新一次 qige.io 网站的页面同时进行抓包,你会发现不少的 304 代码的应答,这是所请求的对象没有更改的意思,让浏览器使用本地缓存的内容即可。那么服务器为什么会回答 304 应答而不是常见的 200 应答?
当用户第一次请求index.html时,服务器会添加一个名为Last-Modified响应头,这个头说明了index.html的最后修改时间,浏览器会把index.html内容,以及最后响应时间缓存下来。当用户第二次请求index.html时,在请求中包含一个名为If-Modified-Since请求头,它的值就是第一次请求时服务器通过Last-Modified响应头发送给浏览器的值,即index.html最后的修改时间,If-Modified-Since请求头就是在告诉服务器,我这里浏览器缓存的index.html最后修改时间是这个,您看看现在的index.html最后修改时间是不是这个,如果还是,那么您就不用再响应这个index.html内容了,我会把缓存的内容直接显示出来。而服务器端会获取If-Modified-Since值,与index.html的当前最后修改时间比对,如果相同,服务器会发响应码304,表示index.html与浏览器上次缓存的相同,无需再次发送(节省传输成本),浏览器可以显示自己的缓存页面,如果比对不同,那么说明index.html已经做了修改,服务器会响应200。