kill网络tcp session

Originally from: http://rtomaszewski.blogspot.sk/2012/11/how-to-forcibly-kill-established-tcp.html

Here are some options:

  • Attach with gdb and call close() on the fd. You can map from addr/port to inode number via /proc/net/tcp and from inode number to FD inside the process with ls -la /proc/$pid/fd.
  • Spoof a RST packet. You'll need to generate it locally and guess the SEQ number somehow.
  • Maybe setup an iptables rule to generate a RST on the next packet.
  • Write a kernel module.

There doesn't seem to be a well supported way to do this. It is likely that processes will crash if their FDs are unexpectedly closed anyway.

To "kill" a socket, you must send a TCP reset packet. To send it (and be accepted by the other side), you must know the actual TCP sequence number.

1) The already mentioned tcpkill method learns the SEQ number by passively sniffing on the network and waiting for valid packets of this connection to arrive. Then it uses the learned SEQ number to send RSET packets to both sides. However if the connection is idle/hanged and no data flows, it won't do anything and will wait forever.

2) Another method uses perl script called killcx (link to Sourceforge). This actively sends spoofed SYN packets and learns the SEQ number from the answer. It then sends RSET packets the same way as tcpkill.

Alternatively approach (based on what you want to achieve) is to use gdb debugger to attach to a process owning this socket/connection and issue close() syscall on its behalf - as detailed in this answer.

If you want to deal only with hanged connections (the other side is dead), there are various timeouts (TCP keepalive for example), which should automatically close such connections if configured properly on the system.

实际操作其实用iptable会更方便一点:

iptables -A INPUT/OUTPUT/FORWARD -p TCP ...(match元组信息) -j REJECT--reject-with tcp-reset

和9.98.31.137:22 建立了22端口连接:

root:~# netstat -tuanp|grep :22
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1334088/sshd        
tcp        0      0 9.84.31.220:59834       9.98.31.137:22          ESTABLISHED 1337907/ssh    

现在用iptables kill掉这个session 连接:

root:~# iptables -A OUTPUT -p tcp --dport 22 -d 9.98.31.137 -j REJECT --reject-with tcp-reset
root:~# 
root:~# 
root:~# iptables -nvL|grep '9.98.31.137'
    2   164 REJECT     tcp  --  *      *       0.0.0.0/0            9.98.31.137          tcp dpt:22 reject-with tcp-reset

 session 已经不存在了:

root:~# netstat -tuanp|grep :22
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1334088/sshd      

ssh terminal 断开了连接: 

[root@cnwbzp3137 ~]# client_loop: send disconnect: Broken pipe
allen:~$ 
allen:~$ 

重新发起ssh 连接也会出现refuse: 

allen:~$ ssh root@cnwbzp3137.cn.dst.ibm.com
ssh: connect to host cnwbzp3137.cn.dst.ibm.com port 22: Connection refused

如果使用drop:

root:~# iptables -A OUTPUT -p tcp --dport 22 -d 9.98.31.137 -j DROP
root:~# 
root:~# 
root:~# iptables -nvL|grep '9.98.31.137'
   35 30112 DROP       tcp  --  *      *       0.0.0.0/0            9.98.31.137          tcp dpt:22
root:~# 

 ssh session 出现timeout 退出:

[root@cnwbzp3137 ~]# Timeout, server cnwbzp3137.cn.dst.ibm.com not responding.
allen:~$ 
allen:~$ 

 session先FIN_WAIT, 然后退出:

root:~# netstat -tuanp|grep :22
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1341464/sshd        
tcp        0   1589 9.84.31.220:60362       9.98.31.137:22          FIN_WAIT1   -                   

root:~# 
root:~# netstat -tuanp|grep :22
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1341464/sshd      

SSH连接无任何响应(直接drop,无回应)最后timeout 

allen:~$ ssh root@cnwbzp3137.cn.dst.ibm.com

allen:~$ ssh root@cnwbzp3137.cn.dst.ibm.com
ssh: connect to host cnwbzp3137.cn.dst.ibm.com port 22: Connection timed out
allen:~$ 

如果是用input,是没有效果的:

root:~# iptables -A INPUT -p tcp --dport 22 -d 9.98.31.137 -j REJECT --reject-with tcp-reset
root:~# 

root:~# iptables -nvL|grep '9.98.31.137'
    0     0 REJECT     tcp  --  *      *       0.0.0.0/0            9.98.31.137          tcp dpt:22 reject-with tcp-reset

连接始终存在:

root:~# netstat -tuanp|grep :22
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1341464/sshd        
tcp        0      0 9.84.31.220:32792       9.98.31.137:22          ESTABLISHED 1346751/ssh         
root:~# 


[root@cnwbzp3137 ~]# less /usr/local/ch.log
[root@cnwbzp3137 ~]# 
[root@cnwbzp3137 ~]# 

使用forward也是没有效果:

root:~# iptables -A FORWARD -p tcp -d 9.98.31.137 -j REJECT --reject-with tcp-reset
root:~# 
root:~# iptables -nvL|grep '9.98.31.137'
    0     0 REJECT     tcp  --  *      *       0.0.0.0/0            9.98.31.137          reject-with tcp-reset

连接始终存在:

root:~# netstat -tuanp|grep :22
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1341464/sshd        
tcp        0      0 9.84.31.220:32792       9.98.31.137:22          ESTABLISHED 1346751/ssh   
[root@cnwbzp3137 ~]# uptime
 10:35:36 up 39 days, 15:11,  3 users,  load average: 0.60, 0.33, 0.29
[root@cnwbzp3137 ~]# 

How to use tcpkill:

Linux: How to kill a TCP connection using netstat?

You cannot kill a TCP connection using netstat utility. netstat is use for

  • Display network connections
  • Routing tables
  • Interface statistics
  • Masquerade connections
  • Multicast memberships
  • And much more

However Linux support two other commands or utility that can be used to kill a TCP connection.

tcpkill command

Use tcpkill command to kill specified in-progress TCP connections. It is useful for libnids-based applications which require a full TCP 3-whs for TCB creation.

Syntax:

tcpkill -i eth0 { expression }

Examples:

(a) Kill all outgoing ftp (port 21) connection:

tcpkill -i eth0 port 21

(b) Kill all all packets arriving at or departing from host 192.168.1.2 (host12.nixcraft.com)

tcpkill host 192.168.1.2

OR

tcpkill host host12.nixcraft.com


(c) To kill all IP packets between 192.168.1.2 and any host except 192.168.1.111, type the following:

tcpkill ip host 192.168.1.2 and not 192.168.1.111

Since tcpkill expressions are based upon tcpdump command's filter expression, it is recommended that you read options with expression and examples.

使用ss来kill

On linux kernel >= 4.9 you can use the ss command from iproute2 with key -K

ss -K dst client1.something dport = 49987

the kernel have to be compiled with CONFIG_INET_DIAG_DESTROY option enabled.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值