tcpkill工作原理分析
此文已由作者张耕源授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
日常工作生活中大家在维护自己的服务器、VPS有时会碰到这样的情况:服务器上突然出现了许多来自未知ip的网络连接与流量,我们需要第一时间切断这些可能有害的网络连接。除了iptables/ipset, blackhole routing这些常规手段,我们还可以借助一些更轻量级的小工具来临时处理这些情况,如tcpkill。
tcpkill使用简介
tcpkill是一个网络分析工具集dsniff中的一个小工具。在Debian/Ubuntu上可以直接通过dsniff包安装:
# aptitude install dsniff
tcpkill使用的语法和tcpdump几乎一致:
tcpkill [-i interface] [-1...9] expression
其中第一个参数 -i 指定网卡设备。
第二个参数指定“kill”的强制等级,越高越强,默认为3,我们在后面了解tcpkill的工作原理后会知道这个参数的具体作用。
第三个参数则是匹配需要kill的tcp连接通配表达式,语法与tcpdump使用的pcap-filter完全一样。
如果我们需要使用tcpkill临时禁止服务器与主机10.0.0.1的tcp连接,可以在服务器上输入命令:
# tcpkill host 10.0.0.1
tcpkill会一直阻止主机10.0.0.1与服务器的网络连接,直到你结束这个tcpkill进程为止。
tcpkill原理分析
在使用tcpkill时,会发现一件奇怪的事情,运行tcpkill命令后并不会马上中断匹配的tcp连接,只有当该连接有新的tcp包发送接收时,tcpkill才会“kill”这个tcp连接。这个奇怪的现象燃起了我们的好奇心,于是探索一下tcpkill到底是如何工作的。
下面以Linux下的nc命令为例。
我们在两个主机hostA与hostB间通过nc命令建立一个tcp连接:
hostA在本地tcp 5555端口监听
hostA$ nc -l -p 5555
hostB通过本地6666端口连接hostA的5555端口
hostB$ nc hostA 5555 -p 6666
此时在hostA上已经可以观察到一条与hostB的ESTABLISHED连接
hostA$ netstat -anp|grep 5555tcp 0 0 hostA:5555 hostB:6666 ESTABLISHED 19638/nc
在hostA上通过tcpdump也可以观察到3次握手已经完成
hostA# tcpdump -i eth1 port 5555IP hostB.6666 > hostA.5555: Flags [S], seq 750827752, ...IP hostA.5555 > hostB.6666: Flags [S.], seq 1191909671, ack 750827753, ...IP hostB.6666 > hostA.5555: Flags [.], ack 1, win 115, ...
如果此时运行tcpkill命令尝试“kill”这个tcp连接
hostA# tcpkill -1 -i eth1 port 5555tcpkill: listening on eth1 [port 5555]
会发现hostA与hostB上的nc命令并没有受到任何影响而退出,hostA上观察到该tcp连接还是ESTABLISHED状态,tcpdump与tcpkill也没有任何新的输出。
hostA$ netstat -anp|grep 5555tcp 0 0 hostA:5555 hostB:6666 ESTABLISHED 19638/nc
运行tcpkill命令后,建立好的tcp连接并没有受到任何影响。
如果我们此时在hostB的nc上输入任意字符发送,则会发现这时tcp连接中断,nc发送失败退出。
hostB$ nc hostA 5555 -p 6666a<CR>(exit)
hostB$
hostA上的nc监听进程也因为连接中断而退出
hostA$ nc -l -p 5555(exit)
hostA$
netstat已经观察不到这个tcp连接,而tcpdump此时则捕获了一个新tcp rst包:
hostA# tcpdump -i eth1 port 5555IP hostB.6666 > hostA.5555: Flags [S], seq 750827752, ...IP hostA.5555 > hostB.6666: Flags [S.], seq 1191909671, ack 750827753, ...IP hostB.6666 > hostA.5555: Flags [.], ack 1, win 115, ...IP hostA.5555 > hostB.6666: Flags [R], seq 1191909672, ...
此时tcpkill的输出
hostA# tcpkill -1 -i eth1 port 5555tcpkill: listening on eth1 [port 5555]hostB:6666 > hostA:5555: R 1191909672:1191909672(0) win 0hostA:5555 > hostB:6666: R 750827755:750827755(0) win 0
相信看到这里,已经可以明白tcpkill的工作原理,实际上就是通过双向fake tcp rst包重置目标连接双方的网络连接,和某墙的原理一样。
而之所以tcpkill不会马上中断目标tcp连接,是因为伪造tcp rst包时,需要填入正确的sequence number,这需要通过拦截双方的tcp通信才能实时得到。所以运行tcpkill后,只有目标连接有新tcp包发送/接受才会导致tcp连接中断。
最后分析一下tcpkill第二个参数的具体作用。manpage里的说明比较模糊,只能看出和receive window有关:
-1...9 Specify the degree of brute force to use in killing a connection. Fast connections may require a higher number in order to land a RST in the moving receive window. Default is 3.
直接看源代码(只有100多行)
...intmain(int argc, char *argv[]){
... /* 通过libpcap抓取所有符合条件的包,回调函数为tcp_kill_cb */
pcap_loop(pd, -1, tcp_kill_cb, (u_char *)&sock);
...
}static voidtcp_kill_cb(u_char *user, const struct pcap_pkthdr *pcap, const u_char *pkt){
... /* 只处理tcp包 */
ip = (struct libnet_ip_hdr *)pkt; if (ip->ip_p != IPPROTO_TCP) return; /* 不处理tcp syn/fin/rst包 */
tcp = (struct libnet_tcp_hdr *)(pkt + (ip->ip_hl << 2)); if (tcp->th_flags & (TH_SYN|TH_FIN|TH_RST)) return; /* 伪造ip包 */
libnet_build_ip(TCP_H, 0, 0, 0, 64, IPPROTO_TCP,
ip->ip_dst.s_addr, ip->ip_src.s_addr,
NULL, 0, buf); /* 伪造tcp rst包 */
libnet_build_tcp(ntohs(tcp->th_dport), ntohs(tcp->th_sport), 0, 0, TH_RST, 0, 0, NULL, 0, buf + IP_H); /* fake tcp rst包的sequence number即为抓到的包的ack number */
seq = ntohl(tcp->th_ack);
... /* 这里Opt_severity即为tcpkill的第二个参数 */
win = ntohs(tcp->th_win); for (i = 0; i < Opt_severity; i++) {
ip->ip_id = libnet_get_prand(PRu16);
seq += (i * win);
tcp->th_seq = htonl(seq);
libnet_do_checksum(buf, IPPROTO_TCP, TCP_H); /* 发送伪造的tcp rst包 */
if (libnet_write_ip(*sock, buf, sizeof(buf)) < 0)
warn("write_ip");
fprintf(stderr, "%s R %lu:%lu(0) win 0\n", ctext, seq, seq);
}
}
从上面可以看出,tcpkill的第二个参数,实际上就是沿tcp连接窗口滑动而发送的tcp rst包个数。将这个参数设置较大主要是为了应对高速tcp连接的情况。
参数的大小从中断tcp连接的原理上没有区别,只是发送rst包数量的差异,通常情况下使用默认值3已经完全没有问题了。所以使用tcpkill时请不要像网络上某些中文教程中一样不适当的使用参数 -9 。
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 从互联网+角度看云计算的现状与未来
tcpkill工作原理分析的更多相关文章
- SPI协议及工作原理分析
说明.文章摘自:SPI协议及其工作原理分析 http://blog.csdn.net/skyflying2012/article/details/11710801 一.概述. SPI, Serial ...
- Security:蠕虫的行为特征描述和工作原理分析
________________________ 参考: 百度文库---蠕虫的行为特征描述和工作原理分析 http://wenku.baidu.com/link?url=ygP1SaVE4t4-5fi ...
- Azure WAF防火墙工作原理分析和配置向导
Azure WAF工作原理分析和配置向导 本文博客地址为:http://www.cnblogs.com/taosha/p/6716434.html ,转载请保留出处,多谢! 本地数据中心往云端迁移的的 ...
- Hadoop生态圈-Zookeeper的工作原理分析
Hadoop生态圈-Zookeeper的工作原理分析 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 无论是是Kafka集群,还是producer和consumer都依赖于Zoo ...
- 原理剖析-Netty之服务端启动工作原理分析(下)
一.大致介绍 1.由于篇幅过长难以发布,所以本章节接着上一节来的,上一章节为[原理剖析(第 010 篇)Netty之服务端启动工作原理分析(上)]: 2.那么本章节就继续分析Netty的服务端启动,分 ...
- AQS工作原理分析
AQS工作原理分析 一.大致介绍1.前面章节讲解了一下CAS,简单讲就是cmpxchg+lock的原子操作:2.而在谈到并发操作里面,我们不得不谈到AQS,JDK的源码里面好多并发的类都是通过Sy ...
- getaddrinfo工作原理分析
getaddrinfo工作原理分析 将域名解析成ip地址是所有涉及网络通讯功能程序的基本步骤之一,常用的两个接口是gethostbyname和getaddrinfo,而后者是Posix标准推荐在新应用 ...
- Mina工作原理分析
Mina是Apache社区维护的一个开源的高性能IO框架,在业界内久经考验,广为使用.Mina与后来兴起的高性能IO新贵Netty一样,都是韩国人Trustin Lee的大作,二者的设计理念是极为相似 ...
- 结合 category 工作原理分析 OC2.0 中的 runtime
绝大多数 iOS 开发者在学习 runtime 时都阅读过 runtime.h 文件中的这段代码: struct objc_class { Class isa OBJC_ISA_AVAILABILI ...
随机推荐
- Python解释器是单线程应用 IO 密集型 计算密集型 GIL global interpreter lock
[Python解释器是单线程应用] [任意时刻,仅执行一个线程] 尽管Python解释器中可以运行多个线程,但是在任意给定的时刻只有一个线程会被解释器执行. [GIL锁 保证同时只有一个线程运行] 对 ...
- SAP-财务知识点
[转自 http://blog.itpub.net/195776/viewspace-1023912/] SAP FI/CO Reading RepositorySAP财务成本知识库 目 录前言.一. ...
- Spring自定义配置--ConfigurationProperties
自定义配置的变量名: 在 *.properties 里面定义特定的变量 server.port=9000 amazon.associateId=habuma-20 建立Properties文件制定特定 ...
- jQuery 网页禁止复制
<script type="text/javascript"> $(document).ready(function(){ $('#文本框id') ...
- Laravel5.5执行表迁移命令出现表为空的解决方案
今天在使用一个第三方包 laravel-admin 时,出现了这样的错误:SQLSTATE[42000]: Syntax error or access violation: 1103 Incorre ...
- 《CSS权威指南(第三版)》---第四章 值和单位
本章主要讲解的是一些属性声明用的值: CSS中的值主要有数字,百分数,颜色, 1.颜色: rgb(100%,100%,100%) OR rgb(255,255,255) OR #FF0000 WE ...
- tomcat 1)启动时不识别执行启动命令 2)启动报错 3)关闭不了,用myEclipse启动时显示jvm_bind,端口占用
- 51Nod 1627 瞬间移动 —— 组合数学
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1627 1627 瞬间移动 基准时间限制:1 秒 空间限制:1 ...
- poj1328 Radar Installation —— 贪心
题目链接:http://poj.org/problem?id=1328 题解:区间选点类的题目,求用最少的点以使得每个范围都有点存在.以每个点为圆心,r0为半径,作圆.在x轴上的弦即为雷达可放置的范围 ...
- 鸟哥的linux私房菜 - 第5/6/7/9章(在线求助 man page、Linux档案权限与目录配置、Linux档案与目录管理、压缩与打包)
第五章.在线求助 man page X window与文本模式的切换 Ctrl+Alt+F1~F6:文字接口登入tty1~tty6终端机: Ctrl+Alt+F7:图形接口桌面. 注销当前用户:exi ...