当我们想要阻止某些 TCP 连接的建立,在 Linux 平台上有一个很好的解决方案iptables,但是对那些已经建立的 tcp 连接,iptables 就不能做到随心所欲的阻断了。
我在互联网上检索的时候发现了tcpkill这个工具,tcpkill 是一个网络分析工具集dsniff中的一个小工具。在 Linux 上可以直接通过 dsniff 包安装,使用方式也非常简单。
通过测试我发现 tcpkill 在执行命令之后并不会立刻阻断 tcp 连接,而是等待有数据传输时,才会阻断,因此在执行完命令之后程序并不会主动退出,而是需要通过***Ctrl+C***来退出,这对于某些想要通过程序来调用的脚本小子(例如我)来说简直是个灾难。
阻断一个已经建立的 tcp 连接通常有这几种方案:
前三种局限性太大,只能用第 4 种了。
GoPacket 是 go 基于libpcap构建的一个库,可以通过旁路的方式接收一份数据包的拷贝。因此我们可以很方便捕获到正在通信的 tcp 数据报文。通过数据报文,我们可以获取到通信双方的 MAC 地址,IP 和端口号,以及 ACK 号等,这些都是伪造数据包必不可少的。
在学习了tcpkill的源码之后,我使用 go 开发了一个增强版的tcpwall,tcpwall不仅可以实现和tcpkill同样的基于 ip 或端口监听到指定数据报文之后伪造 RST 数据报文来阻断 tcp 连接,也可以通过源 ip 源端口,目的 ip 目的端口来主动发送 SYN 数据报文包来诱导那些没有数据的 tcp 连接发送 ACK 数据报文包以获取源 MAC 、目的 MAC 和 ACK 号,并且可以通过指定参数让程序等待一段时间后主动退出。
阻断指定 IP 和端口的 TCP 连接(不关心是源或者目的)
tcpwall -i {interface} -host {host} -port {port}
阻断指定源 IP 和源端口的 TCP 连接
tcpwall -i {interface} -shost {src_host} -sport {src_port}
阻断指定目的 IP 和目的端口的 TCP 连接
tcpwall -i {interface} -dhost {dst_host} -dport {dst_port}
阻断指定源 IP 、源端口、目的 IP 、目的端口的 TCP 连接(会主动向双方发送 SYN 数据报文包)
tcpwall -i {interface} -shost {src_host} -sport {src_port} -dhost {dst_host} -dport {dst_port}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.