什么可能导致TCP / IP重置(RST)标志不被发送?

时间:2011-09-03 08:07:24

标签: networking tcp ip

我有两个linux服务器(让我们将它们命名为A和B),连接到同一个(非托管)交换机。我在两台服务器上都禁用了防火墙(所有表中都没有规则,所有默认策略都设置为ACCEPT)。因此,没有什么可以阻止一个服务器发送任何TCP / IP数据包和另一个服务器来接收它们。

现在,在A上,我们运行TCP服务器应用程序,它监听/接受传入的连接,然后在循环中将大量数据发送到连接的客户端。它不会尝试从客户端读取,并且如果/当客户端断开连接时,在执行socket()时会发生EPIPE错误。

接下来,在B上我运行nc(netcat)作为客户端应用程序,连接到A上的服务器应用程序,开始接收数据,几秒钟后我按下Ctrl-C来中断此连接。

我看到的是,A上的服务器应用程序只是在write()中挂起,它没有EPIPE或任何其他错误。

我使用tcpdump跟踪了TCP / IP数据包,这就是我所看到的:

  • 在B上中断netcat后,B将FIN发送给A,正确回复了对该FIN的ACK - 所以,现在我们已经公平半开TCP连接,这没关系
  • 接下来,A尝试使用通常的ACK和PSH,ACK数据包向客户端发送下一个数据,这也是预期和正确的
  • 但是,B不会以任何方式回复这些数据包(我希望它能回复RST数据包,因为它接收到已经关闭/不存在的TCP连接的数据包)
  • A没有ACK,所以它停止发送新数据并开始重新发送旧数据包(此时下一次调用write()挂起)

我还尝试在A上运行netcat(因此客户端和服务器应用程序都运行在同一个物理服务器上),这样一切都按预期工作 - 服务器应用程序在我用Ctrl-C中断netcat后立即获得EPIPE。并且tcpdump显示有RST数据包按预期发送。

那么,在这种情况下可能导致不发送RST的原因是什么?

我正在使用Hardened Gentoo Linux,最新的内核2.6.39-hardened-r8,没有任何特定的sysctl网络相关配置。

注意这些服务器上存在重要的网络活动,netstat -alnp随时列出的约5000个tcp连接可能会或可能不重要,我认为大约有1000个连接平均每秒打开和关闭。通常在内核日志中看到这样的东西(但端口号与上面讨论的服务器应用程序使用的不同):

    TCP: Possible SYN flooding on port XXXXX. Sending cookies.
    net_ratelimit: 19 callbacks suppressed

以下是TCP会话通常的样子:http://i54.tinypic.com/1zz10mx.jpg

1 个答案:

答案 0 :(得分:3)

此行为是我的强化内核中启用的功能的结果:

Security options  --->
    Grsecurity  --->
        Network Protections  --->
        [*] TCP/UDP blackhole and LAST_ACK DoS prevention

CONFIG_GRKERNSEC_BLACKHOLE:

如果您在此处说Y,则不会发送TCP重置,也不会发送ICMP目的地不可达数据包以响应发送到没有相关侦听进程的端口的数据包。此功能支持IPV4和IPV6,并免除环回接口的黑名单。启用此功能可使主机对DoS攻击更具弹性,并降低网络对扫描仪的可见性。实现的黑洞功能相当于FreeBSD黑洞功能,因为它可以阻止RST对所有数据包的响应,而不仅仅是SYN。