在Linux上关闭已建立的TCP连接

6
我无法找到一个简单的事情的答案,我将尝试实现:一旦建立了到我的Linux服务器的TCP连接,比如ssh / tcp 22或x11 / tcp 6000显示 ->如何关闭此连接,而不杀死进程(sshd / x11显示服务器)。我还看到一些建议使用iptables,但对我来说它不起作用,连接仍然在netstat -an中可见。如果有人能指点我正确的方向,那就太好了。
我到目前为止尝试了什么。
tcpkill: kills the process, not good for me
iptables: does not close the established connection, but prevent further connections. 

提前感谢,DJ

连接调试器到进程,然后在相应的文件描述符上调用shutdown()close()或者只调用close()。然后希望进程能够处理这个操作。 - Andrew Henle
2个回答

4

好的,我找到了至少一个解决方案(killcx),它是可行的。也许我们能够找到更简单的解决方案。 另外,我看到了“zb”的评论-谢谢-这个也可能有用,但是由于这个工具看起来非常有用但很复杂,所以我无法找到可行的语法。 所以这里有一个示例,说明如何使用对我有效的第一种解决方案:

netstat -anp  | grep 22   
output: tcp  0  0 192.168.0.82:22         192.168.0.77:33597      VERBUNDEN   25258/0
iptables -A INPUT -j DROP -s 192.168.0.77 (to prevent reconnect)
perl killcx.pl 192.168.0.77:33597 (to kill the tcp connection)

killcx可以在这里找到:http://killcx.sourceforge.net/ 它“窃取”来自外部主机(192.168.0.77)的连接并关闭它。这个解决方案很好,但如果你处于压力之下,设置起来太复杂了。以下是所需的软件包:

apt-get install libnetpacket-perl  libnet-pcap-perl libnet-rawip-perl
wget http://killcx.sourceforge.net/killcx.txt -O killcx.pl

然而,有一个更简单的解决方案会更好。

1

tcpkill无法起作用,因为它只能杀掉新连接,而不能杀死已存在的已建立连接

以下是如何删除已建立的TCP连接:

  1. 查找进程的PID和正在连接的客户端的IP,假设你在serverA上,有人正在从serverB连接

    root@A> netstat -tulpan | grep ssh | grep serverB

应该会看到类似于以下内容:

tcp        0      0 <serverA IP>:<port>     <serverB>:<port>   ESTABLISHED 221955/sshd
  1. 使用lsof实用程序,通过父进程ID获取此连接的文件描述符

    root@A> lsof -np 221995 | grep serverB IP

应该会看到类似于这样的内容

sshd 221955 <user>  17u IPv4 2857516568  0t0  TCP <serverA IP>:<port>-><serverB IP>:<port> (ESTABLISHED)

获取文件描述符号(第四列)= 17u

  1. 使用GDB关闭此连接,而不杀死sshd

    root@A> gdb -p 211955 --batch -ex 'call shutdown(17u, 2)'

应该会看到类似的东西,

0x00007f0b138c0b40 in __read_nocancel () from /usr/lib64/libc.so.6
$1 = 0
[Inferior 1 (process 211955) detached]

那个TCP连接现在应该关闭了。


作为替代方案,可以使用ss代替netstatss -tp '( sport = :22 )' - antonbormotov

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