2011-09-03 207 views
6

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

现在,在一个我们运行TCP服务器应用程序,这听/接受传入的连接,然后发送大量的数据要在环连接的客户端(S)。它不会尝试从客户端读取数据,并且在客户端断开连接时执行write()套接字操作时会出现EPIPE错误。

接着,在B I运行NC(netcat的)作为客户端应用程序,连接到上的一个服务器应用程序,开始接收数据,和几秒钟后我按下Ctrl-C中断这个连接。

我看到的,是服务器应用上的一个刚刚在写()挂起,它并没有得到EPIPE或其他任何错误。

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

  • 中断第B的netcat后,B发送一个翅片到,它正确地ACK回复该FIN - 所以,现在我们要公平半开TCP连接,这是确定
  • 接下来,尝试下一个数据发送到客户端与常规ACK和PSH,ACK数据包,这也有望和正确
  • BUT,B没有按不会以任何方式回复这些数据包(虽然我期望它回复RST数据包,因为它将数据包接收到已经关闭/不存在的TCP连接)
  • A没有得到ACK,所以它停止发送新数据,并开始重新发送数据包老(在这一点上一次调用write()方法挂起)

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

那么,什么可能会导致在此情况下,不发送RST?

我使用硬化的Gentoo Linux,跟上时代的,内核2.6.39硬化-R8,没有任何特定的sysctl网络相关的配置。

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

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

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

+0

从对其他网站的讨论:** 1)**的netcat后退出了netstat不会再列出它连接上服务器B(虽然我认为它应该在FIN_WAIT_2状态中列出),在服务器A上的netstat仍然显示此按照预期,处于CLOSE_WAIT状态的连接; ** 2)**有人认为这可能是因为SO_LINGER而发生的,但我不同意,因为netcat不会手动激活SO_LINGER并在exit()之前执行close(),因此不应该自动激活,并且SO_LINGER不应该影响ACK/RST无论如何都会对_incoming_包进行回复。 – Powerman

+0

看起来像旧内核(2.6.28-hardened-r9)按预期工作 - 发送RST数据包。 – Powerman

回答

3

此行为是结果启用功能在我硬化内核:

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

CONFIG_GRKERNSEC_BLACKHOLE:

如果你比如Y在这里,无论是TCP资源ets也不会发送ICMP目标不可达数据包以响应发送到不存在关联侦听进程的端口的数据包。此功能同时支持IPV4和IPV6,并免除了blackholing的环回接口。启用此功能可使主机更容易抵御DoS攻击,并降低扫描器的网络可见性。实现的黑洞功能等同于FreeBSD的黑洞功能,因为它阻止RST响应所有数据包,而不仅仅是SYN。

相关问题