tcpdump抓包分析实战-学习网络问题排查必备技能-抓包分析,附多个案例讲解

原创 吴就业 166 0 2024-02-06

本文为博主原创文章,未经博主允许不得转载。

本文链接:https://wujiuye.com/article/d7af16a165134b5a9312288bf2560683

作者:吴就业
链接:https://wujiuye.com/article/d7af16a165134b5a9312288bf2560683
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。

抓包分析是排查网络问题的必备技能,也是排查接口问题的有效手段。带着问题学习技能往往会更容易掌握,本篇介绍如何通过抓包分析解决实际问题。

三大案例:

服务端抓包

一、登录虚拟机执行tcpdump命令监听tcp数据包

在获得root权限的前提下,我们可以通过tcpdump命令监听指定端口的tcp数据包,例如:

tcpdump -i any "tcp and port 9099"

命令执行输出如下:

tcpdummp命令执行输出

单纯依靠这种方式我们很难从图中看出数据包是什么内容。不过tcpdump支持将数据包输出到文件,这样我们就可以通过借助其它工具来分析。

将tcpdump内容输出到文件可使用-w参数指定输出文件,例如:

tcpdump -i any -w ~/tcp_dump.pcap "tcp and port 9099"

执行此命令dump数据包将输出到~/目录下的tcp_dump.pcap文件。

然后将tcpdump的tcp数据包文件下载到本地。

二、使用Wireshark分析dump数据包

使用Wireshark工具难度较高,需要先掌握tcp协议。推荐给初学者的一个TCP数据包分析学习工具:https://www.chattcp.com/

安装Wireshark工具,使用Wireshark打开tcpdump下来的数据包。Wireshark的使用教程有很多,可以网上搜索学习。

Wireshark

三、抓HTTPS数据包

有时候应用会请求一些第三方的接口,只提供https域名。又或者抓线上数据包的时候,用的也是https协议。要分析这些数据包就需要拿到解密数据所需要的密钥。

这需要我们能拿到每次https建连完成TLS握手后生成的tls session key(Master Secret),该session key是TLS握手协商生成的对称加密密钥。

这里介绍三种场景下的session key获取方式。

  1. 在Chrome浏览器访问

使用Chrome浏览器访问接口或者使用curl命令访问接口的场景下。

Linux、Mac系统,在~/.profile文件下配置SSLKEYLOGFILE环境变量。

export SSLKEYLOGFILE=${自定义文件路径}
  1. 在应用代码里面访问

在应用里面调用第三方接口,需要抓取数据包分析的场景下,可以在代码里面配置输出session key日记到文件,再将文件从服务器上下载到本地。

以go为例:

func initHttpClient(){
    config := &tls.Config{
       KeyLogWriter: os.Stdout, // 这里是输出到控制台,改为输出到文件即可
    }
    transport := &http.Transport{
       TLSClientConfig: config,
    }
    httpCli = &http.Client{
      Transport: transport,
    }
}

日记内容如下:

CLIENT_RANDOM 566410c77ddd57eb1527b8dd6992ac23a44c3bf171bd3e9d8f708102c62a8fd6 cec00adeb348715f2e5f28cbccd809d31e3c50bac9a048e1fcf3414fab20f074fc3418ebef21c589f72268a7f7fff9e7
CLIENT_RANDOM 1c319799192126f896019e91baa72f764e2235bdc0357d854ee631d3c3601a64 634a2135e8e50eb44adc214088e2845c21a58f2654abac0f8e44289ec5257bf75754422252fabc9bc605f9d2a5cf2d33
  1. 在服务端输出session-key日记

Java JDK的SSLSessionImpl类记录了TLS/SSL协商过程中的Master Secret,可通过反射或者字节码插桩方式获取。例如开源的插桩实现工具extract-tls-secrets:https://github.com/neykov/extract-tls-secrets。(此方案对Netty无效)

Wireshark配置

依次打开配置页面:Perferences->Protocols->TLS,选择session key日记文件。

选择session key日记文件

在未配置之前

未配置session key之前

配置之后

配置session key之后

案例一:客户端发起IDL请求,连接不上网关

内部测试环境,客户端反馈发送IDL请求经常连接不上,然后过一会又可以,然后调通一次之后,kill掉app进程重启又不行了。

在部署网关的机器上抓包如下:

网关抓包

发现与客户端建立连接成功之后,立马就被服务端主动断开了。

原因是以前为了测试限流功能,配置了按连接数限流,超过1个连接之后,后面的连接就会被断开。

因为客户端是直接kill进程的,没主动关闭连接,而过一会后,前面建立的连接超时关闭了,所以后面再发起请求就又可以了。

案例二:服务端接收请求延迟十几秒

基于websocket实现的自定义请求响应协议。

测试反馈,并发请求会偶现服务端接收请求延迟十几秒的现象。

客户端日记打印消息发送时间与服务端打印的接收时间相差十几秒,并且客户端出现等待响应超时情况。

网络延迟不可能有十几秒,因此我们需要确定服务端接收到数据包的时间,是否与日记打印的时间相同,进一步排查问题。

通过tcpdump抓包,使用Wireshark分析dump文件,找到客户端发送的数据包如下。

Wireshark分析dump文件

而服务端打印的接收请求的日记如下。

服务端打印的接收请求的日记

对比抓包分析的服务端接收到数据包的时间,确实相差了十几秒,说明不是网络延迟问题,而是服务端的代码问题。

我们通过进一步分析服务端打印的日记,发现出现这种情况的时间点,都有打印kafka消息发送超时的错误信息。

进一步通过jstack查看,发现配置的200个核心线程的业务线程池只创建了4个线程,再分析日记,发现这个连接发送的请求都是由同一个线程处理。

综上我们可以得出结论。由于前面的请求阻塞在kafka消息发送,导致后续的请求都在排队,最终就是我们所看到的现象:服务端日记打印的接收时间比实际数据包到达时间晚了十几秒。

最后通过分析Netty源代码发现,我们配置的DefaultEventLoopGroup线程池,一个连接Netty只会通过next()绑定一个线程(EventLoop),该连接的所有消息都由这个线程处理。

案例三:并发出现数据包解码失败

消息推送系统(中间件)的架构:

  1. 请求响应的架构:客户端app -> 推送网关 -> 连接管理服务

  2. 推送消息的架构:客户端app <- 推送网关 <- 连接管理服务 <- 业务服务

在开发测试过程中,我们发现,推送网关使用单一连接并发请求连接管理服务,在连接管理服务侧会偶现解码失败,导致连接管理服务主动与推送网关断开连接。现象截图如下:

偶现解码失败

推送网关与连接管理服务之间的通信协议是WebSocket。推送网关使用go语言开发,使用gobwas实现WebSocket Clinet。连接管理服务使用Java语言开发,使用Netty实现WebSocket Server。

通过抓包分析,我们发现,WebSocket连接关闭数据包附近的几个数据包,有出现乱码包的情况。

gobwas发送乱码包

但这个数据包并不是我们发的,所以我们怀疑是gobwas这个库发的。为了排除是库的问题,我们把gobwas换成gorilla。而换gorilla之后,问题不再出现,所以确定是gobwas的问题。

总结

了解网络协议、学会利用tcpdump抓包,学会利用Wireshark分析数据包,将能帮助我们解决一些仅从客户端日记分析或仅从服务端日记分析无法解决的疑难杂症。

线上容器化部署我们很难通过tcpdump在服务端一侧抓包,需要在pod所在的node节点上抓包,并且真实环境网络流量大,并不适合抓包。不过通过Charles工具我们可以从客户端侧抓包,并支持https协议抓包,也能解决大部分接口问题。

#网络

声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。

文章推荐

NFS协议RPC通信数据包解码发现头4个字节不知道是什么?

当我们抓包并写代码解码的过程中发现,我们解码每个TCP数据包,无论是rpc请求还是rpc响应,都是要先跳过前四个字节,才是rpc协议的消息id,这样解码才正确,为什么呢?

nfs协议的rpc通信协议

通过开源项目go-nfs-client理解nfsv3的rpc通信协议,从而知道怎么解析抓取的数据包,获取需要的信息。

nfs协议,写文件流程分析

理解nfsv3协议的打开一个文件写和创建一个文件写的流程,以及相关操作的协议的理解、请求和响应的结构体的理解。

tcpdump抓包分析实战-客户端接收到网关响应的body是空的

只因请求头deviceId多了一个‘\n’导致,服务端接收到的body是空的。

带宽问题排查实战-记一次线上文件下载慢问题排查

上传的文件是仅办公网络可访问,办法室网络有带宽限制,一个页面加载上百张图片,很容易达到带宽限制,所以出现下载很慢。

从断点续传故障排查,分析浏览器是怎么实现断点续传的

自研实现文件上传下载的中间件在测试阶段发现断点续传有问题。具体表现是:使用wget下载mp4文件可以正常播放,用google浏览器打开链接,google浏览器无法正常播放mp4视频。