如何使用 linux netfilter/iptables 在特定条件下立即重置两端的 tcp 连接?

如何使用 linux netfilter/iptables 在特定条件下立即重置两端的 tcp 连接?

亲爱的 Serverfault 社区,

我遇到了以下问题:如果在数据包数据中遇到某个字符串,我需要立即重置(断开)网络两端的 tcp 连接。我无法控制两端的应用程序,只能使用 linux iptables(或类似工具)来中止连接。

我的第一个想法是使用以下 iptables 规则来实现我想要的效果:

/usr/sbin/iptables -A INPUT -p tcp --dport 1234 -m string --algo bm --string 'BAD STRING' -j REJECT --reject-with tcp-reset

远程端可以通过向客户端发送 TCP RST 数据包完美地实现此操作,因此客户端将立即断开连接。不幸的是,本地端不会在强制断开连接时收到通知,服务器进程(连接)将永远挂起。

我认为在特定条件下(本例中为 IP 数据包中的字符串匹配)立即断开双方已建立的连接的要求并不罕见。因此我进行了 Google 搜索,但令我惊讶的是,在合理的时间内找不到任何可用的内容。

有没有办法使用 iptables 在网络两端实现 TCP 断开连接?如果没有,我可以使用哪些其他工具(请记住,我无法控制客户端/服务器应用程序)?

非常感谢您提前提供的宝贵答案!

此致,

延斯

答案1

您可以使用重置例如,-j RESET

答案2

您可以配置您的应用程序以使其超时。

另一个解决方案是配置 TCP KeepAlive 并进行更频繁的检查,例如每 10 分钟一次。

一些应用程序在应用程序级别实现了 KeepAlive。例如 SSH、apache。

当发送保持活动并且远程端关闭连接时,您将收到来自远程端的 RST。

状态防火墙会在一段时间不活动后忘记连接。这意味着,当您在一段时间内(30 分钟或 1 小时)没有流量时,您可能会收到丢弃的数据包和半开连接。

我认为最好询问您要解决的具体问题,而不是您要实施的具体解决方案。

答案3

不幸的是,强制断开连接后,本地端不会收到通知

应该是,tcp-reset 意味着应该告知客户端连接正在关闭。如果在发送重置时客户端挂起,则意味着它没有正确处理从运行 IPTables 的主机发回的重置。除非您有办法解决这个问题,否则我想不出任何可以实现此目的的方法。

相关内容