将tcp_tw_recycle / reuse设置为1有什么影响?


10

我在配置文件中将tcp_tw_recycle / reuse都设置为1。

这样做的后果是什么?

如果重新使用TCP套接字,是否会带来安全风险?即2个不同的连接都可能能够发送数据?

它是否适用于寿命短的连接,并且有重新连接的机会?


显而易见的问题是,您期望从这一变化中获得什么?
罗伯特·蒙提亚努

Answers:


24

默认情况下,当同时禁用tcp_tw_reuse和时tcp_tw_recycle,内核将确保TIME_WAIT处于该状态的套接字将保持足够长的状态-足够长的时间以确保属于将来连接的数据包不会被误认为是旧连接的最新数据包。

启用时tcp_tw_reuseTIME_WAIT可以使用处于状态的套接字在它们到期之前使用,并且内核将尝试确保与TCP序列号没有冲突。如果启用tcp_timestamps(也称为PAWS,用于防止包裹的序列号),它将确保不会发生这些冲突。然而,你需要TCP时间戳上启用两个端(至少,这是我的理解)。有关详细信息,请参见tcp_twsk_unique定义

启用后tcp_tw_recycle,内核将变得更具攻击性,并会假设远程主机使用的时间戳。它将跟踪处于连接TIME_WAIT状态的每个远程主机使用的最后时间戳记,并在时间戳正确增加后允许重新使用套接字。但是,如果主机使用的时间戳更改(即,时间倒退),则SYN数据包将被静默丢弃,并且连接将无法建立(您会看到类似于“连接超时”的错误)。如果您想深入研究内核代码,则tcp_timewait_state_process定义可能是一个很好的起点。

现在,时间戳永远都不能回到过去。除非:

  • 重新启动主机(但是,当它重新启动时,TIME_WAIT套接字可能已经过期,因此这将不是问题);
  • IP地址很快就会被其他东西重用(TIME_WAIT连接会保留一些,但是其他连接可能会被删除TCP RST,从而释放一些空间);
  • 连接中间涉及网络地址转换(或智能裤防火墙)。

在后一种情况下,您可以在同一IP地址后面有多个主机,因此,时间戳的序列不同(或者说,在每个连接处,防火墙都会随机分配这些时间戳)。在这种情况下,某些主机将随机无法连接,因为它们被映射到TIME_WAIT服务器的存储桶具有较新时间戳的端口。这就是为什么文档告诉您“由于设置,NAT设备或负载平衡器可能会开始丢帧”的原因。

有人建议tcp_tw_recycle独自一人,但能tcp_tw_reuse和降低tcp_timewait_len。我同意 :-)


很好的解释
yanglei 2012年

6

我只是被我咬了一口,所以也许有人可能会从我的痛苦和磨难中受益。首先,一个包含大量信息的链接:http : //vincent.bernat.im/zh/blog/2014-tcp-time-wait-state-linux.html

特别是:

缺乏文档的唯一结果是,我们找到了许多调优指南,建议将这两个设置都设置为1,以减少TIME-WAIT状态下的条目数。但是,如tcp(7)手册所述,net.ipv4.tcp_tw_recycle选项对于面向公众的服务器来说是个问题,因为它无法处理来自同一NAT设备后面的两台不同计算机的连接,这是一个很难解决的问题发现并等待咬你:

我曾经成功地启用了这些功能,以提供尽可能低的延迟,从客户端到MySql NDB群集的haproxy连接。这是在私有云中,任何连接到任何连接都没有任何类型的NAT。用例很有道理,可以尽可能地减少通过haproxy攻击Radius客户端到NDB的延迟。它是这样做的。

我在面向公众的haproxy系统上再次进行了此操作,平衡了网络流量,却没有真正研究其影响(愚蠢,对吗?!),并经过大量的故障排除和追捕后发现:

  • 它将为通过NAT连接的客户端造成混乱。
  • 由于它是完全随机的,断断续续的,而且症状会以与客户B完全不同(或没有)的时间击中客户A,这几乎是不可能的。

在客户方面,他们将看到一段时间不再获得对SYN数据包的响应,有时会在这里和那里,有时会很长一段时间。再次,随机。

根据我最近的经历(痛苦的经历),这里的简短故事是,不管角色如何,在面向公众的服务器上将这些设置单独/禁用!


4

从“ man 7 tcp”中,您将看到:

   tcp_tw_recycle (Boolean; default: disabled; since Linux 2.4)
          Enable fast recycling of TIME_WAIT sockets.  Enabling this option is not recommended since this causes problems when working with NAT
          (Network Address Translation).

   tcp_tw_reuse (Boolean; default: disabled; since Linux 2.4.19/2.6)
          Allow  to  reuse  TIME_WAIT  sockets  for  new connections when it is safe from protocol viewpoint.  It should not be changed without
          advice/request of technical experts.

那里没有太多帮助。此举也有一些很好的见解:

/programming/6426253/tcp-tw-reuse-vs-tcp-tw-recycle-which-to-use-or-both

但是没有关于为什么重用比回收更安全的具体信息。基本的答案是,如果TIME_WAIT中已经有一个套接字具有相同的TCP参数,并且处于没有预期进一步通信的状态(我相信在发送FIN后,它将可以使用一个套接字)使用tcp_tw_reuse )。另一方面,tcp_tw_recycle只会使用相同的参数重用TIME_WAIT中的套接字,而不管其状态如何,这可能会使有状态的防火墙(可能期望使用不同的数据包)感到困惑。

通过设置SO_REUSEADDR套接字选项,可以有选择地在代码中完成tcp_tw_reuse,其记录man 7 socket如下:

   SO_REUSEADDR
          Indicates that the rules used in validating addresses supplied in a bind(2) call should allow reuse of local addresses.  For  AF_INET
          sockets  this means that a socket may bind, except when there is an active listening socket bound to the address.  When the listening
          socket is bound to INADDR_ANY with a specific port then it is not possible to bind to this port for any local address.   Argument  is
          an integer boolean flag.

1
您确定SO_REUSEADDR与链接tcp_tw_reuse吗?据我所知,SO_REUSEADDR仅在需要时才适用bind(),而如果需要创建新的传出连接,tcp_tw_reuse它将指示内核重用处于TIME_WAIT状态的本地套接字的端口。
jpetazzo 2012年

不,我不确定。:-P
SpamapS 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.