【问题标题】:Drop an open TCP connection without sending RST丢弃打开的 TCP 连接而不发送 RST
【发布时间】:2018-02-19 04:22:34
【问题描述】:

查看nginx: ignore some requests without proper Host header 让我想到,如果操作系统通过向另一端发送RST(和/或FIN)正确终止底层TCP 连接,实际上不可能close(2) TCP 连接.

一种解决方法是使用tcpdrop(8) 之类的东西,但是,从usr.sbin/tcpdrop/tcpdrop.c on OpenBSDFreeBSD 可以看出,它是通过基于 sysctl 的接口实现的,并且可能在 BSD 之外存在可移植性问题. (事实上​​,OpenBSD 和 FreeBSD 之间甚至基于 sysctl 的实现看起来也可能有很大的不同,需要一个移植层——OpenBSD uses tcp_ident_mapping 结构(随后,它包含两个 sockaddr_storage 元素,加上一些其他信息),而 FreeBSDDragonFlyNetBSD 直接使用由两个 sockaddr_storage 元素组成的数组。) 事实证明,OpenBSD 的 tcpdrop 似乎确实发送了 R 数据包根据tcpdump(8),可以通过查看/sys/netinet/tcp_subr.c :: tcp_drop()来确认,它最后调用tcp_close()(和tcp_close()is confirmed to send RST elsewhere on SO),所以,它似乎也不起作用。

如果我自己通过 C 建立连接,有没有办法在不确认对方的情况下随后将其丢弃,例如,不启动 RST

【问题讨论】:

  • 这样做有什么意义?顺便说一句,您链接的工具实际上是一种以管理方式关闭连接的方法。它确实发送通知。
  • @spectras 的重点是让连接挂在另一端(例如,浪费攻击者的资源)
  • > 连接也将挂在您的所有网络设备上。正确发送关闭通知可以让您的路由器和防火墙将连接置于快速老化的线路上,从而释放其表中的宝贵条目。假设攻击者拥有比您更多的设备,那么您实际上给您的基础设施施加的压力比他们的更大(更准确地说,压力分散在他们这边)。
  • 感谢labrea.sourceforge.net/labrea-info.html 链接(无论是谁删除了自己的消息);基本上,是的,但我没有任何未使用的 IP 地址可以完全专用于此;正在寻找编写 nginx 模块或补丁。附言不幸的是,该页面上 CVS 网站的链接似乎已损坏,知道代码在哪里吗?
  • @spectras 不正确;唯一的状态防火墙是在终止连接的机器上,所以,这里的整个想法是完全断开连接而不发送任何数据包。

标签: c sockets tcp network-programming tcp-rst


【解决方案1】:

如果我自己通过 C 建立连接,有没有办法在不确认对方的情况下(例如,不启动 RST)随后将其丢弃?

没有。即使有,如果对等方随后发送任何内容,它也会由 RST 回复。

NB 正常 TCP 终止使用 FIN,而不是 RST。

【讨论】:

  • 这个想法是浪费攻击者的资源;另外,我认为是否完全确认没有正确建立状态的通信取决于防火墙设置。
  • @cnst 当然这取决于防火墙,但是您的问题是关于已建立的连接,因此已经穿透了防火墙。如果您现在只是询问防火墙规则,(a)您已经完全改变了问题并且(b)您偏离了主题。浪费攻击者资源而不消耗您自己的资源的最佳方法是首先不允许连接,让防火墙丢弃所有内容。
  • 不,问题是一样的——防火墙在内核中运行;我想删除连接,这将完全从内核中删除它,包括从防火墙中删除,而不发送任何 RST;如果客户端尝试通过同一个连接再次通信,就好像连接从未建立,因此,防火墙根本不会发回任何东西;同样的问题,与防火墙规则无关。
【解决方案2】:

以这种方式欺骗攻击者可能是个好主意。当然,在这种情况下,您已经为已建立的连接保留了服务器资源。在最基本的模式下,您可以使用 netfilter 删除任何设置了 RST 或 FIN 标志的 TCP 传出段。这条规则 iptables 规则可以是一个例子:

sudo iptables -A OUTPUT -p tcp --tcp-flags FIN,RST SYN -j DROP

当然,这条规则会影响你所有的 TCP 连接。我写它只是为了提供一个指导你如何做到这一点。转到https://www.netfilter.org/ 以获得更多关于您的解决方案的想法。基本上你应该能够只对选定的连接做同样的事情。

由于 TCP 的工作原理,如果您能够实现它,客户端(或攻击者)将长时间保持连接打开。要了解它在客户端中的影响,请阅读此处:TCP, recv function hanging despite KEEPALIVE,我在其中提供了测试结果,其中对方不返回任何 TCP 段(甚至不返回 ACK)。在我的配置中,套接字进入错误状态需要 13 分钟(这取决于 tcp_retries1 和 tcp_retries2 等 Linux 参数)。

仅考虑 DoS 攻击通常意味着来自数千个不同设备的连接,而不一定是来自同一设备的许多连接。这很容易在防火墙中检测和阻止。因此,您不太可能在客户端中产生资源耗尽。此外,此解决方案不适用于半开连接攻击的情况。

【讨论】:

  • 这个解决方案不仅完全不完整,甚至是特定于 Linux 的,而且如果这只是在防火墙级别完成,没有适当地终止网络服务器期望通过多包 @987654324 终止的连接@ 序列(例如,没有将RST 插入回本地服务器,或类似的),那么这将有效地导致您自己的网络服务器的 DoS。
  • @cnst 这个想法是网络服务器正在关闭它的连接。但是带有 FIN 和 RST 的 TCP 段不会到达客户端。你说的是服务器套接字将永远等待FIN / ACK?是的,iptables 和 netfilter 是特定于 Linux 的。为什么您认为回复不完整?
猜你喜欢
  • 2010-10-21
  • 2017-11-11
  • 1970-01-01
  • 2018-08-29
  • 2019-04-04
  • 2021-12-22
  • 1970-01-01
  • 2012-10-14
相关资源
最近更新 更多