《wireshark网络分析的艺术》总结
《linux为什么卡住了?》《像福尔摩斯一样思考》《一篇关于VMware的文章》《来点有深度的》 ==================================================================================================================== 《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
《三次握手的小知识》《被误解的TCP》《最经典的网络问题》《为什么丢了单子?》《受损的帧》《虚惊一场》 ==================================================================================================================== 《三次握手的小知识》 握手失败一般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协议分析》《wireshark的提示》《书上错了吗?》《顺便说说LSO》 ==================================================================================================================== 《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》(cwnd)《一个你本该能解决的问题》《几个关于分片的问题》《MTU导致的悲剧》 =========================================================================================================== 《熟读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,反倒出问题了
《迎刃而解》《昙花一现的协议》《另一种流控》《过犹不及》《治疗强迫症》 =========================================================================================================== 《迎刃而解》 问题:某台客户端连接某台服务器有问题;连接其他服务器都是ok的 抓包分析: 1.看到了第2个包sys,ack包的虚假重传,客户端也回复了第3个包,ack包 2.说明了第3个包没有被服务器接收到,3次握手没跑完 3.深入分析,发现3次握手的syn包和ack包的dst mac不一致 TLB(transmit load balancing):多网卡完成一个NIC teaming,特点:接收由1张网卡负责,发送则分摊给所有网卡 所以这里回包发送给了只负责发送的网卡,该网卡不能负责接收,那么就丢包了。。。 ---------------------------------------------------------------------------------------------- 《昙花一现的协议》 背景:98年,当时以太网的传输速度不够快,此时的FC网络可以达到2Gbit/s,而以太网仅仅只是百兆网络 FMP网络协议,相当于是双栈的一个协议: 1.通过以太网获取文件位置 2.通过FC网络完成文件读写 现在已经不用FMP协议了,因为以太网更新换代,带宽甚至超过了FC ---------------------------------------------------------------------------------------------- 《另一种流控》 问题:服务器端使用千兆网络时,是正常的;仅升级服务器端网络为万兆后,反倒出现了问题,性能下降了 分析:wireshark抓包分析,果然看到了重传和快速重传 重传率超过千分之一,就得采取措施了 万分之一以下的重传率,很难消除 根因:服务器侧更滑万兆网络后,发包太快;而交换机连接客户端的还是千兆网络,从而造成了丢包 ---------------------------------------------------------------------------------------------- 《过犹不及》 问题:数据中心在中东,需要定时把新数据同步到英国,常常因为传输太慢而同步超时。 分析:wireshark专家信息显示10万个包中存在1万个重传和快速重传包 再查看会话数,发现了客户使用50个tcp连接来做数据同步 因为单个连接可能无法占满整条链路,增加一些连接数确实可以提高传输效率 但是连接数过多却没有意义,反倒可能造成资源争抢,提高了丢包率 合理的tcp连接数:这和网络带宽、往返时间、发送窗口都有关系;没有固定公式,只能一边调节一边观测 ---------------------------------------------------------------------------------------------- 《治疗强迫症》 以2人同时编辑一个文件为案例 notepad实验:后保存的动作会覆盖前一个人的内容,且没有提示 notepad++实验:第一人保存时,会给第二人弹窗提示 excel实验:不允许2个人同时编辑,第二人打开文件时,会提示该文件被锁
《技术与工龄》《如何科学地推卸责任》《一个面试的建议》《假带宽的真相》《手机抓包》《微博为什么会卡》 =========================================================================================================== 《技术与工龄》 背景:客户购买了最高端的服务器,上线后却发现性能不达预期 客户投诉和服务器有关,服务器的接收窗口居然只有16KB(16384) 其实这里wireshark提示了“window size scaling factor”,因为tcp3次握手协商的 window scale参数没抓到 假如协商的window scale为3,那么实际通过的接收窗口为16384*2*2*2 = 131072 所以这里的根因并不在于接收窗口太小,而是其他原因。。。 ---------------------------------------------------------------------------------------------- 《如何科学地推卸责任》 故障现象:在client侧抓包,发现从server侧发来了大量的RST报文 在client/server两端同时抓包,发现client侧收到RST报文,但是server侧并没有发过RST报文 排查方法:通过TTL值来判断,发现RST报文却是不是server端发送的,根据TTL条数可以判断出是防火墙发送的RST报文 ---------------------------------------------------------------------------------------------- 《一个面试的建议》 仅仅只是面试建议 你在工作中遇到什么困难,最后是怎么解决的? ---------------------------------------------------------------------------------------------- 《假带宽的真相》 对测试软件进行抓包,发现同时使用了5个TCP连接 在《一定带宽接入速率测试方法》通信行业标准中,明确规定了“测试中使用的线程数量>=4” 连接数达到一定数量后,再多就没什么意义了,甚至会影响TCP的拥塞控制效果。 在下载测试开始前,使用get请求获得下载源,然后以IP的形式直接发起下载测试,避免了DNS的影响 ---------------------------------------------------------------------------------------------- 《手机抓包》 1.安卓和iphone的web抓包,可以使用fiddler和charles工具抓包 2.在pc上设置http代理,然后在pc上抓包 3.一些现成的安卓抓包工具,需要root权限;ios上没有这类软件 4.tpackercapture工具,无需root也可以抓包,但是需要到googleplay上下载。。。需要越狱 5.pc设置热点,手机连接该热点,在pc上抓包 ---------------------------------------------------------------------------------------------- 《微博为什么会卡》 手机微博经常发现会卡,通过pc热点抓包 发现了手机微博严重依赖dns,两分钟的抓包,上百个dns查询动作;相比之下,微信的dns请求就少很多 把手机dns设置了一个错误的ip,然后就复现了微博的问题
《寻找httpDNS》《谁动了我的网络》《一个协议的进化》《假装产品经理》《自学的窍门》《打造自己的分析工具》《一个创业点子》 =========================================================================================================== 《寻找httpDNS》 DNS支持GSLB,能根据DNS请求所包含的原地址返回最佳结果,从而匹配同地区/同运营商的IP,使用户体验到最好的性能 腾讯的GSLB是通过DNS服务器的地址来判断的,而不是通过用户IP来判断; 这种配置会存在问题,假设电信用户配置了联通dns,那么访问网站时,将拿到该网站的联通ip,最终也将访问网站的联通ip,这属于绕远路的行为,用户体验变差 腾讯使用httpdns来解决这个问题,允许手机的app直接查询腾讯自家的httpdns服务器,根据用户的地址判断返回的ip,从而绕过来传统dns的影响 实际情况经过抓包测试,并没有发现哪个主流产品使用来httpdns,所以也没有抓到过httpdns的包 ---------------------------------------------------------------------------------------------- 《谁动了我的网络》 从一个网站广告的案例,找到了运营商插入广告的秘密 通过分光器设备,复制了http请求;结果真实server/虚假server都进行了响应,因为虚假server距离用户更近,所以响应会先一步到达 判断的网络层依据: 1.TTL值,数字相同的几率很低 2.IP头的Identification,在一个会话中,第一个包的Identification是随机的,之后每发一个包,数值+1;如果发现Identification值突然有变化,不符合规律,那么就是虚假server回的包 判断的tcp层依据: 1.虚假server并没有参与3次握手过程,不清楚windows scale数值,所以server在回包时,会携带真正的窗口值,很可能会大的夸张 2.虚假server的回包可能会导致wireshark提示乱序 ---------------------------------------------------------------------------------------------- 《一个协议的进化》 http协议的进化过程 ---------------------------------------------------------------------------------------------- 《假装产品经理》 用wireshark分析微博app是怎么上传和下载图片的 1.图片被选定之后就开始上传,而不是等待用户点击发送按钮之后。(用户体验更流畅) 2.微博app会先压缩,在上传图片 3.下载的图片比上传时更小了,说明又经过了一次压缩 ---------------------------------------------------------------------------------------------- 《自学的窍门》 1.浏览权威的百科网站开始,例如维基百科 2.善用搜索引擎:尽量用google;把关键词翻译成英文再搜;不要忽视图片搜索的价值 3.啃一本经典书籍 4.动手操作 ---------------------------------------------------------------------------------------------- 《打造自己的分析工具》 1.用tshark进行分析;tshark官网链接:https://www.wireshark.org/docs/man-pages/tshark.html 2.将分析工具web化 ---------------------------------------------------------------------------------------------- 《一个创业点子》 很多数据中心跨站点的访问存在网络性能瓶颈 1.花钱购买更大的带宽 2.通过传输层(基本都是tcp)的调优来提高带宽利用率(创业点子) 将tcp调优进行程序化 创业点子:在两个站点的出口各自架设1台加速器,代理两个站点之间的所有tcp连接 主要解决2个方面的问题: 1.延迟高,延迟越高,需要等待的时间就越长,这很影响用户体验;解决:在延迟无法减少的情况下,尽量增大窗口。 2.丢包率高: a.网络质量差导致的零星丢包 b.拥塞导致的大量丢包 解决:尽可能第降低丢包几率,比如提前预测并采取措施避免拥塞发生;更精细地处理丢包后的流控,避免过度限流 其他的加速手段 1.启用tcp window scale 2.检测延迟来避免拥塞 3.利用发送窗口实现优先级 4.启用sack 5.改进满启动算法 6.启用tcp timestamps