kill一条TCP连接实现方法详解

目录
  • 简介
  • kill活跃的TCP连接
    • 实现原理
  • kill空闲的TCP连接
    • 使用ss杀死连接
    • 使用hping3杀死连接

简介

如果你的程序写得有毛病,打开了很多TCP连接,但一直没有关闭,即常见的连接泄露场景,你可能想要在排查问题的过程中,先临时kill一波泄露的连接。

又比如你要验证程序在遇到网络错误时的自愈能力,想手动kill掉一些正常TCP连接,看程序是否能自动重连并恢复运行。

这些场景,都需要手动kill一部分TCP连接,那在Linux下有哪些kill连接的方法呢?

kill活跃的TCP连接

使用ngrep或tcpkill命令可以杀死活跃状态的TCP连接,用法如下:

# ngrep杀死连接
$ sudo ngrep -d any -K3 '' 'port 54690'
# 安装tcpkill,及使用其杀死连接
$ sudo apt install dsniff
$ sudo tcpkill -i any 'port 45308'

如上所示,可以发现在杀死连接时,ngrep和tcpkill都向连接方发送了RST包。

实现原理

学过《计算机网络》的同学都知道,TCP协议是通过FIN包与ACK包来做四次挥手,从而断开TCP连接的,这是正常的TCP断连过程,但TCP协议中还有RST包,这种包用于异常情况下断开连接,Linux在收到RST包后,会直接关闭本端的Socket连接,而不需要经历四次挥手过程。

而上面的ngrep与tcpkill命令,正是通过给对方发送RST包,从而实现杀死TCP连接的。但要发送一个正确的RST包,需要知道TCP连接交互时所使用的序列号(seq),因为乱序的包会被TCP直接丢弃,所以ngrep和tcpkill还会监听网卡上交互的包,以找到指定连接所使用的序列号seq。

所以,ngrep与tcpkill只能kill有流量的活跃TCP连接,对于空闲连接就无法处理了。

kill空闲的TCP连接

对于空闲状态的TCP连接,可以用ss或hping3命令来处理,如下:

使用ss杀死连接

通过ss命令的-K选项可以用来kill连接,如下:

# 安装ss命令
$ sudo apt install iproute2
# 使用ss杀死目标端口为65987的连接
$ sudo ss -K dport = 65987

注意,使用这个功能需要你的内核版本>=4.9,且打开了CONFIG_INET_DIAG_DESTROY选项,因此某些情况下可能无法使用。

使用hping3杀死连接

如果无法使用ss命令,则可以考虑使用hping3命令来kill连接,hping3命令可以发任何类型的TCP包,因此只要模拟tcpkill的原理即可,如下:

  • 通过发送SYN包来获取seq

上面提到了,TCP协议会直接丢弃乱序的数据包,但是对于SYN包却区别对待了,如果你随便发一个SYN包给已连接状态的Socket,它会回复一个ACK,并携带有正确的seq序列号,如下:

# 第一个参数,表示发送包的目标ip地址
# -a:设置包的源ip地址
# -s:设置包的源端口
# -p:设置包的目标端口
# --syn:表示发SYN包
# -V:verbose output,使hping3输出序列号seq
# -c:设置发包数量
$ sudo hping3 172.26.79.103 -a 192.168.18.230 -s 8080 -p 45316 --syn -V -c 1
using eth0, addr: 172.26.79.103, MTU: 1500
HPING 172.26.79.103 (eth0 172.26.79.103): S set, 40 headers + 0 data bytes
len=40 ip=172.26.79.103 ttl=64 DF id=16518 tos=0 iplen=40
sport=45316 flags=A seq=0 win=502 rtt=13.4 ms
seq=1179666991 ack=1833836153 sum=2acf urp=0

可以在输出中找到,ack=1833836153即是对方回复的序列号,我们用在后面的发RST包中。

  • 使用seq发RST包
# --rst:表示发RST包
# --win:设置TCP窗口大小
# --setseq:设置包的seq序列包
$ sudo hping3 172.26.79.103 -a 192.168.18.230 -s 8080 -p 45316 --rst --win 0 --setseq 1833836153 -c 1
HPING 172.26.79.103 (eth0 172.26.79.103): R set, 40 headers + 0 data bytes
--- 172.26.79.103 hping statistic ---
1 packets transmitted, 0 packets received, 100% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms

整个过程如下:

可以发现前面我们用lsof查到的连接,在发送RST包后就查不到了,说明连接已经被kill了。整个操作看起来有点麻烦,可以自己写个脚本封装一下。

以上就是kill一条TCP连接实现方法详解的详细内容,更多关于kill TCP连接的资料请关注我们其它相关文章!

(0)

相关推荐

  • linux下2个检查tcp连接的命令

    1 检测web服务器的链接数量及状态: netstat -ant|awk '{print $5 "\t" $6}'|grep "::ffff:"|sed -e 's/::ffff://' -e 's/:[0-9]*//' |sort|uniq -c| sort -rn|head -10 结果: 122 125.162.71.199 TIME_WAIT 99 79.119.125.43 TIME_WAIT 81 125.167.243.77 TIME_WAIT 75

  • Android使用socket创建简单TCP连接的方法

    本文实例讲述了Android使用socket创建简单TCP连接的方法.分享给大家供大家参考,具体如下: 不管是在Java还是Android编程中,通信都是及其重要的一部分.有连接的socket编程,重要性自然毋庸置疑. 这里以一个简单的demo演示一个最基本的socket编程. 先写服务端.服务端是Java代码.笔者懒得装eclipse等编程软件,就是直接notepad编程,dos运行的.服务端一般是新建一个绑定端口的serversocket,监听客户端请求(死循环监听).当接收到客户端消息时,

  • Linux系统创建TCP连接流程介绍

    目录 Linux创建TCP的步骤 服务端 客户端 TCP建立流程 示例代码 Linux创建TCP的步骤 TCP编程需要客户端和服务器两套编码,其创建TCP的流程也是不完全一致的 服务端 使用socket函数创建一个套接字 使用setsockopt函数设置套接字的属性 使用bind函数绑定IP地址.端口信息到套接字上使用listen函数监听指定端口 使用accept函数接收客户端的连接请求 使用send/recv和read/write函数进行数据的收发 使用close函数关闭网络连接和监听 客户端

  • Qt基于TCP实现客户端与服务端的连接

    Qt TCP的客户端与服务端的连接,供大家参考,具体内容如下 可以实现局域网内简单的信息传递(文件传输,稍后更新) 界面是用ui设计师做的简单设计 客户端 (1).ClientWidget.h 头文件 #ifndef CLIENTWIDGET_H #define CLIENTWIDGET_H #include <QWidget> #include "ui_ClientWidget.h" #include <QTcpSocket> #include <QHo

  • kill一条TCP连接实现方法详解

    目录 简介 kill活跃的TCP连接 实现原理 kill空闲的TCP连接 使用ss杀死连接 使用hping3杀死连接 简介 如果你的程序写得有毛病,打开了很多TCP连接,但一直没有关闭,即常见的连接泄露场景,你可能想要在排查问题的过程中,先临时kill一波泄露的连接. 又比如你要验证程序在遇到网络错误时的自愈能力,想手动kill掉一些正常TCP连接,看程序是否能自动重连并恢复运行. 这些场景,都需要手动kill一部分TCP连接,那在Linux下有哪些kill连接的方法呢? kill活跃的TCP连

  • LyScript获取上一条与下一条汇编指令的方法详解

    LyScript 插件默认并没有提供上一条与下一条汇编指令的获取功能,当然你可以使用LyScriptTools工具包直接调用内置命令得到,不过这种方式显然在效率上并不理想,我们需要在LyScript插件API基础上自己封装实现这个功能. LyScript项目地址:https://github.com/lyshark/LyScript 获取下一条汇编指令 下一条汇编指令的获取需要注意如果是被命中的指令则此处应该是CC断点占用一个字节,如果不是则正常获取到当前指令即可. 1.我们需要检查当前内存断点

  • PHP使用Redis长连接的方法详解

    本文实例讲述了PHP使用Redis长连接的方法.分享给大家供大家参考,具体如下: php-redis在github上的项目地址:https://github.com/phpredis/phpredis pconnect函数声明 其中time_out表示客户端闲置多少秒后,就断开连接.函数连接成功返回true,失败返回false: pconnect(host, port, time_out, persistent_id, retry_interval) host: string. can be a

  • Android中SeekBar拖动条控件使用方法详解

    SeekBar拖动条控件使用方法,具体内容如下 一.简介 1.  二.SeekBar拖动条控件使用方法 1.创建SeekBar控件 <SeekBar android:id="@+id/SeekBar1" android:layout_width="match_parent" android:layout_height="wrap_content" android:progress="30" /> 2.添加setOn

  • 探讨如何配置SQL2008,让其允许C#远程外部连接的方法详解

    Step 1:在服务器图标上单击右键,选择property,然后选connection,把allow remote connection选上,这一步的目的是让数据库允许远程连接. Step 2:在数据库服务器图标上,展开目录,找到Security下的Logins子目录树,设置SA账户的属性,改password,在status栏里,login选上enable.这一步的目的是,允许远程客户端使用sa用户邓肯,sa是system administrator的缩写,拥有数据库最高管理权限,默认状态下是禁

  • Java中获取MongoDB连接的方法详解

    首先是所需jar包,Maven中的配置如下: <dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver</artifactId> <version>3.4.1</version> </dependency> <dependency> <groupId>org.mongodb</groupId>

  • PHP长连接实现与使用方法详解

    本文实例讲述了PHP长连接实现与使用方法.分享给大家供大家参考,具体如下: 长连接技术(Long Polling) 在服务器端hold住一个连接, 不立即返回, 直到有数据才返回, 这就是长连接技术的原理 长连接技术的关键在于hold住一个HTTP请求, 直到有新数据时才响应请求, 然后客户端再次自动发起长连接请求. 那怎么样hold住一个请求呢?服务器端的代码可能看起来像这样的 set_time_limit(0); //这句很重要, 不至于运行超时 while (true) { if (has

  • python连接mongodb集群方法详解

    简单的测试用例 #!/usr/bin/python # -*- coding: UTF-8 -*- import time from pymongo import MongoClient # 连接单机 # single mongo # c = MongoClient(host="192.168.89.151", port=27017) # 连接集群 c = MongoClient('mongodb://192.168.89.151,192.168.89.152,192.168.89.1

  • 在IntelliJ IDEA中使用Java连接MySQL数据库的方法详解

    一.下载MySQL数据库并进行安装和配置 下载地址:https://dev.mysql.com/downloads/installer/ 二.下载JDBC连接器 下载地址:mysql-connector-java-8.0.22 下载好压缩包并解压后找到mysql-connector-java-8.0.22.jar文件放在自己指定的路径下. 三.在项目中导入jar包 用于测试数据库连接的测试类Test.java代码: import java.sql.Connection; import java.

随机推荐