149  
查询码:00000832
linux之tcp_tw_recycle系统参数引发的故障
作者: 盖杰 于 2020年10月16日 发布在分类 / 物联网组 / 边缘接入网关 下,并于 2020年10月16日 编辑
采坑

1. 问题背景

    前段时间为了优化内网穿透工具,修改了云服务器的tcp_tw_recycle参数,该参数默认是0(关闭),将其改为了1(打开)。接着就发生了诡异的事情。

在公司内网、阿里云服务器上可以正常访问该云主机,而从腾讯云服务器上却无法访问该云主机。

通过抓包工具得知, 确定有收到syn包,但被拒绝。同时,发现只有客户端带时间戳的包才会被拒绝,而关闭客户端时间戳,问题恢复。这就解释了为什么只有部分用户有问题,其他用户正常

2. 问题定位

    通过参考网上的资料,定位到原因是开启了tcp_tw_recycle

    tcp_tw_recycle
    Enable fast recycling of TIME-WAIT sockets. Enabling this option is not recommended since this causes
    problems when working with NAT (Network Address Translation).

    启用TIME-WAIT状态sockets的快速回收,这个选项不推荐启用。在NAT(Network Address Translation)网络下,会导致大量的TCP连接建立错误。

下面我们来具体说下,首先解释下TCP的TIME_WAIT状态:

  • 通信双方建立TCP连接后,主动关闭连接的一方就会进入TIME_WAIT状态。
  • 比如,客户端主动关闭连接时,会发送最后一个ack后,然后会进入TIME_WAIT状态,再停留2个MSL时间(后有MSL的解释),进入CLOSED状态。
  • TIME_WAIT状态的作用是为了保证连接正常关闭,且不影响其他新建的链接。
    这里写图片描述

开启net.ipv4.tcp_tw_recycle的目的,就是希望能够加快TIME_WAIT状态的回收,当然这个选项的生效也依赖于net.ipv4.tcp_timestamps的开启(缺省就是开启的)。

当开启了tcp_tw_recycle选项后,当连接进入TIME_WAIT状态后,会记录对应远端主机最后到达分节的时间戳。如果同样的主机有新的分节到达,且时间戳小于之前记录的时间戳,即视为无效,相应的数据包会被丢弃

3. 问题解决

解决办法是Linux内核引入 tcp_tw_timeout 开关,该开关可以动态设置TIME_WAIT 时间,加速回收TIME_WAIT 状态,从而可以关闭tcp_tw_recycle ,避免上述问题。

参考文献

http://blog.csdn.net/jueshengtianya/article/details/52130667 TCP服务端收到syn但是不回复syn ack问题分析

http://elf8848.iteye.com/blog/1739571 TCP/IP TIME_WAIT状态原理

http://dngood.blog.51cto.com/446195/988968/ 转:记一次TIME_WAIT网络故障

http://blog.csdn.net/wireless_tech/article/details/6405755 【经验总结】tcp_tw_recycle参数引发的故障






 推荐知识

 历史版本

修改日期 修改人 备注
2020-10-16 16:24:22[当前版本] 盖杰 linux

 附件

附件类型

GIFGIF

知识分享平台 -V 4.8.7 -wcp