其他分享
首页 > 其他分享> > Wireshark分析艺术【读书总结】

Wireshark分析艺术【读书总结】

作者:互联网

Wireshark分析艺术【读书总结】

一,Wireshark实战操作

界面的操作分析

三板斧之一:查看统计、属性信息

性能分析三板斧之一:

【统计->捕获文件属性】 Statistics -> Summary,查看文件属性信息,如平均速度、包大小、包数等等

判断流量高低峰、是否过载



三板斧之二:查看分析专家信息

性能分析三板斧之二:

【分析->专家信息】 Wireshark ->Analyze -> Expert Infos -> Notes,查看抓包的统计信息

查看是否有Notes、Warnings、errors之类的信息,看看是否有相关警告和错误,判断网络质量、重传乱序等



三板斧之三:查看服务响应时间

性能分析三板斧之三:

【统计->服务响应时间】 statistics -> Service Response Time -> xxxxx(如:ONC-RPC -> Program:NFS)

查看各项操作的服务响应时间,判断是否过载

将seq使用相对值来替代真实值

Edit->Preferences->Protocols->TCP,勾选 Relative Sequence Numbers

启用之前就是相对值了。

查看TCP StreamGraph

Statistics -> TCP StreamGraph -> TCP Sequence Graph(Stevens)

查看数据传输情况,如传输的是否均匀、是否有TCP Zero Windows之类的

字段含义&提示信息

字段含义就是wireshark的一些提示信息,也就是wireshark抓包的一些info信息,这些提示信息都是Info这一栏中体现。

1,[Packer size limited during caputre]

如果某个包被标记提示[Packer size limited during caputre],说明这个包没有抓全,可以进一步查看下面的frame信息。一般这个情况是抓包的姿势不对。某些操作系统中,tcpdump默认只抓取每个帧的前96个字节,因此tcpdump抓包的时候,可以通过 -s参数指定要抓取的字节数

2,[TCP ACKed unseen segment]

如果wireshark发现被Ack的那个包没有抓到,就会提示[TCP ACKed unseen segment],不过这个提示大部分情况都可以忽略。因为大都情况下,刚开始抓包的时候,都是只抓到了后面的Ack而没有抓到前面的ACK

3,[TCP Previous segment not captured]

TCP数据传输中,除了三次握手和四次握手之外,同一台机器发出的数据段应该是连续的,即后一个包的Seq等于前一个包的Seq+Len,正确情况都应该是这样;如果发现后一个包的Seq大于前一个包的Seq+Len,那么就说明中间丢了一段数据,如果丢失的数据在整个网络包中都找不到,wireshark就会提示[TCP Previous segment not captured]

出现这种情况的两个可能性:

4,[TCP Out-of-Order]

TCP数据传输中,除了三次握手和四次握手之外,同一台机器发出的数据段应该是连续的,即后一个包的Seq等于前一个包的Seq+Len,正确情况都应该是这样;或者说后一个包的Seq应该会大于等于前一个包的Seq+Len,如果wireshark发现后一个包的Seq小于前一个包的Seq+Len,那么就认为是乱序了,就会提示[TCP Out-of-Order]

一般而言,小跨度的乱序影响不大,如果是大跨度的乱序则会导致快速重传。举例如下,如果一个包的顺序是1、2、3、4、5被打乱成2、1、3、4、5则属于小跨度乱序,影响不大;如果被打乱成2、3、4、5、1,则会触发足够多的Dup ACK,从而导致1号包的重传。

5,[TCP Dup ACK]

当乱序或者丢包发生时,接收方就会收到一些Seq号比期望值大的包,TCP协议每收到一个这种包就会ACK一次期望的Seq值,通过这个方式告知发送方,因此就产生了一些重复的Ack。Wireshark抓到这些重复的Ack就会提示[TCP Dup ACK].

6,[TCP Fast Retransmission]

当发送方连续收到3个或者以上[TCP Dup ACK]时,就意识到之前发的包可能丢了,于是根据RFC的规定就会开始快速重传。[TCP Dup ACK]是接收方回应给发送方的,因此发送方就能够感知到并当连续收到3个以上的时候就开启快速重传。

快重传算法规定,发送方只要一连收到3个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计数器时间到期。

7,[TCP Retransmission]

如果一个包真的丢了,又没有后续包可以在接收方触发[Dup Ack],那么就不会开启快速重传,这种情况发送方只能等到超时后再发送重传,超时重传的包就会被wireshark标记并提示[TCP Retransmission]

TCP 超时与重传应该是 TCP 最复杂的部分之一,超时重传是 TCP 保证可靠传输的基础。当 TCP 在发送数据时,数据和 ack  都有可能会丢失,因此,TCP  通过在发送时设置一个定时器来解决这种问题。如果定时器溢出还没有收到确认,它就重传数据。关键之处就在于超时和重传的策略,需要考虑两方面:

在 Linux 较高的内核版本中,比如 3.15 中,已经有了至少 9 个定时器:超时重传定时器,持续定时器,ER延迟定时器,PTO定时器,ACK延迟定时器,SYNACK定时器,保活定时器,FIN_WAIT2定时器,TIME_WAIT定时器。

8,[TCP zerowindow]

TCP包中“win=xxx”代表接收窗口的大小,表示这个包的发送方当前还有多少缓冲区可以接受数据。当wireshark发行一个包中的“win=0”时,就会标记提示[TCP zerowindow],表示缓冲区已经满了,无法再接收数据了。

一般的,在缓冲区满之前,窗口大小应该是逐渐减小的过程。

9,[TCP window Full]

如果一个包的发送方已经把对方所声明的接收窗口大小耗尽了,就会被wireshark标记为[TCP window Full]。比如某一端在握手时声明自己的接收窗口只有65535,也就意味着对端最多只能给他发送65535字节的数据而无需确认,即“在途字节数”最多只能是65535,当wireshark计算出对端已经有65535字节未被确认时,就会发生这个提示。

[TCP window Full]和上面的[TCP zerowindow]比较容易混淆,前者表示这个包的发送方暂时没有办法再发送数据了;后者表示这个包的发送方没有办法再接收数据了;两者都会意味着要暂停数据传输

10,[TCP segment of reassembled PDU]

只有在Edit->Preferences->Protocols->TCP菜单里启用了Allow sub dissector to reassemble TCP streams后,才有可能收到这个提示。这个表示可以把属于同一个应用层PDU的TCP包虚拟的集中起来

11,[Continuation to #]

只有在Edit->Preferences->Protocols->TCP菜单里关闭了Allow sub dissector to reassemble TCP streams后,才有可能收到这个提示。

12,[Time-to-live-exceeded(Fragment reasembly time execeeded)]

(Fragment reasembly time execeeded)表示这个包的发送方之前收到了一些分片,但是由于某些原因导致迟迟无法组装起来。

比如传输过程中有一些分片被丢包了,那么接收方就无法组装起来,然后就通过这个ICMP的方式告知发送方

ICMP是(Internet Control Message  Protocol)Internet控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。

二,Wireshark分析TCP协议

TCP抓包协议基础

TCP控制字段

在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG.

抓包显示的控制字段形态如下:

[SYN] : 建立连接、发起包 [FIN] : 关闭连接、结束包 [PSH] : DATA数据传输 [ACK] : ACK回应 [RST] : RESET、连接重置

另外两个常用字段:

[Len] :数据包长度 [Seq] :数据包序列号

ACK是可能与SYN,FIN等同时使用的,比如SYN和ACK可能同时为1,它表示的就是建立连接之后的响应,如果只是单个的一个SYN,它表 示的只是建立连接

当出现FIN包或RST包时,我们便认为客户端与服务器端断开了连接 当出现SYN和SYN+ACK包时,我们认为客户端与服务器建立了一个连接

抓包方向(client or server)

TCP的Ack

对应http而言,一般就是request->reponse,一问一答。但对应TCP而言,并不一定每个包都会ACK。TCP的ACK是一种累积的ACK,也就是表示在我这个ACK之前的所有其他ACK都已经确认收到了。

比如,97号包的ACK=65701,96号包的Seq+Len=64273+1428=65701,那么就是表示97号的ACK是对96号的回应,也就是96号之前的其他没有被显示ACK的包,其实都已经通过97号包ACK了,这样发送方也就知道了在96号之前发出去的所有包对方都已经收到并ACK了。

MSL、TTL、RTT

MAC地址解析

Protocol = ARP Source 和 Destination 都是MAC地址格式如 00:60:48:ff:12:31

抓包分析中,如果网络不通,发出去收不到ACK等等之类的,要再进一步看看每个包的MAC地址是否正确,反之有多个MAC地址导致的一些问题

TCP握手和挥手协议

TCP三次握手&判断回包

TCP四次挥手&三次挥手

TCP拥塞控制算法

在途字节数

网络拥塞

一些实战经验告诉我们,Wireshark ->Analyze -> Expert Info -> Notes统计中的重传率如果超过了0.1%,就需要采取一些措施了。但是现实网络环境下,要低于0.01%的重传是基本不可能的。

发送窗口

TCP Nagle算法和延迟确认Delayed ACK

  1. Nagle算法:
       if there is new data to send                                                            复制代码
       if the window size >= MSS and available data is >= MSS         
       send complete MSS segment now       
       else         
       if there is unconfirmed data still in the pipe           
       enqueue data in the buffer until an acknowledge is received         
       else           
       send data immediately         
       end if       
       end if     
       end if 
       
       
2 .延迟ACK:

如果tcp对每个数据包都发送一个ack确认,那么只是一个单独的数据包为了发送一个ack代价比较高,所以tcp会延迟一段时间,如果这段时间内有数据发送到对端,则捎带发送ack,如果在延迟ack定时器触发时候,发现ack尚未发送,则立即单独发送;

延迟ACK好处:

(1) 避免糊涂窗口综合症; (2) 发送数据的时候将ack捎带发送,不必单独发送ack; (3) 如果延迟时间内有多个数据段到达,那么允许协议栈发送一个ack确认多个报文段;

3.当Nagle遇上延迟ACK:

试想如下典型操作,写-写-读,即通过多个写小片数据向对端发送单个逻辑的操作,两次写数据长度小于MSS,当第一次写数据到达对端后,对端延迟ack,不发送ack,而本端因为要发送的数据长度小于MSS,所以nagle算法起作用,数据并不会立即发送,而是等待对端发送的第一次数据确认ack;这样的情况下,需要等待对端超时发送ack,然后本段才能发送第二次写的数据,从而造成延迟;


4 .关闭Nagle算法:

使用TCP套接字选项TCP_NODELAY可以关闭套接字选项;

如下场景考虑关闭Nagle算法:

(1) 对端不向本端发送数据,并且对延时比较敏感的操作;这种操作没法捎带ack; (2) 如上写-写-读操作;对于此种情况,优先使用其他方式,而不是关闭Nagle算法:

TCP和UDP的区别、对比

主要区别

TCP和UDP的区别如TCP是可靠的、UDP是不可靠的,但是实际中的表现是何为可靠?何为不可靠?具体协议的ACK有何区别?

不管对于TCP还是UDP,都可能会被分片,这是由于以太网的MSS决定的;不同在于分片传输的处理:

UDP 比 TCP 更适合语音

语音通话的场景在于不能接受延迟,但是可以接受音质稍差。这样的话,UDP传输的时候,如果有些包丢失,应用层可以选择忽略并继续传输其他包,丢到一些包只会影响到音质,但是保证了流畅性。TCP而言,会重传每个包,只要丢包就重传,这样就会导致有一定的延迟,在语音中如果有延迟则并不可取。

因此,TCP和UDP,各自有各自的适合场景。 语音、视频中,UDP更合适,像声网、linphone等都是UDP去处理音视频。 基础、核心协议交互中必须采用TCP。

TCP和UDP的效率问题

TCP在传输过程都需要往返时间来确认也就是ACK,而UDP则无需确认,那么UDP的效率一定比TCP高吗?这个是不一定的,虽然UDP可以一直往外不停的发包,不用等待ACK;但是TCP有发送窗口的存在,如果发送窗口小,并没有占满带宽,那么肯定受到往返时间的约束使得效率稍低,但是如果只要窗口足够大并且合适,跑满带宽,那么TCP也是可以不受往返时间的约束而源源不断的传输数据。

举例:马路上只有一辆车来回跑去拉货,回程过程相当于空跑(回程相当于TCP的ACK),这样TCP的效率当然低。但是如果在不拥塞的情况下,尽量提高车辆数量,是的马路上的车被刚好充满,这样总体的传输效率提高了,并且回程的ACK也不受影响。

数据包分片、MTU、MSS

数据包分片和重组

分组交换,把大的数据分割成小包,这样可以实现链路共享,而不至于因为某一方阻塞所有。既然要分割成小包,那么必然要确定一个最大的包大小,这个就是MTU(Maximum  Transmission  Unit)最大传输单位,值为1500字节。如果除去20个字节的包头结构,那么一个IP包最大的包大小为1500-20=1480字节。如果要传输的数据块超过1480字节,那么网络层就会将其分片处理,封装为多个网络包传输。对于TCP而言,TCP协议层会主动把数据分成小段后再交给网络层,TCP的最大分段大小称之为MSS(Maximum  Segment  Size),这个MSS被设置为MTU减去IP头和TCP头之后的大小,这样刚好可以满足一个MTU。因为UDP没有MSS的概念,因此就只能交给网络层去处理分片了。

但是需要注意的是,目前有些网络是Jumbo  Frame(巨帧)或者PPPOE这样的设备,那么他们的MTU则不是1500字节。目前发送方并没有一个好的机制来确定最佳分片大小,应该尽量使得网络中的设备的MTU保持一致。如果网络中的设备的MTU不一致,那么TCP协议如何适配MTU呢?我们知道TCP建连的时候必须要先进行三次握手,TCP在前两个握手包中会相互声明自己的MSS。如果client端声明自己的MSS=8960(巨帧),server端申明自己的MSS=1460,那么client在三次握手后就知道了server端的MSS,因此当client想要发送大于server端MSS的包的时候就会主动将自己的MSS降低为server端的MSS大小,从而适配接收方的MTU,可见,TCP协议层做了非常多的优化和处理

既然有分片,那么接收方必然要进行分片重组,通过抓包工具可以得知,分片的每个包都包含了off=xxx,ID=xxx这样的信息,接收方会把ID相同的分片按照off偏移量进行重组。那么接收方又如何得知那个包才是最后的分片呢?然后什么时候开始重组呢?这里就在于最后一个分片包有一个特殊的Flag,叫More fragment = 0,抓包中的表现形式是..0. ... = More fragment: Not set,这个就表示它是最后一个分片,然后可以开始重组包了。如果是其他分片包,形如..1. ... = More fragment: set则表示接收方需要缓存,等待其他分片传输完成

MTU的实战

如果client端的MTU=9000,server端的MTU=1500,那么当client请求server端的时候,client的包经过路由器时候,要么就被丢包,要么就被分片。如果这个巨帧包在网络层携带了DF(Don't   fragment)标志则被丢弃(设置则表示不允许分片),如果没有设置则进行分片传输。需要注意的是,这种情况下如果丢包了重传还是会被丢弃,就成了黑洞了。

测试中,可以通过ping命令模拟这样的情况:

    成功: ping xxx.xxx.xxx.xxx -l 1472 -f -n 1 
    失败: ping xxx.xxx.xxx.xxx -l 1473 -f -n 1  复制代码

-f 参数表示设置DF标志 -l 参数表示请求字节

当请求字节设置为1472的时候,因为ICMP头部为8字节、IP头为20字节,因此1472+8+20=1500,刚好是一个MTU,因此可以ping成功。但是第二个1473+8+20=1501字节超过MTU了,又因为设置了DF标志表示不允许分片,因此传输失败,一般这样的情况下,路由器会回复Packet needs to be fragmented but DF set

抓包的时候,如果发现一直重传,某个某些相对较大的包(查看Len值)才重传,那么可以通过ping xxx.xxx.xxx.xxx -l [Len] -f值进行测试验证,通过这个ping指定的[Len]的大小变化来寻得规律,可能就会发现网络上某个设备的MTU并非1500,这样导致了超过这个就重传的现象。

特殊的流控和带宽

client 和  server端直接一定有交换机、路由器等设备,如果server端是万兆网卡,client端是千兆网卡,就有可能使得server端发送过快导致数据堵在交换机上,从而交换机在堵满之后发生丢包。   但是一般而言,server端的带宽本应该要大于client端才算合理,为了避免拥塞,因此需要有一种流控机制,允许交换机在过载时告知server端放慢速度或者暂停传输。

有一种“暂停帧”,就能够满足这样的需求:当交换机的缓冲区即将被填满时发送给server端一个暂停帧,当server端等待一会儿再发,这样就可以避免溢出丢包,也避免丢包后的重传。server端等待多久则由暂停帧中的pause_time指定,这样server端在等待pause_time后才会开始继续发送。当然交换机还可以给server端发送一个pause_time=0的暂停帧,告知server端,我已经消化完了,可以立即发送了。

注意,这的流控和TCP的流控是不一样的

三,用Wireshark分析方法论

  1. 通过wireshark排查问题,需要分析网络包,在网络包中寻找一些线索,然后根据网络协议作出推断,接着就是一个一个去否定,然后最终找到问题所在

  2. 需要能够理解底层TCP协议,要能够清楚每一个字段表示的含义

  3. 要善用Wireshark的一些统计、分析工具;过滤器等

  4. 发送发抓包和接收抓包是有极大区别的

  5. 要善用“三板斧“的操作流程和步骤去分析问题

 相关推荐

标签:总结,重传,Seq,ACK,MSS,TCP,发送,读书,Wireshark
来源: https://blog.51cto.com/15127514/2680191