《wireshark网络分析的艺术》 《linux为什么卡住了?》 现象:ssh登陆某些linux服务器时,输完用户名会卡住10秒 抓包分析:发现linux服务器会向dns服务器进行进行反向解析(进行2次,1次5秒) 测试:在dns服务器中添加对应的PTR记录,卡现象解决 解决方法:google “ssh dns”;修改/etc/ssh/sshd_config cat /etc/ssh/sshd_config |grep -i usedns #UseDNS no 《像福尔摩斯一样思考》 现象:web服务器的端口号会随机发生变化; 排查1:客户端和web服务器直连,问题就消失了 根因:防火墙的一些错误配置导致的 观察到的现象: 1.回包的mac和网关mac不同-----说明了往返路径不一致 2.ttl值不符合预期,预期应该是63,实际为64-----说明了往返路径不一致 3.3次握手的sys/ack包和后续的ack包的ip identification不一致(一般情况下,identification是不变的) 《一篇关于VMware的文章》 问题现象:某些iSCSI存储阵列在出现网络拥塞时处理不当,会严重影响VMware的独行性能 根因:存储基于TCP实现的关系 解决方式:在VMware和iSCSI存储阵列关闭延迟确认(delayed ack) 有很多tcp协议栈默认启用延迟确认 VMware建议关闭延迟确认 《来点有深度的》 对应上一篇文件,另一种解法是开启sack 启用sack比关闭延迟确认更高效,因为它可以一次性重传多个丢包,而不用每重传一个就等待一次ack,白费多个往返时间。 这在局域网环境中,优势不是很明显;但是在远程场景下,一个正常的往返时间都需要花费上百ms,那就更应该启用asck了 延迟确认严重影响性能的场景: 0.上述的场景,网络拥塞的场景下,每重传一个报文,都需要等待延迟确认 1.tcp窗口极小的情况下,例如接口窗口只有2920字节,相当于2个MSS,那么每发2个报文,就需要等待ack,因为没有ack,发送窗口就不会更新,就无法发送报文 tcp.analysis.ack_rtt > 0.2 and tcp.len == 0 #过滤出所有超过200毫秒的ack 《三次握手的小知识》 握手失败一般2种情况: 1.丢包 2.拒绝 (tcp.flags.reset == 1) && (tcp.seq == 1) #直接过滤出reset置位的拒绝报文 (tcp.flags.syn == 1) && (tcp.analysis.retransmission) #过滤出丢包or服务端静默的情况or服务端回包丢包 建议在client和server两端同时抓包,观察数据包是否相同。 《被误解的TCP》 误区1:tcp每个包都有对应的ack 每发出一个http请求,就会收到一个http响应; 不止是http,绝大多数应用层协议都采用一问一答的工作方式 但是tcp不一样,ack的频率,不同的操作系统有不同的偏好,比如linux客户端喜欢每收到2个包会一个ack windown客户端更懒,隔好多包菜ack一次 安卓手机收到每个包都会回复ack 误区2:tcp的传输效率比udp低 作者表达的意思:只要发送窗口足够大,tcp也可以源源不断地发送数据,那么这种情况下,未必效率就比udp低了 《最经典的网络问题》 wireshark不但能发现网络上的问题,也能反映出接收方和发送方的一些配置,只不过需要一些技巧来发现 问题:AIX备份到windows系统特别慢,只有1MB/s;基于SFTP传输 其实讲的就是nagle算法+延迟确认 产生的问题。。。 解决方法:2种算法关闭其中一种即可。 《为什么丢了单子?》 问题:访问NFS服务器时,有些文件命名允许某个用户组访问,但是该组的用户却访问不了 复现问题: 1.在linux客户端创建测试账号,并将该账号加入到20个用户组中 2.某个NFS服务器的共享目录挂载到客户端 3.用root账号在共享目录中创建20个空的测试文件,逐个分配给第一步提到的那20个用户组,并将文件权限都设置为070 4.用测试账号逐一打开(cat)这些文件,前16个没有报错,但后4个都报permission denied错误。 抓包分析:客户端的RPC层,只将该账号所属的前16个用户组传递给NFS服务器 RFC 5531 中确实限制了最多传16个用户组 问题解决:将客户端的/etc/passwd和/etc/group复制到服务器上;当服务器用到用户组时,进行本地查询,完全忽略了RPC层传过来的信息 弊端:客户端修改了用户组,需要手工同步到服务器,否则会出现访问问题 《受损的帧》 链路层的错误检测机制FCS: 发送方:每个帧在发送前都会被发送方校验一次,然后生成4字节的FCS存在帧尾 接收方:拿到帧之后,用相同的算法再做一次校验并生成FCS。如果两个FCS不一致,则认为帧已经被损坏,应该丢弃了。 这个校验是由网卡来完成的。所以主机上一般看不到FCS区域 既然抓包看不到损坏的帧,那么如何判断存在损坏的帧呢? netstat -i 问题:wireshark也有bug的时候,会显示错误,把上一个包的部分数据(12字节)作为另一个包的链路层数据显示。结果看起来是另一个包的链路层数据量过大,看起来像是一个损坏的帧 《虚惊一场》 抓包分析时,需要充分考虑到通信两端的发送和接收是存在延迟的;因为这些延迟,可能导致数据包看起来和理想的数据不一致时,此时需要深入分析,而不是觉得就是遇到bug了 《NTLM协议分析》 NTLM是window NT时代就出现的身份验证协议 例如使用windows打开一个远程目录,这里会进行验证,此时就用到了NTLM NTLM协商过程: 1.客户端向服务器发送一个NTLM协商请求;服务器立即回复一个随机字符串作为challenge 2.客户端收到challenge后,向服务器回复了输入的那个用户名xxxx以及2个response值(2个response值是用hash过的用户密码对challenge锁进行的加密,两种不同的加密方式产生了2个不同的response) 3.服务器收到之后,把challenge和2个response转发给域控(domain controller),让域控帮忙验证真假 4.域控收到之后,也用hash过的用户密码对该challenge进行加密。如果加密结果和这2个response一致,说明密码正确,身份验证通过;在响应时,将用户以及用户所属的群组信息告知服务器 5.服务器收到域控发来的消息后,告诉客户端身份验证通过了 《wireshark的提示》 packet size limited during capture:说明被标记的包没有抓全 操作系统不同,默认的抓包长度也有不同;可以通过-s进行设置 tcp previous segment not captured:wireshark发现一个包的seq大于上一个包的seq+len时,就会进行提示 出现该情况的可能:1.丢包;2.抓包工具漏了;3.乱序 如果是抓漏了,可以通过ack报文来确认是否真的是漏了 tcp out-of-order:乱序 wireshark发现后一个包的seq小于前一个包的seq+len时,会认为乱序 tcp acked unseen segment:ack包对应的那个数据包没有抓到,wireshark就会进行该提示 这个提示是可以忽略的,因为都回ack了,那么接收方肯定是收到报文了,只不过没有被抓到而已。。 tcp dup ack:重复ack;当乱序or丢包发生时,接收方收到了一些seq号大于预期值的包 tcp fast retransmission:tcp快速重传 tcp retransmission:tcp超时重传 tcp zerowindow:表示缓存区已满,不能接受数据(不常出现,因为很少缓存区被真正消耗到0) tcp window fill:表示发送方已经把对方声明的接收窗口耗尽了(所以这个也出现的比较少?因为一般剩余几十字节的窗口时,算法会等待窗口放大了再发送) tcp segment of a reassembled PDU:wireshark将属于同一个应用层PDU的tcp包虚拟地集中起来。 该功能需要在wireshark中主动开启:edit-->preferences-->protocols-->tcp菜单-->启用allow sub reassemble tcp streams continuation to#:说明“allow sub reassemble tcp streams”功能未开启 time-to-live exceeded(fragment reassembly time exceeded):表示这个报的发送方之前收到一些分片,但由于某些原因迟迟无法组装起来。 例如某数据包分片丢失,导致无法组装。 《书上错了吗?》 建议两边同时抓包,否则可能会因为回包的传输时延看到与理论不相符的现象;所以需要两边同时抓包,对照着看,避免出现误解。 《计算在途字节数》 在途字节数(bytes in flight):已经发送,但是还未经确认的字节数 在途字节数如果超过了网络的承载能力,那么就会造成丢包/重传 对于接收方,是看不到在途字节数的,也没有分析的意义;因为接收方看到数据就会进行接收咯。。。 对于发送方,存在已发送,但未经确认的数据,这就是在途数据,在途字节数 在途字节数 = 当前数据包的seq+len - 上一个ack的ack值 《估算网络拥塞点》 拥塞点:发送数据正好超过网络承载力,造成丢包重传 发生拥塞时,在途字节数就是该时刻的网络拥塞点;这种方式计算不是完全准确,但具备一定的参考价值 查找拥塞点的方法: 1.找到第一个重传包,然后找到它的原始包 2.根据原始包以及上一个ack来计算在途字节数 3.使用该方法多次查找拥塞点,这样统计出的拥塞点更准确,也更具说服力 每一次拥塞都对传输性能有很大的影响,即使千分之一的概率,也足以导致性能大滑坡 《顺便说说LSO》 现象:wireshark分析,可以看到重传包,但是却找不到原始包 原因: 1.丢包了,所以看不到原始包 2.抓包晚了,没抓到 3.wireshark bug,把一个正常包标记为重传包了 4.原始包实际上已经抓到了,但是存在于另一个包内,直接通过seq不能过滤到而已 传统网络工作方式: 1.应用层把产生的数据交给TCP层 2.TCP层根据MSS大小进行分段(CPU负责),然后交给网卡 LSO(large segment offload): 1.应用层把产生的数据交给TCP层 2.TCP层不分段,直接把大于MSS的数据交给网卡 3.网卡负责分段工作 《熟读RFC》 性能问题是最难的,因为没有任何报错可以入手 问题:客户端发送数据到国外服务器非常慢,不到预期值的一半 分析: 1.查看专家信息,1万个包只有7个包有重传 2.点击ack查看往返时间RTT,大概78ms,比较稳定 影响发送速度的发送窗口取决于2个窗口 1.拥塞窗口cwnd 2.接收窗口(本案例接收窗口很大了。。) cwnd增长的2个阶段 1.慢启动:起点低,增长快;每收到1个ack,cwnd就增加1个mss 2.拥塞避免:起点高,增长慢;每个rtt,即一轮的cwnd数据包确认后,cwnd才会增加1个mss 在途字节数一定程度上可以看成拥塞窗口 回到案例:发现每经过1个rtt,cwnd才增加195bytes,这个就是传输慢的原因 哦哦哦,上面那个确实是原因,但是这个原因是正常的!其实就是拥塞避免阶段的正常算法嘛 根因:服务端回的ack数量过少,导致了cwnd增长过慢。。。(回包过少的原因是因为服务器开启了LRO,会积累多个包再集中处理,因为ack包数量也少了) 《一个你本该能解决的问题》 问题背景:在上海的主数据,通过网络10分钟同步一次到北京的镜像。带宽经过计算是符合要求的,但是实际10分钟不能完成同步。 抓包看到问题:icmp time-to-live exceeded(接收发因为分片丢包而无法按时完成数据包的重组) 根因:传输使用udp,同时数据包被分片,部分分片的丢包导致了所有数据的重传,导致了传输效率低 《几个关于分片的问题》 问题1:为什么要分片? 1个IP包最多些到1480字节数据(1500-20);传输的数据块大于1480时,就会进行分片 问题2:发送方是怎么样确认分片大小的? 一般来说,发送方根据自身的MTU来决定分片大小 问题3:接收方又是靠什么重组分片的? 1.每个分片都有“off=xxx,ID=xxx”的信息,根据off偏移量完成重组 2.最后一个分片有flag“more fragments = 0”;其他分片“more fragments = 1 ” 网络攻击:不断发送“more fragments = 1 ”的数据包,导致接收方耗尽内存 问题4:TCP是如何避免被发送方分片的? 1.TCP开始时就主动根据MTU进行协商MSS,发送数据时,主动分片后再传给IP层 2.UDP没有MSS的概念,所以可能会被分片 问题5:TCP怎么样适配接收方的MTU? 通过tcp3次握手协商;使用mtu较小的那一方的mtu值 但是传输路径上的网络设备mtu较小的话,这个问题无法避免 问题6:为什么udp比tcp更适合语音通话? 1.语音通话更在于数据的实时性 2.可以想象语音基于TCP,发生TCP重传的美妙场景 《MTU导致的悲剧》 IP层DF位 1.若DF位置位,且数据包过大,那么丢包 2.若DF位没有置位,且数据包过大,那么分片 1472(数据)+8(icmp报头)+20(ip头) = 1500 所以指定数据>=1473字节时,且DF置位,那么将会一直丢包 案例1:用户浏览某些共享目录时,客户端会死机,浏览其他目录则不会 抓包分析发现持续重传,但是客户端一直没有确认 丢包的可能: 1.防火墙阻止(那么3次握手就会丢) 2.网络拥塞(那么不会持续丢,而应该是随机丢) 3.丢的那个包比较大,而其他较小的包没丢(有可能是MTU的缘故) 测试:ping包指定数据大小,同时设置DF位 案例2:客户端MTU 1500;服务端MTU9000,平时正常;两端都修改9000后,反倒出问题了 因为tcp协商使用较小的MTU,所以平时没有问题;但是两端都修改9000后,那么MSS也协商位8960,反倒出问题了View Code
标签:总结,重传,ack,tcp,拥塞,网络分析,分片,客户端,wireshark From: https://www.cnblogs.com/AllenWoo/p/17002783.html