如何在Linux中终止单个TCP连接?

13

我有一个过程,它在不同的端口上打开了多个浏览器的TCP连接。

使用netsat命令的输出大致如下:

tcp 0 0 server1.something:myprog client1.something:49987 ESTABLISHED
tcp 0 0 server1.something:myprog client1.something:65987 ESTABLISHED
tcp 0 0 server1.something:myprog client1.something:89987 ESTABLISHED

现在我想精确地关闭一个连接,该怎么做?(因为杀死进程会关闭所有连接)

4个回答

20

在Linux内核版本大于等于4.9时,您可以使用iproute2中的ss命令并带上-K选项。

ss -K dst client1.something dport = 49987

内核必须启用CONFIG_INET_DIAG_DESTROY选项进行编译。


在 Fedora 36 上(作为 root 用户)运行良好。 - maxschlepzig

11

以下是一些选项:

  • 使用gdb连接并在fd上调用close()。您可以通过/proc/net/tcp将addr/port映射到inode号码,然后通过ls -la /proc/$pid/fd将inode号码映射到进程内的FD。
  • 伪造一个RST数据包。您需要在本地生成它并以某种方式猜测SEQ号码。
  • 也许设置一个iptables规则,在下一个数据包上生成RST。
  • 编写一个内核模块。

目前似乎没有很好的方法来做到这一点。如果FD意外关闭,进程可能会崩溃。


我认为安全问题也是缺乏这样一个工具的主要原因。 - OkieOth

6
您可以根据目标端口进行杀死操作:
ss -K dport = 65987

1
此解决方案需要 root 权限。 - ks1322
1
@ks1322 或者更准确地说,CAP_NET_ADMIN - iBug

4

您不能杀死一个进程的单个连接。

但是,您可以使用iptables阻止它。因此,该连接无法提供或接收数据,并且客户端将在超时中运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接