2

研究nginx : ignore some requests without proper Host headerclose(2)让我想到如果操作系统通过向另一端发送RST(and/or ) 正确终止底层 TCP 连接,实际上不可能建立 TCP 连接FIN

一种解决方法是使用类似的东西,但是,从OpenBSDFreeBSDtcpdrop(8)可以看出,它是通过基于 sysctl 的接口实现的,并且可能在 BSD 之外存在可移植性问题。(事实上​​,看起来即使是基于 sysctl 的实现在 OpenBSD 和 FreeBSD 之间也可能有很大的不同,需要一个移植层——OpenBSD 使用该结构(随后,它包含两个元素,加上一些其他信息),而FreeBSDDragonFlyNetBSD直接使用两个元素的数组usr.sbin/tcpdrop/tcpdrop.ctcp_ident_mappingsockaddr_storagesockaddr_storage。) 事实证明,OpenBSDtcpdrop似乎确实R按照tcpdump(8), 并且可以通过查看最终/sys/netinet/tcp_subr.c :: tcp_drop()调用tcp_close()的 , 来确认(并确认在 SOtcp_close() 上发送RST到其他地方),因此,它似乎也不起作用。

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

4

2 回答 2

1

以这种方式欺骗攻击者可能是个好主意。当然,在这种情况下,您已经为已建立的连接保留了服务器资源。在最基本的模式下,您可以使用 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 函数挂起,尽管 KEEPALIVE我提供了测试结果,其中对方不返回任何 TCP 段(甚至没有 ACK)。在我的配置中,socket 需要 13 分钟才能进入错误状态(这取决于 tcp_retries1 和 tcp_retries2 等 Linux 参数)。

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

于 2017-09-19T14:02:38.410 回答
1

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

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

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

于 2017-09-11T02:14:50.867 回答