又遇TCP协议栈异常问题
作者:易隐者 发布于:2013-10-29 16:47 Tuesday 分类:案例讨论
大家还记得我以前写的《TCP确认机制异常案例》(链接为:http://www.vants.org/?post=200)吗?今天在一个用户那边再次遇到了一个TCP协议栈异常的问题。
用户反馈的问题现象是业务交互出现异常,难以定位异常出现的原因,我在用户现场分析了异常出现时的报文交互情况,如下图所示:
由F5设备主动向服务器发送SYN连接请求报文,服务器响应SYN/ACK报文,F5发送ACK报文确认后,向服务器连续发送3个大小分别为1514、1514、350大小的应用请求报文,但是1.199秒之后,F5重传了应用请求的第一个报文(该报文序列号为No7,该数据报其实是序号为No4的报文的重传),紧接着,2秒后,看到服务器的SYN/ACK的重传报文(该报文序列号为No8,该报文为No2报文的重传报文),后面数十秒的交互,基本是都是F5对应用请求报文的重传和服务器SYN/ACK报文的重传,在40秒之后,由F5主动发送RST报文释放该TCP连接。
由整个交互的过程,我们可以清晰的看到,服务器不断重传SYN/ACK报文,说明服务器没有正常处理F5的ACK报文(序列号为No3的报文),站在F5的角度,TCP连接已经建立成功,但是站在服务器的角度,却认为TCP连接未建立完成,因此服务器不断重传SYN/ACK报文,为什么服务器在明确收到了F5的三次握手的ACK报文,却没有正确处理呢?而且后续F5重传的应用请求报文(No7、No10、No11、No14、No17)都可以说是对服务器SYN/ACK报文的确认,但是服务器全部忽略了,因此,这基本上可以判断为服务器端系统的TCP协议栈出现异常,导致了应用出现了异常。
标签: TCP F5 应用故障 SYN 重传 TCP协议栈 应用异常
服务器经网关地址映射访问时的注意事项
作者:易隐者 发布于:2013-6-20 22:05 Thursday 分类:网络分析
有朋友在用户现场遇到一个故障无法定位,网上找我帮忙,大概情况是某内网用户将一台服务器端口映射出去供互联网访问,内部主机通过互联网地址进行访问测试时,发现无法正常连接。我让其在服务器区域前端防火墙上抓客户端与服务器交互的报文,如下:
10:33:28.747771 R@eth3 IP 172.16.7.68.8525 > 172.16.2.146.3389: S 3134287530:3134287530(0) win 58400 <mss 1460,nop,wscale 0,nop,nop,sackOK>
//客户端发起SYN请求
10:33:28.747786 X@eth4 IP 172.16.7.68.8525 > 172.16.2.146.3389: S 3134287530:313
4287530(0) win 58400 <mss 1460,nop,wscale 0,nop,nop,sackOK>
//防火墙内口转发客户端的SYN请求
10:33:28.748165 R@eth4 IP 172.16.2.146.3389 > 172.16.7.68.8525: S 3568427973:356
8427973(0) ack 3134287531 win 16384 <mss 1460,nop,wscale 0,nop,nop,sackOK>
//服务器响应客户端的SYN报文
g10:33:28.748172 X@eth3 IP 172.16.2.146.3389 > 172.16.7.68.8525: S 3568427973:356
8427973(0) ack 3134287531 win 16384 <mss 1460,nop,wscale 0,nop,nop,sackOK>
//防火墙转发服务器响应报文
10:33:28.749519 R@eth3 IP 172.16.7.68.8525 > 172.16.2.146.3389: R 3134287531:313
4287531(0) win 0
10:33:28.749523 X@eth4 IP 172.16.7.68.8525 > 172.16.2.146.3389: R 3134287531:313
4287531(0) win 0
//客户端发送RST报文
客户端发起SYN连接请求,防火墙转发,服务器响应SYN/ACK报文,这个过程都是正常的,但是紧接着却是客户端发送RST报文,异常释放了这个TCP连接。单从这个数据包交互的过程来看,大部分的人都会认为是客户端的问题。
但是其实跟客户端完全无关。我很早以前在天融信做工程师时曾今在用户 处遇到过同类型的问题,当时解决完之后曾打算将其作为一个经典案例写下来供大家分享,后来由于时间问题,拖时间长了,原始报文找不到了,只能作罢,今天就 这个案例,我来做一个简单的分析和说明,以供大家参考。
我们在用户现场经常会遇到这样的客户需求:
1,用户希望通过通过防火墙等设备的端口映射/地址映射功能实现内网服务器对互联网访问者提供服务的需求;2,为了使用方便,用户一般都会同时要求内部客户端也可以直接通过服务器映射后的互联网地址进行访问。
第一点需求非常容易实现,在防火墙上做一个常规的地址映射/端口映射,再将服务器对外提供服务的端口放行即可。但是在实现用户第二点需求时,我们需要注意一个关键的问题,那就是客户端与服务器端的报文来回路径不一致问题。
我们先将故障发生时的报文交互过程跟大家一起分析一下,其交互过程大致如下图所示:这个交互的过程具体描述如下:
1) 客户端访问经网关设备映射出去的服务器的互联网地址,向其发送SYN报文;
2) 客户端访问的目的地址经网关转换为内网服务器真实地址之后,转发至内网服务器,此时报文的源IP地址是真实的内网地址(另外一种处理情况为出口网关将该报 文经NAT后至转发出互联网接口,然后再匹配识别为内网服务器的映射的策略,再次将该报文转发至内网服务器,此时报文的原IP、目的IP地址均发生变化 了,此种情况下由于报文原IP地址已经改变为NAT后的互联网地址,因此不在我们的讨论的范畴之内,这个跟网关设备对数据报文处理的流程有关,在此不详细 讨论,有兴趣的同学可仔细思考思考。);
3) 内网服务器在接受到这个报文之后,直接向客户端内网IP发送SYN/ACK报文;
4) 内网客户端接收到服务器的SYN/ACK报文,但是客户端的TCP连接表中并没有与之相应的信息(因为客户端是与服务器映射后的互联网地址发送SYN请求报文的),因此,客户端向服务器发送RST报文。
5) 服务器端收到这个RST报文之后,其会将这个TCP连接释放,因此客户端连接服务器失败。
那么,在这种情况下,我们如何解决这个问题呢?其实,解决的方式就是在网关处增加一条源地址转换策略,将访问服务器的客户端地址转换为一个互联网地址或网关内部接口地址,如此巧妙的让服务器回包给网关(防火墙),从而保证客户端、服务器的报文来回路径一致。
NAT在很多复杂环境下的确能够帮助我们巧妙的解决很多令人头疼的问题,我在博客文章《某公司业务系统经ISA防火墙访问正常而经硬件防火墙访问慢故障分析解决案例》中曾今在文章后面留下一个思考问题,至今无人应答,我也没给出答案,其实答案就是NAT。有兴趣的兄弟自行去查看那篇文章吧,在此我不做展开了,当然NAT也可能会带来一些意想不到的问题,以前遇到过一个案例,等我有空的时候再整理发布吧。
这个用户现场案例,我们通过在防火墙中增加一条源地址转化策略之后,再次以互联网地址访问服务器,正常,数据包交互如下:
10:37:54.637923 R@eth3 IP 172.16.5.253.9182 > 172.16.2.146.3389: S 223750126:223750126(0) win 58400 <mss 1460,nop,wscale 0,nop,nop,sackOK>
10:37:54.637943 X@eth4 IP 172.16.5.253.9182 > 172.16.2.146.3389: S 223750126:223
750126(0) win 58400 <mss 1460,nop,wscale 0,nop,nop,sackOK>
//客户端发起SYN报文
10:37:54.638373 R@eth4 IP 172.16.2.146.3389 > 172.16.5.253.9182: S 892121112:892
121112(0) ack 223750127 win 16384 <mss 1460,nop,wscale 0,nop,nop,sackOK>
10:37:54.638379 X@eth3 IP 172.16.2.146.3389 > 172.16.5.253.9182: S 892121112:892
121112(0) ack 223750127 win 16384 <mss 1460,nop,wscale 0,nop,nop,sackOK>
//服务器响应SYN报文
10:37:54.639048 R@eth3 IP 172.16.5.253.9182 > 172.16.2.146.3389: . ack 1 win 584
00
10:37:54.639052 X@eth4 IP 172.16.5.253.9182 > 172.16.2.146.3389: . ack 1 win 584
00
//客户端确认,连接建立
标签: TCP RST SYN 防火墙 NAT 地址转换 网关 来回路径不一致 映射
TCP Fast Open(TFO)
作者:易隐者 发布于:2013-1-10 15:22 Thursday 分类:网络分析
【说在之前】:
我在之前的博客文章《非标准TCP三次握手建立连接过程一例》一文中提到了非标准的TCP三次握手行为,今天在微博上看到有人转发有关TCP Fast Open(TFO)的文章,大致看了一下,了解到所谓的TCP Fast Open(TFO)就是利用三次握手的SYN报文来传输应用数据,也就是说,允许SYN报文中包含应用数据。这样做的好处是在客户端与服务器的交互过程中减少一个RTT来提高交互的效率,如此来看,TCP Fast Open(TFO)就是一个最为典型的非标准TCP行为,但是这种非标准的TCP行为由于其特性优势使其将成为国际标准,其具体的交互过程和原理大家可参考下面的文章和相关链接。
【原文链接】:
http://blog.sina.com.cn/s/blog_583f42f101011veh.html
【原文全文】:
Google近日正式公布了TFO的paper,地址:http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/zh-CN/us/pubs/archive/37517.pdf
Google研究发现TCP三次握手是页面延迟时间的重要组成部分,所以他们提出了TFO:在TCP握手期间交换数据,这样可以减少一次RTT。根据测试数据,TFO可以减少15%的HTTP传输延迟,全页面的下载时间平均节省10%,最高可达40%。
目前互联网上页面平均大小为300KB,单个object平均大小及中值大小分别为7.3KB及2.4KB。所以在这种情况下,多一次RTT无疑会造成很大延迟。
在HTTP/1.1中,我们有了keep-alive。但实际应用并不理想,根据Google对一个大型CDN网络的统计,平均每次建连只处理了2.4个请求。
为了证实TCP三次握手是目前页面访问的重要性能瓶颈之一,Google工程师分析了Google的web服务器日志及Chrome浏览器统计数据。
2011年6月,对Google web服务器进行连续7天数十亿次针对80端口的请求分析,包括搜索、Gmail、图片等多个服务。其中第一次建连被称为cold requests,复用连接的请求称为warm requests。
图中描述了在cold requests及all requests中TCP握手时间在整个延迟时间中的占比。在cold requests中,TCP握手时间占延迟时间的8%-28%;即使统计所有的请求,TCP握手时间也占到了延迟时间的5%-7%。
对Chrome浏览器的统计持续了28天,当然仅限于愿意发送统计数据的用户。经过分析,即使打开了keep-alive,仍有33%的请求建立了新连接。主要原因可能为:为了加快下载速度,新版的浏览器对单个域名都会并行打开6-10个连接;而网页设计时也会把元素分配到多个域名上;NAT也可能关闭keep-alive;而手机端为了节省电源,也会尽快关闭空闲连接。
图中对比了三条线,一条为all requests;一条为cold request;而cold req no hsk代表去除了TCP握手时间的cold requests延迟数据。Y轴把所有采样数据按数值分布到各个百分比区间。
对比证明:cold requests基本比all requests慢50%,而TCP握手时间在cold requests延迟时间中往往占比了25%。
下面这幅图清楚的说明了TFO的设计:
1、用户向服务器发送SYN包并请求TFO cookie;
2、服务器根据用户的IP加密生成cookie,随SYN-ACK发给用户;
3、用户缓存住TFO cookie。
再次访问时:
1、用户向服务器发送SYN包并携带TCP cookie,同时请求实体数据;
2、服务器校验cookie。如果合法,向用户发送SYN+ACK,在用户回复ACK之前,便可以向用户传输数据;如果cookie校验失败,则丢弃此TFO请求,视为一次普通SYN,完成正常的三次握手。
因为用户使用DHCP,IP地址会改变;同时也为了防止攻击,服务器端会定期变换cookie。
建立了TFO连接而又没有完成TCP建连的请求在服务器端被称为pending TFO connection,当pending的连接超过上限值,服务器会关闭TFO,后续的请求会按正常的三次握手处理。
而一个带有TFO的SYN请求如果在一段时间内没有收到回应,用户会重新发送一个标准的SYN请求,不带任何其他数据。
在集群环境中,所有服务器会使用相同的key。
目前TFO被植入了Linux 2.6.34内核。
为了验证TFO的作用,Google分别测试了全页面的下载时间及开启TFO对服务器性能的影响。平均来看,页面一般会包含44个元素,分布在7个域名中。同时浏览器会支持并行下载。抽样的测试对象为:亚马逊、纽约时报、华尔街日报和维基百科。可以看到RTT时间越大,TFO的效果越明显。当RTT为200ms时,改善达到了11%-41%。这对移动互联网尤其意义重大。
那么TFO对服务器性能是否有影响呢?可以直观看出,完全没有,甚至在某些连接数区间,性能还有改善。
网页访问的一步步优化看起来都是ms级别的,但对于大型网站来说,无形中影响的可能就是PV、用户满意度及收入。
【相关链接】:
http://www.pagefault.info/?p=282
http://blog.solrex.org/articles/tcp-fast-open-by-google.html
http://tools.ietf.org/html/draft-cheng-tcpm-fastopen-01
标签: TCP SYN 非标准TCP cookie RTT TCP Fast Open TFO
TCP确认机制异常案例
作者:易隐者 发布于:2012-12-8 15:06 Saturday 分类:案例讨论
缘起
一个好友通过Sina微博转发了一个兄弟的问题给我,其问题如下:
“AB机器tcp,A发送100字节给B,B返回数据但是其ACK=1,这期间A均正确ACK B的所有序列号,B置FIN位,A发 FIN+ACK 给B,此后B返回的ACK=2,那么此时A是应该重传之前的99字节,还是直接重传之前的FIN+ACK包给B?”。
通过这样的描述我认为这在实际环境中应该不会存在,结果这个兄弟告诉我是在实际环境中发生的,并将交互的报文传一份给我。
好奇之余,对这个报文进行了仔细的分析,接下来跟我一起来看一下整个分析的过程。
分析产生这个交互的原因
选取其中一个TCP会话,查看其具体的报文交互情况,如下图所示:
这个报文交互的情况截图结合下面的TCP交互流图一起,看起来更清晰一些:
通过交互报文的解码,我们可以清晰的看到,服务器192.168.104.229已经对客户端发送的get请求作出了应用层的响应,如下图所示:
其响应为:HTTP/1.0 403 Forbdden
但是其ACK号却为1,接收并处理了客户端的应用请求报文,但却并未对其进行确认,这充分证明服务器192.168.114.229的TCP确认机制出现了异常!
我们再来一起看看客户端主动发送FIN报文之后的交互情况:
客户端在发送FIN报文之后,服务器的ACK号变为2,这对于客户端来说,这是对其应用字段的确认,这说明服务器端仅收到客户端1字节的应用字段,因此客户端将剩下的303字节的应用字段放在FIN报文中一起发给服务器端,而服务器在收到这个报文后,回应客户端的ACK号变为3,客户端接着将剩下的302字节的应用字段放在FIN报文中再次重传给服务器端,如此反复。
至此,我们已经能够意识到,服务器端的ACK确认并不是针对客户端的应用字段的,而是针对客户端的FIN报文的,服务器的确认机制出现了异常,服务器不再确认客户端的应用字段,而只确认客户端的SYN报文和FIN报文。
分析结论
此问题产生的原因为:服务器的TCP确认机制出现异常,其只确认SYN报文和FIN报文而不对应用数据进行确认。
另外,我们还留意到一个有意思的现象:正常情况下,端系统一般都会在发送的数据段获得对端确认之后,才会主动发送FIN报文,释放TCP连接,如果在多次重传之后仍未得到对端的确认,通常会向对端发送RST报文,异常释放TCP连接,但是此处可能为了提高交互的效率,客户端与服务器在发送的数据段未收到对端的确认报文就主动发送FIN报文释放TCP连接。
网页打开慢但HTTP下载快故障分析案例
作者:易隐者 发布于:2012-10-10 16:06 Wednesday 分类:网络分析
【说在之前】:
1,用到了疑难杂症网络分析过程中最基本、最核心的两个分析方法:对比分析法和关联分析法;
2,该案例涉及到的知识点主要有SYN重传、连接数限制等,大家可参考本博客中相关知识点的文章。
【我的案例】:
故障环境
某单位大体的网络结构如下图所示:
内部办公人员通过交换机到流控设备,再通过防火墙做NAT访问互联网。
故障现象
1,在地矿局进行互联网时,打开网页的速度非常的慢,有的网页要刷新几次才可以正常显示;
2,但是使用下载工具或是基于HTTP的下载速度却很快。
故障分析
1 确认故障原因
我们找一台主机,访问互联网的某网站,发现的确比较慢,我们抓取故障时的交互数据包,如下图所示:
通过上图,我们可以发现,客户端在与服务器建立TCP连接时,其SYN请求报文被客户端重传了一次,这个重传导致了2.88秒的延时。TCP重传一般是中间设备丢包导致的,那么到底是在什么地方丢包的呢?我们首先需要界定一下可能丢包的故障关键点。
2 选择故障关键点
该故障环境相对简单,在办公用户访问互联网时,数据包只通过了交换机、流控设备和防火墙,而交换机主要负责转发数据,不会对数据包进行深度的检测和过滤等操作,所以在该环境下主要的关键故障点是流控设备和防火墙,如下图所示:
3分析流控设备是否丢包
关键故障点确定之后,我们首先在流控设备的前后同时抓包做对比分析,以确定是否是流控设备丢包,如下图所示:
通过我们还原故障现象时,在流控设备前后抓取数据包的对比分析,结论显示,流控设备前后数据包交互的过程是一样的(这个对比分析通过五元组关联同一会话之后,对比查看数据交互过程的差异即可,由于流控设备前后的数据交互过程完全一样,在此不做具体详细的分析说明),这说明,在打开页面较慢时,流控设备并未丢弃任何交互的数据报文。
4 分析防火墙是否丢包
同样,我们再在防火墙的进出口同时抓包,通过比较防火墙前后数据包的交互情况来确定造成故障的原因,部署图如下所示:
1, 在访问某网站出现缓慢现象时,在防火墙前后同时抓取数据包,并保存,为下面的对比分析提供原始的数据报文。
2,我们先分析防火墙内网口抓取的数据,在科来网络分析系统的“TCP会话”视图,我们发现了一个web连接持续的时间为6秒,并且其在三次握手过程中,存在重传现象,如下图所示:
这个TCP会话的源端口是1124,目的地址为58.30.236.11,目的端口是80
3,我们通过关联分析法,在进行网页访问时,我们在防火墙前后同时进行抓包,下图就是在防火墙出口处抓取到的数据包:
我们知道防火墙在网络运行中起到防护作用,会将未经授权的报文过滤,但是防火墙一般不会阻止正常的数据包,我们在比较上面两张图发现,在防火墙后捕获到的数据包第一次发送同步请求没有成功,然后又重传了一次同步数据包,才成功建立了连接;而在防火墙前面抓取到的数据包却没有看到重传的数据包(黑框标记的部分),这很清晰的说明,第一个SYN报文被防火墙丢弃了。
4 分析结论
通过上面的分析,我们可以得出如下结论:
由于防火墙在转发数据包时,随机丢弃了客户端发送的SYN报文而造成的。可能是防火墙配置不当(连接数限制)或防火墙BUG(在处理TCP新建连接时不稳定)导致的。
总结
经过分析知道是由于防火墙不规律丢弃SYN报文导致的网页打开慢现象,但是为什么HTTP下载的速度却很快?这是因为防火墙仅随机丢弃SYN报文,而HTTP下载在刚开始建立TCP连接时,防火墙有可能会丢弃其SYN报文,但是下载行为决定其会不断发起SYN报文进行连接建立的尝试,而一旦连接建立成功,则防火墙不会丢包,给用户的感觉就是速度也非常快。
日历
最新日志
链接
分类
最新碎语
- 如果一个人想要做一件真正忠于自己内心的事情,那么往往只能一个人独自去做"——理查德·耶茨
2019-06-25 21:34
- 日后我们知道,真正的人生道路是由内心决定的。不论我们的道路看上去如此曲折、如此荒谬地背离我们的愿望,它终归还是把我们引到我们看不见的目的地。(茨威格《昨日世界》)
2019-03-16 21:27
- 如果你渴望得到某样东西,你得让它自由,如果它回到你身边,它就是属于你的,如果它不会回来,你就从未拥有过它。——大仲马《基督山伯爵》
2018-10-09 22:07
- 人生有两大悲剧:一个是没有得到你心爱的东西;另一个是得到了你心爱的东西。人生有两大快乐:一个是没有得到你心爱的东西,于是可以寻求和创造;另一个是得到了你心爱的东西,于是可以去品味和体验。——弗洛伊德
2018-09-25 18:06
- 一个人越有思想,发现有个性的人就越多。普通人是看不出人与人之间的差别的——布莱兹·帕斯卡尔
2018-08-30 18:44
存档
- 2020年11月(2)
- 2018年1月(1)
- 2017年12月(1)
- 2017年11月(6)
- 2017年6月(1)
- 2017年5月(1)
- 2017年4月(1)
- 2017年3月(1)
- 2016年11月(1)
- 2016年4月(1)
- 2015年7月(2)
- 2015年6月(1)
- 2015年5月(5)
- 2014年12月(1)
- 2014年11月(1)
- 2014年10月(1)
- 2014年8月(1)
- 2014年7月(1)
- 2014年6月(1)
- 2014年5月(1)
- 2014年4月(3)
- 2014年2月(2)
- 2014年1月(2)
- 2013年12月(1)
- 2013年11月(1)
- 2013年10月(2)
- 2013年9月(1)
- 2013年8月(1)
- 2013年7月(3)
- 2013年6月(2)
- 2013年5月(1)
- 2013年4月(3)
- 2013年3月(1)
- 2013年2月(2)
- 2013年1月(2)
- 2012年12月(11)
- 2012年11月(12)
- 2012年10月(12)
- 2012年9月(26)
- 2012年8月(29)
- 2012年7月(18)
- 2012年6月(2)
- 2012年5月(25)
- 2012年4月(16)
- 2012年3月(13)
- 2012年2月(6)