一站式学习Wireshark(一):Wireshark基本用法
按照国际惯例,从最基本的说起。
抓取报文:
下载和安装好Wireshark之后,启动Wireshark并且在接口列表中选择接口名,然后开始在此接口上抓包。例如,如果想要在无线网络上抓取流量,点击无线接口。点击Capture Options可以配置高级属性,但现在无此必要。
点击接口名称之后,就可以看到实时接收的报文。Wireshark会捕捉系统发送和接收的每一个报文。如果抓取的接口是无线并且选项选取的是混合模式,那么也会看到网络上其他报文。
上端面板每一行对应一个网络报文,默认显示报文接收时间(相对开始抓取的时间点),源和目标IP地址,使用协议和报文相关信息。点击某一行可以在下 面两个窗口看到更多信息。“+”图标显示报文里面每一层的详细信息。底端窗口同时以十六进制和ASCII码的方式列出报文内容。
需要停止抓取报文的时候,点击左上角的停止按键。
色彩标识:
进行到这里已经看到报文以绿色,蓝色,黑色显示出来。Wireshark通过颜色让各种流量的报文一目了然。比如默认绿色是TCP报文,深蓝色是DNS,浅蓝是UDP,黑色标识出有问题的TCP报文——比如乱序报文。
报文样本:
比如说你在家安装了Wireshark,但家用LAN环境下没有感兴趣的报文可供观察,那么可以去Wireshark wiki下载报文样本文件。
打开一个抓取文件相当简单,在主界面上点击Open并浏览文件即可。也可以在Wireshark里保存自己的抓包文件并稍后打开。
过滤报文:
如果正在尝试分析问题,比如打电话的时候某一程序发送的报文,可以关闭所有其他使用网络的应用来减少流量。但还是可能有大批报文需要筛选,这时要用到Wireshark过滤器。
最基本的方式就是在窗口顶端过滤栏输入并点击Apply(或按下回车)。例如,输入“dns”就会只看到DNS报文。输入的时候,Wireshark会帮助自动完成过滤条件。
也可以点击Analyze菜单并选择Display Filters来创建新的过滤条件。
另一件很有趣的事情是你可以右键报文并选择Follow TCP Stream。
你会看到在服务器和目标端之间的全部会话。
关闭窗口之后,你会发现过滤条件自动被引用了——Wireshark显示构成会话的报文。
检查报文:
选中一个报文之后,就可以深入挖掘它的内容了。
也可以在这里创建过滤条件——只需右键细节并使用Apply as Filter子菜单,就可以根据此细节创建过滤条件。
Wireshark是一个非常之强大的工具,第一节只介绍它的最基本用法。网络专家用它来debug网络协议实现细节,检查安全问题,网络协议内部构件等等。
一站式学习Wireshark(二):应用Wireshark观察基本网络协议
TCP:
TCP/IP通过三次握手建立一个连接。这一过程中的三种报文是:SYN,SYN/ACK,ACK。
第一步是找到PC发送到网络服务器的第一个SYN报文,这标识了TCP三次握手的开始。
如果你找不到第一个SYN报文,选择Edit -> Find Packet菜单选项。选择Display Filter,输入过滤条件:tcp.flags,这时会看到一个flag列表用于选择。选择合适的flag,tcp.flags.syn并且加上==1。点击Find,之后trace中的第一个SYN报文就会高亮出来了。
注意:Find Packet也可以用于搜索十六进制字符,比如恶意软件信号,或搜索字符串,比如抓包文件中的协议命令。
一个快速过滤TCP报文流的方式是在Packet List Panel中右键报文,并且选择Follow TCP Stream。这就创建了一个只显示TCP会话报文的自动过滤条件。
这一步骤会弹出一个会话显示窗口,默认情况下包含TCP会话的ASCII代码,客户端报文用红色表示服务器报文则为蓝色。
窗口类似下图所示,对于读取协议有效载荷非常有帮助,比如HTTP,SMTP,FTP。
更改为十六进制Dump模式查看载荷的十六进制代码,如下图所示:
关闭弹出窗口,Wireshark就只显示所选TCP报文流。现在可以轻松分辨出3次握手信号。
注意:这里Wireshark自动为此TCP会话创建了一个显示过滤。本例中:(ip.addr eq 192.168.1.2 and ip.addr eq 209.85.227.19) and (tcp.port eq 80 and tcp.port eq 52336)
SYN报文:
图中显示的5号报文是从客户端发送至服务器端的SYN报文,此报文用于与服务器建立同步,确保客户端和服务器端的通信按次序传输。SYN报文的头部有一个32 bit序列号。底端对话框显示了报文一些有用信息如报文类型,序列号。
SYN/ACK报文:
7号报文是服务器的响应。一旦服务器接收到客户端的SYN报文,就读取报文的序列号并且使用此编号作为响应,也就是说它告知客户机,服务器接收到了SYN报文,通过对原SYN报文序列号加一并且作为响应编号来实现,之后客户端就知道服务器能够接收通信。
ACK报文:
8号报文是客户端对服务器发送的确认报文,告诉服务器客户端接收到了SYN/ACK报文,并且与前一步一样客户端也将序列号加一,此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
ARP & ICMP:
开启Wireshark抓包。打开Windows控制台窗口,使用ping命令行工具查看与相邻机器的连接状况。
停止抓包之后,Wireshark如下图所示。
ARP和ICMP报文相对较难辨认,创建只显示ARP或ICMP的过滤条件。
ARP报文:
地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。其功能是:主机将ARP请求广播到网络上的所有主机,并接收返回消息,确定目标IP地址的物理地址,同时将IP地址和硬件地址存入本机ARP缓存中,下次请求时直接查询ARP缓存。
最初从PC发出的ARP请求确定IP地址192.168.1.1的MAC地址,并从相邻系统收到ARP回复。ARP请求之后,会看到ICMP报文。
ICMP报文:
网络控制消息协定(Internet Control Message Protocol,ICMP)用于TCP/IP网络中发送控制消息,提供可能发生在通信环境中的各种问题反馈,通过这些信息,令管理者可以对所发生的问题作出诊断,然后采取适当的措施解决。
PC发送echo请求,收到echo回复如上图所示。ping报文被mark成Type 8,回复报文mark成Type 0。
如果多次ping同一系统,在PC上删除ARP cache,使用如下ARP命令之后,会产生一个新的ARP请求。
C:\> ping 192.168.1.1
… ping output …
C:\> arp –d *
HTTP:
HTTP协议是目前使用最广泛的一种基础协议,这得益于目前很多应用都基于WEB方式,实现容易,软件开发部署也简单,无需额外的客户端,使用浏览器即可使用。这一过程开始于请求服务器传送网络文件。
从上图可见报文中包括一个GET命令,当HTTP发送初始GET命令之后,TCP继续数据传输过程,接下来的链接过程中HTTP会从服务器请求数据 并使用TCP将数据传回客户端。传送数据之前,服务器通过发送HTTP OK消息告知客户端请求有效。如果服务器没有将目标发送给客户端的许可,将会返回403 Forbidden。如果服务器找不到客户端所请求的目标,会返回404。
如果没有更多数据,连接可被终止,类似于TCP三次握手信号的SYN和ACK报文,这里发送的是FIN和ACK报文。当服务器结束传送数据,就发送 FIN/ACK给客户端,此报文表示结束连接。接下来客户端返回ACK报文并且对FIN/ACK中的序列号加1。这就从服务器端终止了通信。要结束这一过 程客户端必须重新对服务器端发起这一过程。必须在客户端和服务器端都发起并确认FIN/ACK过程。
一站式学习Wireshark(三):应用Wireshark IO图形工具分析数据流
基本IO Graphs:
IO graphs是一个非常好用的工具。基本的Wireshark IO graph会显示抓包文件中的整体流量情况,通常是以每秒为单位(报文数或字节数)。默认X轴时间间隔是1秒,Y轴是每一时间间隔的报文数。如果想要查看 每秒bit数或byte数,点击“Unit”,在“Y Axis”下拉列表中选择想要查看的内容。这是一种基本的应用,对于查看流量中的波峰/波谷很有帮助。要进一步查看,点击图形中的任意点就会看到报文的细 节。
为了讲解方便,点击示例报文包,或用自己的wireshark点击Statistics – IO Graphs。这个抓包是HTTP下载遇到报文丢失的情况。
注意:过滤条件为空,此图形显示所有流量。
这个默认条件下的显示在大多数troubleshooting中并不是非常有用。将Y轴改为bits/tick这样就可以看到每秒的流量。从这张图 可以看到峰值速率是300kbps左右。如果你看到有些地方流量下降为零,那可能是一个出问题的点。这个问题在图上很好发现,但在看报文列表时可能不那么 明显。
过滤:
每一个图形都可以应用一个过滤条件。这里创建两个不同的graph,一个HTTP一个ICMP。可以看到过滤条件中Graph 1使用“http”Graph 2使用“icmp”。图中可以看到红色ICMP流量中有些间隙,进一步分析。
创建两个图形,一个显示ICMP Echo(Type=8)一个显示ICMP Reply(Type=0)。正常情况下对于每一个echo请求会有一个连续的reply。这里的情况是:
可以看到红色脉冲线(icmp type==0 – ICMP Reply)中间有间隙,而整张图中ICMP请求保持连续。这意味着有些reply没有接收到。这是由于报文丢失导致的reply drop。CLI中看到的ping信息如下:
常用排错过滤条件:
对于排查网络延时/应用问题有一些过滤条件是非常有用的:
tcp.analysis.lost_segment:表明已经在抓包中看到不连续的序列号。报文丢失会造成重复的ACK,这会导致重传。
tcp.analysis.duplicate_ack:显示被确认过不止一次的报文。大凉的重复ACK是TCP端点之间高延时的迹象。
tcp.analysis.retransmission:显示抓包中的所有重传。如果重传次数不多的话还是正常的,过多重传可能有问题。这通常意味着应用性能缓慢和/或用户报文丢失。
tcp.analysis.window_update:将传输过程中的TCP window大小图形化。如果看到窗口大小下降为零,这意味着发送方已经退出了,并等待接收方确认所有已传送数据。这可能表明接收端已经不堪重负了。
tcp.analysis.bytes_in_flight:某一时间点网络上未确认字节数。未确认字节数不能超过你的TCP窗口大小(定义于最初3此TCP握手),为了最大化吞吐量你想要获得尽可能接近TCP窗口大小。如果看到连续低于TCP窗口大小,可能意味着报文丢失或路径上其他影响吞吐量的问题。
tcp.analysis.ack_rtt:衡量抓取的TCP报文与相应的ACK。如果这一时间间隔比较长那可能表示某种类型的网络延时(报文丢失,拥塞,等等)。
在抓包中应用以上一些过滤条件:
注意:Graph 1是HTTP总体流量,显示形式为packets/tick,时间间隔1秒。Graph 2是TCP丢失报文片段。Graph 3是TCP 重复ACK。Graph 4是TCP重传。
从这张图可以看到:相比于整体HTTP流量,有很多数量的重传以及重复ACK。从这张图中,可以看到这些事件发生的时间点,以及在整体流量中所占的比例。
函数:
IO Graphs有六个可用函数:SUM, MIN, AVG, MAX, COUNT, LOAD。
MIN( ), AVG( ), MAX( )
首先看一下帧之间的最小,平均和最大时间,这对于查看帧/报文之间的延时非常有用。我们可以将这些函数结合“frame.time_delta”过滤条件看清楚帧延时,并使得往返延时更为明显。如果抓包文件中包含不同主机之间的多个会话,而只想知道其中一个pair,可将“frame.time_delta”结合源和目标主机条件如“ip.addr==x.x.x.x &&ip.addr==y.y.y.y”。如下图所示:
我们做了以下步骤:
- 将Y轴设置为“Advanced”,让Caculation域可见。不做这一步就看不到计算选项。
- X轴时间间隔1秒,所以每个柱状图代表1秒间隔的计算结果。
- 过滤出两个特定IP地址的HTTP会话,使用条件:“(ip.addr==192.168.1.4&& ip.addr==128.173.87.169) && http”。
- 使用3个不同的graph,分别计算Min(), Avg(), Max()。
- 对每一个计算结果应用条件“frame.time_delta”,将style设置成“FBar”,显示效果最佳。
从上图可见,在第106秒时数据流的MAX frame.delta_time达到0.7秒,这是一个严重延时并且导致了报文丢失。如果想要深入研究,只需要点击图中这一点,就会跳转至相应帧。对应 于本例抓包文件中第1003个报文。如果你看见帧之间平均延时相对较低但突然某一点延时很长,可点击这一帧,看看这一时间点究竟发生了什么。
Count( )
此函数计算时间间隔内事件发生的次数,在查看TCP分析标识符时很有用,例如重传。例图如下:
Sum( )
该函数统计事件的累加值。有两种常见的用例是看在捕获TCP数据量,以及检查TCP序列号。让我们看看第一个TCP长度的例子。创建两个图,一个使 用客户端IP 192.168.1.4为源,另一个使用客户端IP作为一个目的地址。每个图我们将sum()功能结合tcp.len过滤条件。拆分成两个不同的图我们就 可以看到在一个单一的方向移动的数据量。
从图表中我们可以看到,发送到客户端的数据量(IP.DST = = 192.168.1.4过滤条件)比来自客户端的数据量要高。在图中红色表示。黑条显示从客户端到服务器的数据,相对数据量很小。这是有道理的,因为客户 只是请求文件和收到之后发送确认数据,而服务器发送大文件。很重要的一点是,如果你交换了图的顺序,把客户端的IP作为图1的目标地址,并且客户端IP作 为图2的源地址,采用了FBAR的时候可能看不到正确的数据显示。因为图编号越低表示在前台显示,可能会覆盖较高图号。
现在让我们看一下同一个数据包丢失和延迟的TCP序列号。
可以在图中看到若干峰值和下降,表示TCP传输有问题。与正常TCP报文比较:
这张图可以看到TCP序列号相当稳定地增加,表示传输平稳,没有过多重传或丢包。
一站式学习Wireshark(四):网络性能排查之TCP重传与重复ACK
作为网络管理员,很多时间必然会耗费在修复慢速服务器和其他终端。但用户感到网络运行缓慢并不意味着就是网络问题。
解决网络性能问题,首先从TCP错误恢复功能(TCP重传与重复ACK)和流控功能说起。之后阐述如何发现网络慢速之源。最后,对网络各组成部分上的数据流进行概况分析。这几张内容将会帮助读者识别,诊断,以及排查慢速网络。
更多信息
接下来的内容,较多是黑白图片了。虽然看起来有点不爽,但还是很值得一看。
TCP错误恢复功能:
TCP的错误恢复功能是定位,诊断及修复网络延时的最佳工具。延时可以在单程也可以往返方向测量。高延时是网络管理员的头号大敌。本节我们讨论TCP高延时是如何导致序列号和确认号乱序的。
TCP重传:
主机报文重传是TCP最基本的错误恢复功能,它的目的是防止报文丢失。
报文丢失的可能因素有很多种,包括应用故障,路由设备过载,或暂时的服务宕机。报文级别速度是很高的,而通常报文丢失是暂时的,因此TCP能够发现和恢复报文丢失显得尤为重要。
决定报文是否有必要重传的主要机制是重传计时器(retransmission
timer),它的主要功能是维护重传超时(RTO)值。当报文使用TCP传输时,重传计时器启动,收到ACK时计时器停止。报文发送至接收到ACK的时
间称为往返时间(RTT)。对若干次时间取平均值,该值用于确定最终RTO值。在最终RTO值确定之前,确定每一次报文传输是否有丢包发生使用重传计时
器,下图说明了TCP重传过程。
当报文发送之后,但接收方尚未发送TCP
ACK报文,发送方假设源报文丢失并将其重传。重传之后,RTO值加倍;如果在2倍RTO值到达之前还是没有收到ACK报文,就再次重传。如果仍然没有收
到ACK,那么RTO值再次加倍。如此持续下去,每次重传RTO都翻倍,直到收到ACK报文或发送方达到配置的最大重传次数。
最大重传次数取决于发送操作系统的配置值。默认情况下,Windows主机默认重传5次。大多数Linux系统默认最大15次。两种操作系统都可配置。
示例如下图:
TCP重传过程发送的第一个报文如下图所示(图片不很清楚,已经尽力了):
这是一个TCP PSH/ACK报文①,包含648字节数据②,从10.3.30.1发送至10.3.71.7。这是一个典型的数据报文。
在通常情况下,第一个报文发送之后很快会收到TCP ACK报文。然而,在这个case里,第二个是重传报文。可以在Packet
list面板里看到。Info栏清楚的标明“TCP Retransmission”,报文以黑色背景红色字体标出。下图是Packet
List面板中的重传示例(仍然不清楚,但可参见上图):
也可以在Packet Details和Packet Bytes面板中查看来确定是否是重传报文,如下图所示:
注意此报文与源报文相同(除了IP标识和checksum字段)。要验证这一点,比较两个报文的Packet Bytes①。
在Packet Details面板,注意到重传报文在SEQ/ACK
Analysis下面有些额外的信息②。这些信息是由Wireshark提供的而并非报文本身。SEQ/ACK
Analysis告诉我们这确实是一个重传报文,RTO值是0.206秒,此时的RTO是基于报文1的时间增量。
检查剩下的报文会得到类似的结果,不同之处只有IP标识和checksum,以及RTO值。要使报文之间的时间间隔形象化,在Packet List面板中查看Time栏,如下图所示。这里可以看到RTO值的翻倍增长关系。
TCP重复ACK以及快速重传:
重复ACK是指在接收方收到乱序报文时,所发出的一类TCP报文。TCP使用报文头的序列号和确认号以有效保证数据按照发送的顺序接收和重组。
当TCP连接建立以后,握手过程中交换的一个最重要的信息是初始序列号(ISN)。一旦连接双方设定了ISN之后,接下来发送的报文所包含的序列号增加一个数据载荷值。
假设有个主机ISN是5000,发送500字节报文至接收方。一旦报文接收之后,接收端回复一个ACK号为5500的TCP ACK报文,基于以下公式:
Sequence Number In + Bytes of Data Received = Acknowledgment Number Out
按照上述计算结果,返回发送端的确认编号实际上是接收端希望收到的序列号。示例如下图:
数据接收方通过序列号来检查报文丢失。接收方通过追踪接收到的序列号,能够确认序列号是否乱序。当接收方收到一个不正常的序列号,它会假设传输过程中有报
文丢失。为了正确重传数据,接收方必须拥有丢失报文,所以它发送包含有丢失报文正确序列号的ACK报文,以便发送方重传此报文。
当重传主机从发送端接收到3个重复ACK时,它会假设此报文确实在传送中丢失,并且立即发送一个快速重传。一旦触发了快速重传,所有正在传输的其他报文都被放入队列中,直到快速重传报文发送为止。过程如下图所示:
承接上文的彩图:
本例中第一个报文如下图:
这是一个TCP ACK报文,从数据接收端(172.31.136.85)发给发送端(195.81.202.68)①,确认前一个报文所发送的数据。
此报文中的确认编号是1310973186②,应当是下一个接收报文的序列号,如下图所示:
不幸的是接收端的序列号是1310984130①,并不是所期望的值。这意味着报文在传送中丢失。接收端注意到报文乱序,并且在第三个报文中发送重复ACK,如下图所示:
可以通过以下两种方式之一来确认这是一个重复ACK:
在Packet Detaisl面板中的Info栏。报文呈现黑色背景红色字体。
SEQ/ACK Analysis下的Packet Deatails面板。扩展这一栏会发现报文显示为duplicate ACK。接下来几个报文重复此过程。如下图所示:
此文件中的第四个报文是发送端所发出具有错误序列号①的另一个数据块。因此,接收端发送第二个重复ACK②。接收端又收到一个乱序报文③。从而触发了第三以及最后一个重复ACK④.
一旦发送方接收到接收方所发来的第三个重复ACK,它就会暂停所有传输报文并且重传丢失报文,下图显示了快速重传过程:
重传报文同样可以通过Packet List面板的Info栏观察到。报文呈现黑色背景红色字体。这个报文的SEQ/ACK
Analysis截面告诉我们这可能是一个快速重传帧。(标识报文为快速重传的信息不是报文本身所包含的内容,而是Wireshark的功能)。最后一个
报文是接收到快速重传的ACK。
一站式学习Wireshark(五):TCP窗口与拥塞处理
TCP通过滑动窗口机制检测丢包,并在丢包发生时调整数据传输速率。滑动窗口机制利用数据接收端的接收窗口来控制数据流。
接收窗口值由数据接收端指定,以字节数形式存储于TCP报文头,并告知传输设备有多少数据将会存储在TCP缓冲区。缓冲区就是数据暂时放置的地方, 直至传递至应用层协议等待处理。因此,发送端每次只能发送Window Size字段指定的数据量。为了使发送端继续传送数据,接收端必须发送确认信息:之前的数据接收到了。同时必须对占用缓冲区的数据进行处理以释放缓存空 间。下图显示了接收窗口是如何工作的:
上图中,客户端向服务器发送数据,服务器接收窗口是5000字节。客户端发送了2500字节,服务器缓冲区还剩2500字节,之后又发送了2000 字节,从而缓冲区只剩500字节。服务器发送确认信息。对缓存中数据进行处理并清空缓存。此过程重复进行,客户端又发送3000字节和1000字节,服务 器缓存减少至1000字节,客户端再次确认数据并处理缓存中内容。
更多信息
调整窗口大小:
当TCP堆 栈接收到数据的时候,生成一个确认信息并以回复的方式发送,但是放置在接收端缓存中的数据并不总是立即被处理。当服务器忙于处理从多个客户端接收的报文, 服务器很有可能因为清理缓存而变得缓慢,无法腾出空间接收新的数据,如果没有流控,则可能会造成丢包和数据损坏。好在,接收窗口所设定的速率无法使服务器 正常处理数据时,能够调整接收窗口大小。通过减小返回给发送端的ACK报文的TCP头窗口大小值来实现。如下图所示:
上图中,服务器初始窗口大小为5000字节。客户端发送2000字节,之后又发送了2000字节,缓冲区中只有1000字节可用。服务器意识到缓冲 区正在快速填满,它知道如果数据继续以此速率传输,很快会有报文丢失。为了防止报文丢失,服务器发送确认信息给客户端,更新窗口大小为1000字节。结 果,客户端减少数据发送,服务器以可以接受的速率处理缓存内容,即保持数据流以稳定的速率传输。
调整窗口大小在两个方向都是可行的。当服务器能够更加快速的处理报文时,它会发送一个较大窗口的ACK报文。
零窗口暂停数据流:
某些情况下,服务器无法再处理从客户端发送的数据。可能是由于内存不足,处理能力不够,或其他原因。这可能会造成数据被丢弃以及传输暂停,但接收窗口能够帮助减小负面影响。
当上述情况发生时,服务器会发送窗口为0的报文。当客户端接收到此报文时,它会暂停所有数据传输,但会保持与服务器的连接以传输探测(keep- alive)报文。探测报文在客户端以稳定间隙发送,以查看服务器接收窗口状态。一旦服务器能够再次处理数据,将会返回非零值窗口大小,传输会恢复。下图 示例了零窗口通知过程。
服务器初始接收数据窗口为5000字节大小。从客户端接收4000字节数据之后,服务器负载变得非常繁重,无法继续处理客户端任何数据。服务器于是 发送窗口大小值为0的报文。客户端暂停数据传输并发送一个探测报文。探测报文之后,服务器回复以告知客户端现在可以接收数据的报文,以及窗口大小为 1000字节。客户端恢复传送数据。
TCP滑动窗口实战:
本例中,开始从192.168.0.20发送至192.168.0.30。我们关心的是窗口大小字段,可以从Packet List面板的Info栏以及Packet Details的TCP报文头看到。前三个报文后,可看到该值立刻减小,如下图所示:
窗口大小值从第一个报文的8760字节变成第二个报文的5840字节到第三个报文的2920字节①。窗口大小值的减小是主机延时的典型标志。在时间 栏注意到这一过程发生的非常迅速②。当窗口大小迅速减小的时候,通常就有可能下降为零。这就是第四个报文所发生的,如下图所示:
第四个报文从192.168.0.20发送至192.168.0.30,目的是告诉192.168.0.30它不再接收任何数据。0值见于TCP报 文头①,Wireshark的Packet List面板Info栏,以及TCP报文头的SEQ/ACK Analysis字段②也告诉我们这是一个0窗口报文。
一旦发送了零窗口报文,192.168.0.30的设备不会再发送任何数据,直到收到从192.168.0.20的窗口更新,告知窗口大小已经增加了。本例中导致零窗口的问题是暂时的,所以在下一个报文中发送了窗口更新信息,如下图所示。
本例中,窗口大小增加到一个非常健康的数值64,240字节①。Wireshark再次在SEQ/ACK Analysis告诉我们这是一个窗口更新。
一旦收到更新报文,192.168.0.30的主机就再次开始发送数据,在报文6和报文7中。这一过程发生很快。如果它持续时间再长一点,就可能会导致网络的潜在中断,引起数据传输减慢或失败。
下一个关于滑动窗口的例子,第一个报文是正常HTTP,从195.81.202.68至172.31.136.85。此报文之后立刻跟随一个从172.31.136.85发送的零窗口报文,如下图所示:
这与上一个例子中的零窗口报文十分类似,但结果显著不同,172.31.136.85主机不是发送一个窗口更新并回复通讯,而是一个探测报文,如下图所示:
此报文被Wireshark标注为探测报文①。时间栏告诉我们这一报文发生于最后一个接收到的报文3.4秒之后。这一过程持续若干次,一端发送零窗口报文另一端发送探测报文,如下图所示:
探测报文发送间隙为3.4,6.8,13.5秒。这一过程可能会持续相当长一段时间,取决于通讯设备的操作系统。该情况下,把时间栏的值加起来,通讯暂停了25秒。
TCP差错控制和流控排查总结:
重传报文
重 传的发生是由于客户端检测到服务器没有接收到它所发送的数据。因此,取决于你所分析的是通讯的哪一端,有可能是看不见重传的。如果从服务器端抓取数据,并 且它确实没有接收到客户端所发送的和重传报文,可能会一无所获因为无法看见重传报文。如果怀疑并不是服务器端导致的报文丢失,可以考虑在客户端尝试抓取报 文,以查看实际是否有重传发生。
重复ACK
可以将重复ACK看作重传的“所谓相反面”,因为它是在服务器检测到客户端发送报文丢失的时候产生的。大多数情况下,在通讯两端抓取流量时都可以看 到重复ACK。需记住当接收报文乱序时会触发重复ACK。例如,如果服务器之接收到发送的第一个和第三个报文,就会导致发送重复ACK引起客户端对第二个 报文的快速重传,因为你已经收到了第一个和第三个报文,因此不管导致第二个报文丢弃的原因是什么,都很有可能是暂时的,因此大多数情况下重复ACK都会成 功发送和接收。当然,这种情形并不一定永远会发生,因此当你怀疑在服务器端丢失报文而又看不到任何重复ACK,考虑从通讯的客户端抓取报文。
零窗口和探测报文
滑动窗口直接与服务器无法接收和处理报文有关,任何窗口大小的缩小以及零值都是服务器问题的直接结果。所以如果你在哪里看到这两者之一发生,就应该在那里深入研究。通常应当在网络通讯两端一直主机窗口更新报文。
一站式学习Wireshark(六):狙击网络高延时点
在某些情况下,丢包可能并不是造成延时的原因。你可能会发现尽管两台主机之间通讯速度很慢,但这种慢速并没有伴随着TCP重传或是重复ACK的征兆。在这种情况下,需要使用另一种方式来定位高延时点。
查找高延时点最有效的方法之一是检查最初的握手信号以及跟随其后的几个报文。例如,一个简单的客户端与网络服务器的连接,客户端尝试通过浏览器访问 网络服务器的站点。我们只关心这一通信序列的前六个报文,包括TCP握手过程,首次HTTP GET请求,对此GET请求的确认,以及从服务器发至客户端的第一个数据报文。
更多信息
正常通讯:
在讨论高延时状况之前,找一个正常的通讯作为参照。在第二节已经介绍过TCP握手过程以及HTTP通讯,这里不再赘述。在下面这张图里,我们关心的部分只有Time列:
这一通讯序列是非常快速的,整个过程耗时不到0.1秒。
接下来几个抓包文件包含同样的traffic模式,但是在报文时序上有所不同。
慢速通讯——线路延时:
让我们看看下面这个报文。注意到所有报文都是相同的,除了报文2和5的时间延时较长:
逐一分析这六个报文,立刻就会看到第一次延时。客户端(172.16.16.128)发送首次SYN报文以开始TCP握手,在服务器 (74.125.95.104)返回SYN/ACK之前,有0.87秒的延时。这是线路延时的第一个信号,这是由客户端和服务器之间的设备引起的。
我们判断这是线路延时的依据是所传送的报文类型特征。当服务器接收到一个SYN报文,只需花费很少的处理过程就可发送回复,因为这一工作负载并不包 含任何传输层之上的处理。即使服务器工作负载非常繁重,它通常也会快速地以SYN/ACK来回复SYN报文。这就排除了服务器是高延时的潜在原因。
客户端也被排除的原因在于,它除了接收SYN/ACK报文之外,没有进行任何处理。
这一抓包的前两个报文帮我们排除了客户端和服务器,并指出了潜在原因。
继续分析,我们发现结束三步握手信号的ACK报文快速出现,客户端发送的HTTP GET请求也是如此。产生这两个报文的所有处理在本地客户端接收到SYN/ACK之后进行,因此在客户端没有繁重的负载需要处理的情况下,这两个报文预计会很快传送。
到了报文5,我们看到另一个延时高得离谱的报文。出现在最初的HTTP GET请求发送过后,从服务器返回的ACK报文花费了1.15秒才收到。接收到HTTP GET请求之后,服务器在开始发送数据之前首先发送了一个TCP ACK,同样只需占用服务器很少的处理。这是另一个线路延时的信号。
不管何时你经历着线路延时,你几乎总是会看到:在最初的握手信号期间的SYN/ACK报文,以及整个通讯过程的ACK报文中,存在着高延时。即使这 一信息并没有告诉你网络上延时的确切原因,至少让你明白客户端和服务器都不是延时点所在,因此延时发生在两者之间的设备。这时,你应当开始检查受影响主机 之间的各种防火墙,路由器,以及代理,以定位罪魁祸首。
慢速通讯——客户端延时:
下一个延时场景的抓包如下图所示:
这一抓包开始时很正常,TCP握手非常迅速,没有任何延时的迹象。正常状态持续至第四个报文:握手信号结束之后接收到一个HTTP GET请求。这个报文距离前一个接收到的报文有1.34秒的延时。
要确认网络的延时点,需要检查第3和第4个报文之间发生了什么。报文3是客户端发送到服务器的TCP握手信号中的最后一个ACK,报文4是从客户端 发送至服务器的GET请求。这两个报文的共同之处在于都是由客户端发送,并且独立于服务器。由于所有这些操作都集中在客户端上,GET请求应当在发送了 ACK之后快速传送。
不幸的是对于终端用户,从ACK到GET的传送并没有快速发生。GET报文的创建与传输取决于应用层的处理,这一过程中的延时意味着客户端无法及时的执行这一功能。这表示客户端最终为通讯中的高延时负责。
慢速通讯——服务器延时:
最后一个延时场景的抓包如下图所示:
在这一抓包中,两个主机之间的TCP握手过程完成得干脆利落,因此开始时并无问题。接下来几个报文也很顺利,首个GET请求及回复ACK报文也在快速交付。直到最后一个报文,我们看到了高延时的信号。
第六个报文是服务器响应客户端GET请求的第一个HTTP数据报文,但是在服务器发送GET请求的TCP ACK 0.98秒之后才到达。报文5和6的传送过程与我们在前一个场景所见ACK和GTE请求的传送类似。但是,在这一情况下,服务器是我们关注的焦点。
报文5是服务器对从客户端接收GET请求的回应。只要该报文被发送,服务器就应当立即发送数据。这一读取,封装,传送的过程是由HTTP协议完成 的,由于这是应用层协议,需要服务器参与处理过程。这一报文的延迟接收表明服务器无法在合理的时间内处理数据,最终指向服务器是延时点。
延时定位思路:
通过六个报文,我们能够定位服务器与客户端之间的网络高延时点。这些场景可能看起来有点复杂,但是下图能使你的定位延时过程变得简单快捷。这一原则几乎能应用于任何基于TCP的通讯。
一站式学习Wireshark(七):Statistics统计工具功能详解与应用
Wireshark 一个强大的功能在于它的统计工具。使用Wireshark的时候,我们有各种类型的工具可供选择,从简单的如显示终端节点和会话到复杂的如Flow和IO 图表。本文将介绍基本网络统计工具。包括:捕捉文件摘要(Summary),捕捉包的层次结构(Protocol Hirarchy), 会话(Conversations), 终端节点(Endpoints), HTTP。
更多信息
Summary:
从statistics菜单,选择Summary:
如下图的截屏所示,你会看到:
File:
捕捉文件的一般信息,如文件名和路径,长度,等等
Time:
第一个包和最后一个包的时间戳,以及抓包过程持续时间
Capture:
显示文件捕捉于哪一个接口,以及评论窗口
在窗口的较低部分是Display窗口,展示抓包文件统计信息的摘要,包括:
捕捉报文的总数与百分比
显示报文的数量(加上过滤条件之后)
标记报文的数量
何时使用:
这一菜单简单收集所有抓包数据,在定义了过滤条件的时候,将呈现过滤后的数据。当想要知道每秒的平均报文数或是字节数时,可以使用此工具。
Protocol Hierarchy:
这一部分阐述如何确知网络运行数据。从statistics菜单,选择Protocol Hierarchy。
这个窗口现实的是捕捉文件包含的所有协议的树状分支。如下图所示:
Protocol Hierarchy窗口有如下字段:
Protocol:
协议名称
% Packets:
含有该协议的包数目在捕捉文件所有包所占的比例
Packets:
含有该协议的包的数目
Bytes:
含有该协议的字节数
Mbit/s:
抓包时间内的协议带宽
End Packets:
该协议中的包的数目(作为文件中的最高协议层)
End Bytes:
该协议中的字节数(作为文件中的最高协议层)
End Mbit/s:
抓包时间内的协议带宽(作为文件中的最高协议层)
小贴士:
包通常会包含许多协议,有很多协议会在每个包中被统计。End Packets,End Bytes,End Mbit/s列是该层在抓包中作为最后一层协议的统计数据(也就是说,协议处于报文的顶层,并且没有更高层信息了)。例如,没有载荷的TCP报文(例 如,SYN报文),这一类没有负载任何上层信息的报文。这就是为什么在Ethernet层,IPv4层和UDP层报文计数为0,因为没有接收到以这些协议 作为最后一层的帧。
何时使用:
值得注意的两点是:
百分比永远指的是相同协议层级。例如,
使用要点:
1. Percentage永远参照的是相同协议层。例如,上例中81.03%是IPv4报文,8.85%是IPv6报文,10.12%是ARP报文。第二层之上的各协议所占百分比总和是100%。
2. 另一方面,TCP占总数据的75.70%,在TCP协议之内,只有12.74%的报文是HTTP,除此之外没有其他统计。这是由于Wireshark只统计有HTTP头的报文。它不统计如确认报文或数据报文这样没有HTTP头的报文。
3. 为了使Wireshark同时统计数据报文,例如,TCP报文内部的HTTP报文,关闭Allow sub-dissector选项,对TCP数据流重新统计。可在Preferences菜单或Packet Details面板中右键TCP来实现。
Conversations:
1. 在Statistics菜单中,选择Coversations。
2. 会看到以下窗口:
3. 可以选择第2层以太网统计数据,第3层IP统计数据,或第4层TCP或UDP统计数据。
4. 可以选择以下统计工具:
- On layer 2(Ethernet):查找并过滤广播风暴或
- On layer 3 or 4(TCP/IP):通过互联网路由器端口并行连接,查看谁在向ISP传输数据
小贴士:
如果你看到互联网上某一IP地址通过端口80(HTTP)向外传输大量数据流,你就需要将该地址复制入浏览器并且查看你的用户与哪一个网站通讯最多。
如果没有得到结果,只需到标准DNS查询站点(Google一下DNS lookup)查看哪一种流量占用了你的网线。
5. 也可以通过选择位于窗口左下方的Limit to display filter复选框,将会话统计信息进行显示过滤。这样,仅呈现所有通过显示过滤条件的统计数据。
6.要查看IP地址对应名称,可以选择Name resolution复选框。要查看IP名称解析,进入View | Name Resolution | Enable for Network layer进行激活。
7. 对于TCP或UDP,可以在Packet list中对指定报文进行标记,之后从菜单中选择Follow TCP Stream或Follow UDP Stream。从而定义一个显示过滤条件,仅显示指定数据流。
使用要点:
网络会话是两个指定终端之间的数据流。例如,IP会话是两个IP地址之间的所有数据流,TCP会话包含了所有TCP连接。
通过Conversations列表,能看出很多网络问题。
以太网会话统计
在Ethernet conversations statistics中,查找以下问题:
- 大量的广播风暴:可以看见较轻微的广播风暴;而对于每秒数千甚至数万个报文的严重广播风暴,Wireshark会停止显示数据并且屏幕冻结。只有断开Wireshark连接时才能看见。
- 如果你看到来自某一MAC地址的大量数据,查看会话第一部分的vendor ID,会给你一些导致问题的线索。即使MAC地址的第一部分标识了vendor,但它并不一定就标识了PC本身。这是由于MAC地址属于PC上安装的以太 网芯片厂商,而并不一定属于PC制造商。如果无法识别数据流来源地址,可以ping嫌疑地址并通过ARP获取它的MAC地址,在交换机中查找该地址,如果 有操作系统的话直接用find命令来定位。
IP会话统计
在IP conversations statistics中,查找以下问题:
- 查看收发大量数据流的IP地址。如果是你知道的服务器(你记得服务器的地址或地址范围),那问题就解决了;但也有可能只是某台设备正在扫描网络,或仅是一台产生过多数据的PC。
- 查看扫描模式(scan pattern)。这可能是一次正常的扫描,如SNMP软件发送ping报文以查找网络,但通常扫描都不是好事情。
- 一次典型的扫描模式如下图所示:
本例中的扫描模式,一个IP地址,192.168.110.58,发送ICMP报文至192.170.3.44, 192.170.3.45, 192.170.3.46, 192.170.3.47,等等(上图仅显示扫描的很小一部分)。这种情况下我们有一个蠕虫病毒感染了网络上的所有PC,在它感染PC的时候,它就开始产 生ICMP请求并将它们发送至网络。这些窄带连接(例如:WAN连接)可以很容易地被*。
TCP/UDP会话统计
- 查看带有太多TCP连接的设备。每一个PC合理的连接数是10到20个,上百个则是不正常的。
- 尝试查找无法辨识的端口号。它可能是正常的,但也可能是有问题的。下图显示了一次典型的TCP扫描:
Endpoints:
1. 从statistics菜单,选择Endpoints:
2. 出现以下窗口:
3. 此窗口中,能够看到第2,3,4层的endpoints,也就是以太网,IP, TCP或UDP。
使用要点:
这一工具列出了Wireshark发现的所有endpoints上的统计信息。可以是以下任意一种情况:
- 少量以太网endpoints(MAC地址)与大量IP终端节点(IP地址):可能的情况例如,一个路由器从很多远端设备收发报文,我们会看见路由器的MAC地址及很多IP地址经由此处。
- 少量IP终端节点与大量TCP终端节点:可能的情况是每一台主机有很多个TCP连接。可能是有很多连接的服务器的一个正常操作,也可能是一种网络攻击(如SYN攻击)。
以下是一个网络中心的抓包示例,一个内部网络有四个HP服务器和一个Cisco路由器,MAC地址的第一部分已经解析了厂商名称:
当我们查看IPv4:191下的endpoints,我们看到有很多来自192.168.10.0, 192.168.30.0,以及其他网络地址。
HTTP:
1. 从statistics菜单,选择HTTP,将会出现以下窗口:
在HTTP子菜单中,可以看到以下信息:
Packet Counter:
每一个网站的报文数量。帮助识别有多少响应和请求。
Requests:
各网站的请求分布。
Load Distribution:
各网站的负载分布。
按照以下操作步骤查看Packet Counter统计信息:
1. 进入Statistics | HTTP | Packet Counter。
2. 显示以下过滤窗口:
3. 此窗口中,可设置过滤条件以查看符合过滤条件的统计信息。如果想要查看整个抓包文件的统计信息,留白不填。这就会显示IP层之上的统计信息,也就是所有HTTP报文。
4. 点击Create Stat按钮,会看到以下窗口:
如果要查看某一特定节点的HTTP统计信息,可以通过display filter的方式配置过滤条件。
按照以下操作步骤查看HTTP Requests统计信息:
1. 进入Statistics | HTTP | Requests,出现以下窗口:
2. 选择所需过滤条件。对于所有数据,留白。
3. 点击Create Stat按钮,会出现以下窗口:
4. 要获得指定HTTP主机的统计信息,设置过滤条件http.host contains <host_name> 或 http.host==<host_name>。
5. 例如,通过设置过滤条件http.host contains ndi-com.com,可以获得站点 www.ndi-com.com的统计信息,如下图所示:
6. 结果如下图所示:
按照以下操作步骤查看Load Distribution统计信息:
1. 进入Statistics | HTTP | Load Distribution。
2. 出现以下窗口:
3. 选择所需过滤条件。对于所有数据,留白。
4. 点击Create Stat按钮,会出现以下窗口:
使用要点:
当我们打开一个网页,通常会向若干个URL发送请求。本例中,我们打开的其中一个网页是www.cnn.com,并将我们导向edition.cnn.com。我们发送了若干个请求:到root URL,到breaking_news URL,以及主页上两个其他位置。
一站式学习Wireshark(八):应用Wireshark过滤条件抓取特定数据流
应用抓包过滤,选择Capture | Options,扩展窗口查看到Capture Filter栏。双击选定的接口,如下图所示,弹出Edit Interface Settints窗口。
下图显示了Edit Interface Settings窗口,这里可以设置抓包过滤条件。如果你确知抓包过 滤条件的语法,直接在Capture Filter区域输入。在输入错误时,Wireshark通过红色背景区域表明无法处理过滤条件。最有可能的情况是,过滤条件中含有输入错误,或是使用了 display filter的语法。
点击Capture Filter按钮查看并选择已保存的抓包过滤条件。
更多信息
抓取指定IP地址的数据流:
如果你的抓包环境下有很多主机正在通讯,可以考虑使用所观察主机的IP地址来进行过滤。以下为IP地址抓包过滤示例:
- host 10.3.1.1:抓取发到/来自10.3.1.1的数据流
- host 2406:da00:ff00::6b16:f02d:抓取发到/来自IPv6地址2406:da00:ff00::6b16:f02d的数据流
- not host 10.3.1.1:抓取除了发到/来自10.3.1.1以外的所有数据流
- src host 10.3.1.1:抓取来自10.3.1.1的数据流
- dst host 10.3.1.1:抓取发到10.3.1.1的数据流
- host 10.3.1.1 or 10.3.1.2:抓取发到/来自10.3.1.1,以及与之通讯的所有数据流,与10.3.1.2,以及与之通讯的所有数据流
- host www.espn.com:抓取发到/来自所有解析为www.espn.com的IP地址的数据流
抓取指定IP地址范围的数据流:
当你需要抓取来自/发到一组地址的数据流,可以采用CIDR(无类别域间路由,Classless Interdomain Routing)格式或使用mask参数。
- net 10.3.0.0/16:抓取网络10.3.0.0上发到/来自所有主机的数据流(16表示长度)
- net 10.3.0.0 mask 255.255.0.0:与之前的过滤结果相同
- ip6 net 2406:da00:ff00::/64:抓取网络2406:da00:ff00:0000(IPv6)上发到/来自所有主机的数据流
- not dst net 10.3.0.0/16:抓取除了发到以10.3开头的IP地址以外的所有数据流
- not src net 10.3.0.0/16:抓取除了来自以10.3开头的IP地址以外的所有数据流
- ip proto <protocol code>:抓取ip协议字段等于<protocol code>值的报文。如TCP(code 6), UDP(code 17), ICMP(code 1)。
- ip[2:2]==<number>:ip报文大小
- ip[8]==<number>:TTL(Time to Live)值
- ip[9]==<number>:协议值
- icmp[icmptype]==<identifier>: 抓取 ICMP代码等于identifier的ICMP报文, 如icmp-echo 以及 icmp-request。
方括号中第一个数字表示从协议头开始的偏移量,第二个数字表示需要观察多少位。
抓取发到广播或多播地址的数据流:
只需侦听广播或多播数据流,就可以掌握网络上主机的许多信息。
- ip broadcast:抓取广播报文
- ip multicast:抓取多播报文
- dst host ff02::1:抓取到IPv6多播地址所有主机的数据流
- dst host ff02::2:抓取到IPv6多播地址所有路由器的数据流
小贴士:
Wireshark包含了一些默认的抓包过滤条件。点击主工具栏的Edit Capture Filters,跳转到已保存抓包过滤列表。你会发现一些常见抓包过滤的示例。
抓取基于MAC地址的数据流:
当你需要抓取发到/来自某一主机的IPv4或IPv6数据流,可创建基于主机MAC地址的抓包过滤条件。
应用MAC地址时,需确保与目标主机处于同一网段。
- ether host 00:08:15:00:08:15:抓取发到/来自00:08:15:00:08:15的数据流
- ether src 02:0A:42:23:41:AC:抓取来自02:0A:42:23:41:AC的数据流
- ether dst 02:0A:42:23:41:AC:抓取发到02:0A:42:23:41:AC的数据流
- not ether host 00:08:15:00:08:15:抓取除了发到/来自00:08:15:00:08:15以外的所有数据流
- ether broadcast或ether dst ff:ff:ff:ff:ff:ff:抓取广播报文
- ether multicast:多播报文
- 抓取指定以太网类型的报文:ether proto 0800
- 抓取指定VLAN:vlan <vlan number>
- 抓取指定几个VLAN:vlan <vlan number> and vlan <vlan number>
抓取基于指定应用的数据流:
你可能需要查看基于一个或几个应用的数据流。抓包过滤器语法无法识别应用名,因此需要根据端口号来定义应用。通过目标应用的TCP或UDP端口号,将不相关的报文过滤掉。
- port 53:抓取发到/来自端口53的UDP/TCP数据流(典型是DNS数据流)
- not port 53:抓取除了发到/来自端口53以外的UDP/TCP数据流
- port 80:抓取发到/来自端口80的UDP/TCP数据流(典型是HTTP数据流)
- udp port 67:抓取发到/来自端口67的UDP数据流(典型是DHCP据流)
- tcp port 21:抓取发到/来自端口21的TCP数据流(典型是FTP命令通道)
- portrange 1-80:抓取发到/来自端口1-80的所有UDP/TCP数据流
- tcp portrange 1-80:抓取发到/来自端口1-80的所有TCP数据流
抓取结合端口的数据流:
当你需要抓取多个不连续端口号的数据流,将它们通过逻辑符号连接起来,如下图所示:
- port 20 or port 21:抓取发到/来自端口20或21的UDP/TCP数据流(典型是FTP数据和命令端口)
- host 10.3.1.1 and port 80:抓取发到/来自10.3.1.1端口80的数据流
- host 10.3.1.1 and not port 80:抓取发到/来自10.3.1.1除了端口80以外的数据流
- udp src port 68 and udp dst port 67:抓取从端口68到端口67的所有UDP数据流(典型是从DHCP客户端到DHCP服务器)
- udp src port 67 and udp dst port 68:抓取从端口67到端口68的所有UDP数据流(典型是从DHCP服务器到DHCP客户端)
- 抓取TCP连接的开始(SYN)和结束(FIN)报文,配置tcp[tcpflags] & (tcp-syn|tcp-fin)!=0
- 抓取所有RST(Reset)标志位为1的TCP报文,配置tcp[tcpflags] & (tcp-rst)!=0
- less <length>:抓取小于等于某一长度的报文,等同于len <=<length>
- greater <length>:抓取大于等于某一长度的报文,等同于len >=<length>
SYN: 简历连接的信号
FIN: 关闭连接的信号
ACK: 确认接收数据的信号
RST: 立即关闭连接的信号
PSH: 推信号,尽快将数据转由应用处理
- tcp[13] & 0×00 = 0: No flags set (null scan)
- tcp[13] & 0×01 = 1: FIN set and ACK not set
- tcp[13] & 0×03 = 3: SYN set and FIN set
- tcp[13] & 0×05 = 5: RST set and FIN set
- tcp[13] & 0×06 = 6: SYN set and RST set
- tcp[13] & 0×08 = 8: PSH set and ACK not set
tcp[13]是从协议头开始的偏移量,0,1,3,5,6,8是标识位
尽量避免使用抓包过滤。即便多看几个报文,也比漏看一个报文要好。当你抓取了大量报文的时候,用显示过滤(过滤选项也更多)来重点查看某一数据流。
小贴士:
如果你需要查看TCP帧中的某一ASCII字符串,用Wireshark String-Matching Capture Filter Generator(http://www.wireshark.org/tools/string-cf.html)。例如,想要抓取HTTP GET报文,输入GET并将TCP偏移量设置为0。