最近一直在进行http数据请求调试找到了一块比较好用的数据抓包调试工具 tcpdump 是一个比较轻量化,强大的抓包分析工具
 tcpdump ,就是: dump the traffic on a network ,根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump 可以将网络中传送的数据包的 完全截获下来提供分析,它支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用的信息。

tcpdump linux下安装下载

linux下安装下载 tcpdump 很简单

yum -y install tcpdump

tcpdump 命令使用参数说明大全

-a 尝试将网络和广播地址转换成名称。
-c<数据包数目> 收到指定的数据包数目后,就停止操作。
# 例如:tcpdump -i ens33 -c 20
-d 把编译过的数据包编码转换成可阅读的格式
-dd 把编译过的数据包编码转换成C语言的格式
-ddd 把编译过的数据包编码转换成十进制数字的格式
-e 在每列倾倒资料上显示连接层级的文件头。
-f 用数字显示网际网络地址。
-F<表达文件> 指定内含表达方式的文件。
-i<网卡> 使用指定的网卡送出数据包。
# 例如:tcpdump -i ens33 指定网卡
# 例如:tcpdump -i any 任意网卡
-l 使用标准输出列的缓冲区。
-n 不把主机的网络地址转换成名字。
-N 不列出域名。
-O 不将数据包编码最佳化。
-p 不让网络界面进入混杂模式。
-q 精简模式,仅列出少数的传输协议信息。
# 例如:tcpdump -i ens33 -q
-r<数据包文件> 从指定的文件读取数据包数据。
-s<数据包大小> 设置每个数据包的大小。
-s 0 : 抓取数据包时默认抓取长度为68字节。加上-S 0 后可以抓到完整的数据包
-S 用绝对而非相对数值列出TCP关联数。
-t 在每列倾倒资料上不显示时间戳记。
-tt 在每列倾倒资料上显示未经格式化的时间戳记。
-T<数据包类型> 强制将表达方式所指定的数据包转译成设置的数据包类型。
-v 详细显示指令执行过程。
# tcpdump -i ens33 host www.baidu.com -v 然后 另外窗口curl www.baidu.com/aaa 测试
-vv 更详细显示指令执行过程。
-x 用十六进制字码列出数据包资料。
-w<数据包文件> 把数据包数据写入指定的文件。
# tcpdump 对截获的数据并没有进行彻底解码,数据包内的大部分内容是使用十六进制的形式直接打印输出的。显然这不利于分析网络故障,通常的解决办法是先使用带-w参数的tcpdump 截获数据并保存到文件中,然后再使用其他程序(如Wireshark)进行解码分析
-W 保留文件数,通常和-w和-C一起使用
# tcpdump -i ens33 -w ./test.cap -W 5 -C 2(文件大小)
# 上面是抓包保存到当前目录的test.cap里面 每个文件2M,保留5个文件
-C  file-size (nt: 此选项用于配合-w file 选项使用) 单位M

使用 tcpdump 测试抓取

 使用 tcpdump 抓取指定主机域名等数据包

# 抓取 访问 www.baidu.com 的数据包
tcpdump -i ens33 host www.baidu.com
# 抓取 多个域名的 and or
tcpdump -i ens33 host www.baidu.com or www.qq.com
# 支持使用括号,但是需要转义
tcpdump -i ens33 host www.baidu.com and \( aaa or bbb \)
# 排除操作 and not 抓取和www.baidu.com之间的所有交互,但是忽略和192.168.1.9
tcpdump -i ens33 host www.baidu.com and not 192.168.1.9
# 去程,发送请求的主机
tcpdump -i ens33 src host www.baidu.com
# 回程,响应的主机
tcpdump -i ens33 dst host www.baidu.com

 使用 tcpdump 抓取本机网络输入输出的指定端口数据包

# 抓取 80 端口
tcpdump -i any port 80

关于使用 tcpdump 抓包中的 TCP 三次握手

Flags  # 这个包所携带的标志:
S=SYN  # 发起连接标志。
P=PUSH # 传送数据标志。
F=FIN  # 关闭连接标志。
ack    # 表示确认包。
RST=RESET  # 异常关闭连接。
.            # 表示没有任何标志。
()           # 括号中的数字是包的长度,建立连接和关闭连接时,包长都为0,括号前面的都是序列号。

使用 tcpdump 观察 Redis 连接情况

  1. Redis客户端通知Redis服务端:我要建立链接
  2. Redis服务端通知Redis客户端:收到,你准备好了,可以链接了
  3. Redis客户端通知Redis服务端:ok,建立链接
    kt827o85.png

配置 Redis 长连接后使用 tcpdump 观察连接过程

kt829h1g.png

 使用 tcpdump 可以看到第一次是三次握手,第二次刷新页面时候,没有重新三次握手,而是发送了echo 一个随机字符串来验证redis链接,这个应该是redis驱动在fpm里面做的
### 观察 TCP 四次挥手
 使用 tcpdump 测试访问www.baidu.com的80端口四次挥手释放链接

tcpdump -i any port 80 and host www.baidu.com -s 0
curl www.baidu.com

kt82cqox.png

 redis 短链接时候,使用 tcpdump 测试观察连接关闭过程

tcpdump -i any port 6379 -s 0

 可以通过 tcpdump 看到这个过程中,其实第二次和第三次挥手是一起进行的,所以抓包只看到三个
kt82ejl0.png

 redis 长连接时候,重启fpm进程,使用 tcpdump 观察连接关闭过程

tcpdump -i any port 6379 -s 0

kt82h95t.png

tcpdump 异常问题统计

  • tcpdump: packet printing is not supported for link type NFLOG: use -w
    默认网卡的问题,通过ifconfig查看网卡名称 ens33

    tcpdump -i ens33
    # 或者抓取所有网卡
    tcpdump -i any

关于 tcpdump 使用方法及实践测试老马已经全部分享完了

参考文档