Skip to content

1ikc/kill-one-conn

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

koc (kill-one-conn)

背景

  • 调试长连接程序,e.g. ⇒ WebSocket连接的断线重连。
  • 关闭某个TCP连接,e.g. ⇒ 由于用户违规断线指定的WebSocket连接。
  • 如果是在服务端控制,直接kill进程会导致所有连接失效,服务不可用,是不可取的。

针对以上场景,我们需要一种可以细粒度关闭TCP连接的工具。

已有工具

结合现有的tcpkill和killcx,发现使用起来不如意。

  • tcpkill不能立即关闭连接,需要等待有新的数据传输后才进行连接关闭。
  • killcx是perl脚本,安装起来相对繁琐。

因此有了造轮子的想法💡。

特性

  • 支持立即/延时关闭连接
  • 支持一定时间内拦截指定连接并自动退出程序
  • 支持其他项目复用
  • 下载即用
  • 目前仅适用于IPv4

使用说明

需要保证系统已支持libpcap扩展,下文提供安装方式。

  • CLI
    release下载最新二进制文件koc

    ./koc
      -nic {nic} 
      -src_ip {src_ip} -dst_ip {dst_ip} 
      -src_port {src_port} -dst_port {dst_port}
      -delay {delay}
      -timeout {duration}
      -retry {retry}
    • nic:监听的网络接口卡。
    • src_ip:来源IP,使用点分十进制。
    • dst_ip:目的IP,使用点分十进制。
    • src_port:源端口。
    • dst_port:目的端口。
    • delay:延时关闭时间,默认0,单位ms。
    • timeout:持续拦截时间,默认0,单位ms。
    • retry:RST报文的重传机制,默认3。
  • Module

    import (
      koc "github.com/1ikc/kill-one-conn"
    )
    
    func killConn(nic string, options ...koc.Option) {
      // 构建拦截器
      t, _ = koc.Build(
        nic,
        options...,
      )
      // 启动拦截
      t.Intercept()
    }

运行截图

运行kill-one-conn


问题汇总

环境以CentOS为准

  • 工具提示 error while loading shared libraries: libpcap.so.0.8: xxx

    • 安装libpcap

      yum install libpcap-devel

    • 创建软连接

      sudo ln -s /usr/lib64/libpcap.so /usr/lib64/libpcap.so.0.8

  • 交叉编译提示 gopacket/pcap: undefined xxx

    • gopacket使用了CGO,编译开启CGO_ENABLED。
    • 安装C交叉编译器
    • 指定C交叉编译器,交叉编译linux版本

    ⚠️未解决成功,macOS交叉编译还是失败,转到Linux系统编译。如有其他办法,望不吝赐教。


原理

伪造RST包,包的序号利用challenge-ack机制获得。

challenge-ack机制

向ESTABLISHED状态的连接,发送SYN报文。会接收到challenge-ack报文,获取报文中的ack伪造RST报文并发给其中一方。

注意

如果在生产环境抓包发现ESTABLISHED状态的连接有SYN报文到达,需要留意是否正遭受RST攻击。


tcpkill抓包实践

抓包流程

  • 使用 nc 工具建立一条TCP长连接。

    • nc -l 40033 启动服务端

    • nc 127.0.0.1 40033 -p 40022 启动客户端

    • tcpdump 抓包结果 ⇒ TCP的三次握手完成

      tcpdump抓包结果1

  • 使用 tcpkill 工具关闭一条活跃的TCP连接。

    • tcpkill -i lo -3 port 40033 ,同时在nc服务端发送数据,运行结果 ⇒

      tcpkill抓包结果

    • tcpdump抓包结果 ⇒ 伪造RST包关闭活跃连接

      tcpdump抓包结果1

结论分析

tcpkill执行后不是立即关闭连接,而是先监听40033端口的数据传输,当监听到有数据传输时,再伪造RST包进行连接的关闭。同时tcpkill关闭连接后不会自动退出程序。


引用

About

Tool to close tcp connection

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages