将tcp_tw_recycle / reuse重新设置为1的后果是什么?

我在我的configuration文件中将tcp_tw_recycle / reuse重新设置为1。

这样做的后果是什么?

如果一个TCP套接字被重新使用,是否构成安全风险? 即两个不同的连接都有可能发送数据?

是否适合短暂的连接与重新连接的机会?

默认情况下,当tcp_tw_reusetcp_tw_recycle都被禁用时,内核将确保处于TIME_WAIT状态的套接字将保持足够长的时间,以确保属于未来连接的数据包不会被误认为旧的连接。

启用tcp_tw_reuse ,可以在TIME_WAIT状态的套接字到期之前使用套接字,内核将尝试确保TCP序列号没有冲突。 如果启用tcp_timestamps (aka PAWS,用于防护tcp_timestamps序列号),它将确保这些碰撞不能发生。 但是,您需要在两端启用TCP时间戳(至less,这是我的理解)。 详见tcp_twsk_unique的定义 。

当启用tcp_tw_recycle ,内核会变得更具攻击性,并会假定远程主机使用的时间戳。 它将跟踪在TIME_WAIT状态下连接的每个远程主机所使用的最后一个时间戳),并且如果时间戳正确增加,则允许重新使用套接字。 但是,如果主机使用的时间戳发生了变化(即及时回退),则SYN数据包将自动丢弃,并且连接不会build立(您将看到类似于“连接超时”的错误)。 如果你想深入内核代码, tcp_timewait_state_process的定义可能是一个很好的起点。

现在,时间戳不应该回到过去; 除非:

  • 主机重新启动(但是,当它恢复时, TIME_WAIT套接字可能已经过期,所以这将是一个非问题)。
  • IP地址很快被其他东西重新使用( TIME_WAIT连接会保留一点,但其他连接可能会被TCP RST触发,这将释放一些空间)。
  • networking地址转换 (或者smarty-pants防火墙)涉及到连接的中间。

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

有人build议单独离开tcp_tw_recycle ,但启用tcp_tw_reuse并降低tcp_timewait_len 。 我同意 :-)

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

尤其是:

这种文档缺乏的结果是,我们发现许多调整指南build议将这两个设置设置为1以减lessTIME-WAIT状态中的条目数量。 但是,正如tcp(7)手册页所述,net.ipv4.tcp_tw_recycle选项对于面向公众的服务器而言是相当成问题的,因为它不会处理来自同一个NAT设备后面的两台不同计算机的连接,这是一个难以解决的问题检测并等待咬你:

我使用了相当成功的方法来提供尽可能低的延迟,从客户端到MySql NDB集群的haproxy连接。 这是在一个私人的云,没有任何连接到任何有任何forms的NAT在组合。 这个用例是有道理的,尽可能的降低半径客户端通过haproxy访问NDB的延迟。 它是这样做的。

我在一个面向公众的haproxy系统上做了一次,负载均衡的networkingstream量,没有真正研究的影响(愚蠢的,对吗?!),并发现许多故障排除和追逐鬼:

  • 这将为通过NAT连接的客户端造成混乱。
  • 这几乎是不可能的,因为它是完全随机的,间歇性的,并且症状会在与顾客B完全不同(或不是)的时间点击顾客A。

在客户端,他们会看到不再接收SYN数据包的时间段,有时甚至是很长时间。 再一次,随机。

在我最近的痛苦经历中,这里的简短故事是将这些单独/禁用的服务器放在公共的服务器上,不pipeangular色如何!

从'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. 

那里没有太多的帮助。 这个问题也有一些很好的见解:

https://stackoverflow.com/questions/6426253/tcp-tw-reuse-vs-tcp-tw-recycle-which-to-use-or-both

但没有具体的信息,为什么重用比回收更安全。 基本的答案是,tcp_tw_reuse将允许一个人使用相同的套接字,如果在TIME_WAIT中已经有一个具有相同的TCP参数,并且处于没有进一步的通信量的状态(我相信当一个FIN被发送)。 另一方面,tcp_tw_recycle将只是重复使用TIME_WAIT中的套接字,而不pipe状态如何,这会混淆可能期望不同数据包的有状态防火墙。

tcp_tw_reuse可以通过设置SO_REUSEADDR套接字选项在代码中select性地完成,如下所示:

  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.