原创:扣钉日记(微信公众号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'
【如何kill一条TCP连接?】文章插图
如上所示,可以发现在杀死连接时,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
# 第一个参数,表示发送包的目标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 1using eth0, addr: 172.26.79.103, MTU: 1500HPING 172.26.79.103 (eth0 172.26.79.103): S set, 40 headers + 0 data byteslen=40 ip=172.26.79.103 ttl=64 DF id=16518 tos=0 iplen=40sport=45316 flags=A seq=0 win=502 rtt=13.4 msseq=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 1HPING 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 lossround-trip min/avg/max = 0.0/0.0/0.0 ms
整个过程如下:文章插图
可以发现前面我们用lsof查到的连接,在发送RST包后就查不到了,说明连接已经被kill了 。整个操作看起来有点麻烦,可以自己写个脚本封装一下 。
推荐阅读
- 如何才能快速赚大钱(如何轻松又赚大钱)
- 负债累累如何能快速赚到钱
- 如何能快速赚钱(月入1万的10个冷门副业)
- 崩坏3武器索尔之锤强度如何
- 猫之城激潮之涂鸦如何搭配
- 手机反应越来越慢怎么办/怎么解决(手机反应慢如何解除)
- 群主身份如何转让(群主为啥转让不了)
- 怎么把群主让给别人(如何禁止群员改群名)
- 抖音如何转让群主(怎么把群主转让给别人抖音)
- 如何拦截垃圾短信(怎么屏蔽1069开头的垃圾短信)