前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一招搞定TCP孤儿连接引起的端口占用!

一招搞定TCP孤儿连接引起的端口占用!

作者头像
李俊鹏
发布2022-09-21 11:13:07
9180
发布2022-09-21 11:13:07
举报
文章被收录于专栏:运维研习社运维研习社

周六群里大佬发了一篇文章,是关于TCP keepalive相关的,其中有一段是关于孤儿连接的,这里引用下

什么是孤儿连接?

以 redis 做实现吧,client 172.24.213.40, server 172.24.213.39. 在 client 端开启两个 session, 分别连接 server 和 tcpdump

代码语言:javascript
复制
root@worker1:~# redis-cli -h 172.24.213.39 -p 6380
172.24.213.39:6380>
root@worker1:~# tcpdump -i eth0 -n host 172.24.213.39
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:00:42.604669 IP 172.24.213.40.38470 > 172.24.213.39.6380: Flags [S], seq 189110270, win 29200, options [mss 1460,sackOK,TS val 3222067084 ecr 0,nop,wscale 6], length 0
14:00:42.604890 IP 172.24.213.39.6380 > 172.24.213.40.38470: Flags [S.], seq 3111402640, ack 189110271, win 28960, options [mss 1460,sackOK,TS val 1210274267 ecr 3222067084,nop,wscale 7], length 0
14:00:42.604906 IP 172.24.213.40.38470 > 172.24.213.39.6380: Flags [.], ack 1, win 457, options [nop,nop,TS val 3222067084 ecr 1210274267], length 0

14:03:13.731484 IP 172.24.213.40.38470 > 172.24.213.39.6380: Flags [.], ack 11469, win 559, options [nop,nop,TS val 3222218206 ecr 1210410284], length 0
14:03:13.731628 IP 172.24.213.39.6380 > 172.24.213.40.38470: Flags [.], ack 18, win 227, options [nop,nop,TS val 1210425387 ecr 3222067087], length 0
14:03:28.835480 IP 172.24.213.40.38470 > 172.24.213.39.6380: Flags [.], ack 11469, win 559, options [nop,nop,TS val 3222233310 ecr 1210425387], length 0
14:03:28.835615 IP 172.24.213.39.6380 > 172.24.213.40.38470: Flags [.], ack 18, win 227, options [nop,nop,TS val 1210440491 ecr 3222067087], length 0

会看到 client 每隔 15s 会发送空的 ACK 包给 server, 并收到 server 返回的 ACK, 实际上这就是 client 端的 tcp keepalive 在起作用。然后我们在 server 设置 iptables, 人为制造网络隔离

代码语言:javascript
复制
root@myali:~# iptables -I INPUT -s 172.24.213.40 -j DROP;iptables -I OUTPUT -d 172.24.213.40 -j DROP;iptables -nvL

过一会查看 client tcpdump 输出

代码语言:javascript
复制
14:05:14.563481 IP 172.24.213.40.38470 > 172.24.213.39.6380: Flags [.], ack 11469, win 559, options [nop,nop,TS val 3222339035 ecr 1210531111], length 0
14:05:19.683482 IP 172.24.213.40.38470 > 172.24.213.39.6380: Flags [.], ack 11469, win 559, options [nop,nop,TS val 3222344155 ecr 1210531111], length 0
14:05:24.803489 IP 172.24.213.40.38470 > 172.24.213.39.6380: Flags [.], ack 11469, win 559, options [nop,nop,TS val 3222349275 ecr 1210531111], length 0
14:05:29.923486 IP 172.24.213.40.38470 > 172.24.213.39.6380: Flags [R.], seq 18, ack 11469, win 559, options [nop,nop,TS val 3222354394 ecr 1210531111], length 0

client 172.24.213.40 每 5s 发送一个 ACK 三次,最后发一个 RST 包销毁连接。当然这个 RST redis-server 肯定也没有接收到。过一会将 server 防火墙删除

代码语言:javascript
复制
root@myali:~# iptables -D INPUT -s 172.24.213.40 -j DROP;iptables -D OUTPUT -d 172.24.213.40 -j DROP;iptables -nvL

此时再分别查看网络连接 ss -a | grep 6380, 会发现 client 端消失了,但是 server 端的还在,状态仍然是 ESTAB

代码语言:javascript
复制
root@myali:~# ss -a | grep 6380
tcp   ESTAB    0      0   172.24.213.39:6380   172.24.213.40:38470

这就是孤儿连接

孤儿连接会造成什么问题?

这种孤儿连接,首先会占用资源,然后如果你想处理,不管你通过什么方法,比如lsof查看占用该端口的进程,会发现,无法定位进程号,因为进程已经退出了,它不是进程层面的连接

还有一种运维常见的场景

此时如果你想启动相同端口的应用,或者进程,还会发现端口已被占用,无法启动,停止进程,会发现该TCP连接不属于进程管理,无法停止

这个时候怎么做?介绍一款专门针对这种TCP连接的工具

Killcx

Killcx is a Perl script to close a TCP connection under Linux, whatever its state is (half-open, established, waiting or closing state).

这是官方的解释,Killcx就是专门用来关闭Linux下TCP连接的,不管连接状态是什么,半开、连接中、等待或关闭状态

killcx的原理是要关闭的网络连接,从TCP包中提取Acknowlegment和Sequence numbers,熟悉TCP四次挥手,结合上面孤儿连接造成的原因,你就能明白,其实就是client或者server端没有收到SYN和ACK确认包,killcx就是通过伪造这两个包,来完成最后没完成的TCP交互

killcx使用方法如下:

代码语言:javascript
复制
  - syntax   : killcx [dest_ip:dest_port] {interface}

    dest_ip              : remote IP
    dest_port            : remote port
    interface (optional) : network interface (eth0, lo etc).

  - example  : killcx 120.121.122.123:1234
               killcx 120.121.122.123:1234 eth0

Killcx安装

killcx的安装包,可以直接从sourceforge下载,下载地址http://sourceforge.net/projects/killcx/files/

下载完成后,并不能直接执行,killcx官网介绍了它的依赖

代码语言:javascript
复制
Perl modules needed :

You need the following modules to run killcx :

* Net::RawIP : needed to create spoofed packets.
* Net::Pcap : needed to capture TCP packets.
* NetPacket::Ethernet : needed to decode TCP/IP packets.

因为Killcx是perl脚本,它运行依赖三个Perl模块,分别是Net::RawIp、Net::PCAP、NetPacket::Ethernet,这几个模块的安装很简单

代码语言:javascript
复制
# 通过yum先安装perl-CPAN
yum -y install perl-CPAN
# 利用CPAN安装三个模块
perl -MCPAN -e shell
cpan> install Net::RawIP
cpan> install Net::Pcap
cpan> install NetPacket::Ethernet

安装完成后,就可以直接使用了,按照上面提示的官方案例,OK,今天的一个小知识点就到这里,欢迎关注、转发、在看!!!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-12-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 运维研习社 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是孤儿连接?
  • 孤儿连接会造成什么问题?
  • Killcx
  • Killcx安装
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档