在Linux中终止TCP连接


48

我的一个应用程序中有一些死连接,如果客户端计算机死了,则该应用处于挂起状态。

->192.168.1.214:49029 (ESTABLISHED)

有没有办法在不重新启动服务器的情况下从linux命令行终止这些选项?

搜索后,我找到了名为tcpkill的解决方案。但这对我不起作用。由于它会永久阻止该IP。

Answers:


35

最初来自:http : //rtomaszewski.blogspot.sk/2012/11/how-to-forcfully-kill-built-tcp.html

要“杀死”套接字,必须发送TCP重置数据包。要发送它(并被另一端接受),您必须知道实际的TCP序列号。

1)已经提到的tcpkill方法通过在网络上被动嗅探并等待此连接的有效数据包来学习SEQ号。然后,它使用获知的SEQ号将RSET数据包发送到双方。但是,如果连接处于空闲/挂起状态,并且没有数据流,它将不会做任何事情,并且将永远等待。

2)另一种方法使用称为killcx链接到Sourceforge)的perl脚本。这会主动发送欺骗的SYN数据包,并从答案中了解SEQ号。然后以与相同的方式发送RSET数据包tcpkill

另一种方法(基于您要实现的目标)是使用gdb调试器将其附加到拥有此套接字/连接的进程,并close()代表该进程发出syscall(如本答案中所述)

如果您只想处理挂起的连接(另一侧已死),则存在各种超时(例如TCP keepalive),如果在系统上进行了正确配置,它们应该自动关闭此类连接。


如果我们仅通过其文件描述符(fd)关闭TCP套接字,是否可以工作?exec的FD>& -
亚历山大Gonchiy

@AlexanderGonchiy用于实时连接,它将阻止进程响应数据包,因此将导致连接超时。对于空闲连接,将不会发生任何事情。我不确定内核在关闭fd时是否会向网络发送任何内容。
Marki555

我已经嗅到了序列号。那我该怎么办?
user3132194 18/12/29

18

tcpkill可能会为您做。在Ubuntu中,它在dsniff软件包中。

就像是:

$ sudo tcpkill -i wlan0 host 192.168.1.214

(或其他tcpdump类似的表达式表示要终止的连接)。


4
仅当连接正在传输任何内容时,此方法才有效。它不适用于挂起/空闲的TCP连接(有关详细信息,请参阅我的答案)
Marki555

16

在linux kernel> = 4.9上,您可以使用ssiproute2中的命令和key-K

ss -K dst 192.168.1.214 dport = 49029

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


对于linux,这实际上是最好的方法,如果您有空闲的连接(tcpkill无法工作),则几乎是唯一的方法。但是,我承认我没有检查过,killcx但是除非您修改iptables以允许这些欺骗性数据包通过,否则很多安全软件会阻止它运行。
塞斯·罗伯逊

6

做-作为根netstat -tunp|grep 49029。输出的最后一列应显示负责该连接的进程的PID和程序名。

如果幸运的话,只有一个连接过程。

如果您不走运,它将变得更加复杂(PID不仅负责一个连接)。这是什么服务?

您为什么要终止该会话?


8
我无法杀死那个过程。它是Gearman服务器。我只想关闭连接。
Vivek Goel 2013年

1

tcpkill无法关闭无效(挂起)的连接。基于libpcap它,它构造一个包到发送的FIN包。如果连接已死,则无法获得正确的序列号。

唯一的方法是关闭该进程,因此使各处都没有SPOF。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.