網站首頁 編程語言 正文
簡介
如果你的程序寫得有毛病,打開了很多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了。整個操作看起來有點麻煩,可以自己寫個腳本封裝一下。
原文鏈接:https://juejin.cn/post/7159831973664391199
相關推薦
- 2022-10-02 Python實現遍歷讀取文件或文件夾_python
- 2022-09-22 遞歸和迭代(深度優先,廣度優先)的差異
- 2022-12-11 React?RenderProps模式超詳細講解_React
- 2022-10-30 詳解Python?中的命名空間、變量和范圍_python
- 2022-10-20 利用Python的tkinter模塊實現界面化的批量修改文件名_python
- 2022-08-17 go?Cobra命令行工具入門教程_Golang
- 2023-07-04 Netty的SO_LINGER不要隨便用
- 2022-06-22 golang?API請求隊列的實現_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支