https://www.cnblogs.com/codelogs/p/16838850.html

原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。

简介#

如果你的程序写得有毛病,打开了很多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的原理即可,如下:

  1. 通过发送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包中。

  1. 使用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连接?的更多相关文章

  1. 如何kill一条TCP连接?

    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介 如果你的程序写得有毛病,打开了很多TCP连接,但一直没有关闭,即常见的连接泄露场景,你可能想要在排查问题的过程中, ...

  2. Linux 内核协议栈之TCP连接关闭

    Close行为: 当应用程序在调用close()函数关闭TCP连接时,Linux内核的默认行为是将套接口发送队列里的原有数据(比如之前残留的数据)以及新加入 的数据(比如函数close()产生的FIN ...

  3. close_wait状态和time_wait状态(TCP连接)

    1.CLOSE_WAIT的简单解决方案 不久前,我的Socket Client程序遇到了一个非常尴尬的错误.它本来应该在一个socket长连接上持续不断地向服务器发送数据,如果socket连接断开,那 ...

  4. TCP/IP 笔记 - TCP连接管理

    TCP是一种面向连接的单播协议,在发送数据之前,通信双方必须在彼此建立一条连接:这与UDP的无连接不同,UDP无需通信双方发送数据之前建立连接.所有TCP需要处理多种TCP状态时需要面对的问题,比如连 ...

  5. TCP/IP协议--TCP协议概括和TCP连接的建立和终止

    TCP提供一种面向连接的.可靠的字节流服务.面向连接指,发送和接收方在交换数据前必须建立一个TCP连接.顺便说下,一个TCP连接只有两方,因此广播和多播是不能应用于TCP的.字节流指,两个应用程序通过 ...

  6. TCP连接三次握手协议,释放连接四次挥手,以及使用 awl伪造mac地址进行多线程syn洪泛攻击。

    这个TCP连接就是一次追女生-谈恋爱-分手,追求比分手简单,但是分手比追求复杂.哥,谈了半年的女朋友,在就快要成功了的时候分了,原因是因为有人在后面该老子背后搞SYN洪泛攻击,最后女朋友丢失了.学会T ...

  7. Http权威指南(TCP连接)

    1.HTTP请求的过程 世界上几乎所有的HTTP通信都是由TCP/IP承载的,当发生HTTP请求时,实际上经过了以下几个步骤: ①浏览器从请求的URL中解析主机名 ②浏览器查询这个主机名的IP地址 ③ ...

  8. 利用tcpdump抓包工具监控TCP连接的三次握手和断开连接的四次挥手

    TCP传输控制协议是面向连接的可靠的传输层协议,在进行数据传输之前,需要在传输数据的两端(客户端和服务器端)创建一个连接,这个连接由一对插口地址唯一标识,即是在IP报文首部的源IP地址.目的IP地址, ...

  9. 多图详解 TCP 连接管理,太全了!!!

    TCP 是一种面向连接的单播协议,在 TCP 中,并不存在多播.广播的这种行为,因为 TCP 报文段中能明确发送方和接受方的 IP 地址. 在发送数据前,相互通信的双方(即发送方和接受方)需要建立一条 ...

  10. 关于TCP连接的3次握手和4次挥手

    3次握手: 关键在于双方都需要确认自己的发信和收信功能正常,收信功能通过接收对方信息得到确认,发信功能需要发出信息—>对方回复信息得到确认. 举个日常例子,打电话时我们对话如下: 如上,需要第三 ...

随机推荐

  1. Feign源码解析4:调用过程

    背景 前面几篇分析了Feign的初始化过程,历经艰难,可算是把@FeignClient注解的接口对应的代理对象给创建出来了.今天看下在实际Feign调用过程中的一些源码细节. 我们这里Feign接口如 ...

  2. Programming Abstractions in C阅读笔记:p242-p245

    <Programming Abstractions in C>学习第67天,p242-p245总结,总计4页. 一.技术总结 6.2小结主要讲回溯算法及递归算法在迷宫求解中应用,当然,理解 ...

  3. KubeFlow-Pipeline及Argo实现原理速析

    Argo是一个开源原生容器工作流引擎用于在Kubernetes上开发和运行应用程序.Argo Workflow流程引擎,可以编排容器流程来执行业务逻辑,在20年4月8日进入CNCF孵化器组. 而Kub ...

  4. 华为云推出全自研数据库,GaussDB(openGauss)能否撑起一片天?

    摘要:GaussDB(openGauss) 基于华为云底座,能够快速全球化部署,同时支持用户的本地化部署诉求,跟云上生态工具紧密结合让用户在迁移.开发.运维上省时省心. GaussDB(openGau ...

  5. 华为云FusionInsight MRS在金融行业存算分离的实践

    摘要:华为云FusionInsight MRS的大数据存算分离解决方案,实现资源价值最大化,存储与计算资源全面云化.灵活配置.弹性伸缩,降本增效. 在大数据.云计算.5G.AI等技术日新月异,数字经济 ...

  6. DBA:介里有你没有用过的“CHUAN”新社区版本Redis6.0

    摘要:华为云DCS Redis 6.0社区版带来了极致性能.功能全面.可靠性强.性价比高的云服务,并且完全兼容开源Redis,客户端无需修改代码,开通后即可使用,使企业完全无需后顾之忧就能享受到业务响 ...

  7. 高性能 Jsonpath 框架,Snack3 3.2.54 发布(支持 kotlin data 类反序化)

    Snack3,一个高性能的 JsonPath 框架 借鉴了 Javascript 所有变量由 var 申明,及 Xml dom 一切都是 Node 的设计.其下一切数据都以ONode表示,ONode也 ...

  8. Office 看不了激活更改产品密钥

    Office 看不了激活更改产品密钥 解决方案: PatchOffice.rar - 蓝奏云 将文件解压到桌面 >>> 右击,以管理员方式运行或双击运行均可 >>> ...

  9. tidevice中常用api 浅谈

    - 设备管理类API: - `pair(device: Device) -> bool`:配对一个iOS设备,返回是否成功. - `unpair(device: Device) -> bo ...

  10. let、var、const区别

    1.var:传统的变量声明方式 在ES5及之前的JavaScript版本中,我们通常使用var关键字声明变量.var具有以下特点: 函数作用域:变量的作用域限制在声明的函数内部,如果在函数外部访问,将 ...