[转帖]《Linux性能优化实战》笔记(20)—— 使用 tcpdump 和 Wireshark 分析网络流量
tcpdump 和 Wireshark 是最常用的网络抓包和分析工具,更是分析网络性能必不可少的利器。
tcpdump 仅支持命令行格式使用,常用在服务器中抓取和分析网络包。Wireshark 除了可以抓包,还提供了强大的图形界面和汇总分析工具,在分析复杂的网络情景时,尤为简单和实用。因而,在实际分析网络性能时,先用 tcpdump 抓包,后用 Wireshark 分析,也是一种常用的方法。安装方法如下:
-
# Ubuntu
-
apt-get install tcpdump wireshark
-
# CentOS
-
yum install -y tcpdump wireshark
由于 Wireshark 的图形界面,并不能通过 SSH 使用,推荐在本地机器(比如 Windows)中安装。可以到 https://www.wireshark.org/ 下载并安装 Wireshark。
一、 再探 ping
虽然 ping 比较简单,但有时ping 工具本身也可能出现异常,比如运行缓慢,但实际网络延迟却并不大的情况。
接下来,我们执行下面的命令测试案例机器与极客邦科技官网的连通性和延迟。如果一切正常,你会看到下面这个输出:
-
# ping 3 次(默认每次发送间隔1秒)
-
# 假设DNS服务器还是上一期配置的114.114.114.114
-
$ ping -c3 geektime.org
-
PING geektime.org (35.190.27.188) 56(84) bytes of data.
-
64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=1 ttl=43 time=36.8 ms
-
64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=2 ttl=43 time=31.1 ms
-
64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=3 ttl=43 time=31.2 ms
-
-
--- geektime.org ping statistics ---
-
3 packets transmitted, 3 received, 0% packet loss, time 11049ms
-
rtt min/avg/max/mdev = 31.146/33.074/36.809/2.649 ms
假如你运行时发现 ping 很快就结束了,那就执行下面的命令后再重试一下。至于这条命令的含义,稍后我们再做解释。
-
# 禁止接收从DNS服务器发送过来并包含googleusercontent的包
-
$ iptables -I INPUT -p udp --sport 53 -m string --string googleusercontent --algo bm -j DROP
根据 ping 的输出,geektime.org 解析后的 IP 地址是 35.190.27.188,而后三次 ping 请求都得到了响应,延迟(RTT)都是 30ms 多一点。但汇总的地方,3 次发送,收到 3 次响应,没有丢包,但三次发送和接受的总时间居然超过了 11s(11049ms),这就有些不可思议了吧。
你可能会怀疑,这是不是 DNS 解析缓慢的问题?再回去看 ping 的输出,三次 ping 请求中,用的都是 IP 地址,说明 ping 只需要在最开始运行时,解析一次得到 IP,后面就可以只用 IP 了。
我们再用 nslookup 试试。在终端中执行下面的 nslookup 命令,这次我们同样加了 time 命令,输出 nslookup 的执行时间:
-
time nslookup geektime.org
-
#输出
-
Server: 114.114.114.114
-
Address: 114.114.114.114#53
-
-
Non-authoritative answer:
-
Name: geektime.org
-
Address: 35.190.27.188
-
-
real 0m0.044s
-
user 0m0.006s
-
sys 0m0.003s
可以看到,域名解析还是很快的,只需要 44ms,显然比 11s 短了很多。再往后该怎么分析呢?其实,这时候就可以用 tcpdump 抓包,查看 ping 在收发哪些网络包。
二、 tcpdump 与简单案例
再打开另一个终端,执行下面的命令
tcpdump -nn udp port 53 or host 35.190.27.188
- -nn:不解析抓包中的域名(即不反向解析)、协议及端口号。
- udp port 53:只显示 UDP 协议的端口号(包括源端口和目的端口)为 53 的包。
- host 35.190.27.188:只显示 IP 地址(包括源地址和目的地址)为 35.190.27.188的包。
- or:只要满足上面两个条件中的任一个,就可以展示出来。
接下来,回到终端一,执行相同的 ping 命令:
-
$ ping -c3 geektime.org
-
...
-
--- geektime.org ping statistics ---
-
3 packets transmitted, 3 received, 0% packet loss, time 11095ms
-
rtt min/avg/max/mdev = 81.473/81.572/81.757/0.130 ms
命令结束后,再回到终端二中,查看 tcpdump 的输出:
-
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
-
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
-
14:02:31.100564 IP 172.16.3.4.56669 > 114.114.114.114.53: 36909+ A? geektime.org. (30)
-
14:02:31.507699 IP 114.114.114.114.53 > 172.16.3.4.56669: 36909 1/0/0 A 35.190.27.188 (46)
-
14:02:31.508164 IP 172.16.3.4 > 35.190.27.188: ICMP echo request, id 4356, seq 1, length 64
-
14:02:31.539667 IP 35.190.27.188 > 172.16.3.4: ICMP echo reply, id 4356, seq 1, length 64
-
14:02:31.539995 IP 172.16.3.4.60254 > 114.114.114.114.53: 49932+ PTR? 188.27.190.35.in-addr.arpa. (44)
-
14:02:36.545104 IP 172.16.3.4.60254 > 114.114.114.114.53: 49932+ PTR? 188.27.190.35.in-addr.arpa. (44)
-
14:02:41.551284 IP 172.16.3.4 > 35.190.27.188: ICMP echo request, id 4356, seq 2, length 64
-
14:02:41.582363 IP 35.190.27.188 > 172.16.3.4: ICMP echo reply, id 4356, seq 2, length 64
-
14:02:42.552506 IP 172.16.3.4 > 35.190.27.188: ICMP echo request, id 4356, seq 3, length 64
-
14:02:42.583646 IP 35.190.27.188 > 172.16.3.4: ICMP echo reply, id 4356, seq 3, length 64
前两行表示 tcpdump 的选项以及接口的基本信息
从第三行开始,就是抓取到的网络包的输出。这些输出的格式,都是 时间戳 协议 源地址.源端口 > 目的地址.目的端口 网络包详细信息(这是最基本的格式,可以通过选项增加其他字段)。
比如,第一条就表示,从本地 IP 发送到 114.114.114.114 的 A 记录查询请求,它的报文格式记录在 RFC1035 中。36909+ 表示查询标识值,它也会出现在响应中,加号表示启用递归查询。A? 表示查询 A 记录。geektime.org. 表示待查询的域名。30 表示报文长度。
第二条,则是从 114.114.114.114 发送回来的 DNS 响应:域名 geektime.org.的 A 记录值为 35.190.27.188。
第三条和第四条,是 ICMP echo request 和 ICMP echo reply,响应包的时间戳14:02:31.539667,减去请求包的时间戳 14:02:31.508164 ,就可以得到,这次 ICMP 所用时间为 30ms。这看起来并没有问题。
随后的两条反向地址解析 PTR 请求,就比较可疑了。因为我们只看到了请求包,却没有应答包。仔细观察它们的时间,你会发现,这两条记录都是发出后 5s 才出现下一个网络包,两条 PTR 记录就消耗了 10s。
再往下看,最后的四个包,则是两次正常的 ICMP 请求和响应,根据时间戳计算其延迟也是 30ms。到这里,其实我们也就找到了 ping 缓慢的根源,正是两次 PTR 请求没有得到响应而超时导致的。PTR 反向地址解析的目的,是从 IP 地址反查出域名,但事实上,并非所有 IP 地址都会定义 PTR 记录,所以 PTR 查询很可能会失败。
所以,在你使用 ping 时,如果发现结果中的延迟并不大,而 ping 命令本身却很慢,不要慌,有可能是背后的 PTR 在搞鬼。
知道问题后,解决起来就比较简单了,只要禁止 PTR 就可以。执行 man ping 命令,查询使用手册,就可以找出相应的方法,加上 -n 选项禁止名称解析。
-
ping -n -c3 geektime.org
-
#输出
-
PING geektime.org (35.190.27.188) 56(84) bytes of data.
-
64 bytes from 35.190.27.188: icmp_seq=1 ttl=43 time=33.5 ms
-
64 bytes from 35.190.27.188: icmp_seq=2 ttl=43 time=39.0 ms
-
64 bytes from 35.190.27.188: icmp_seq=3 ttl=43 time=32.8 ms
-
-
--- geektime.org ping statistics ---
-
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
-
rtt min/avg/max/mdev = 32.879/35.160/39.030/2.755 ms
你可以发现,现在只需要 2s 就可以结束,比刚才的 11s 可是快多了。
案例最后,如果你在开始时执行了 iptables 命令,那也不要忘了删掉它:
iptables -D INPUT -p udp --sport 53 -m string --string googleusercontent --algo bm -j DROP
不过,删除后你肯定还有疑问,明明我们的案例跟 Google 没啥关系,为什么要根据googleusercontent ,这个毫不相关的字符串来过滤包呢?实际上,如果换一个 DNS 服务器,就可以用 PTR 反查到 35.190.27.188 所对应的域名:
-
nslookup -type=PTR 35.190.27.188 8.8.8.8
-
#输出
-
Server: 8.8.8.8
-
Address: 8.8.8.8#53
-
Non-authoritative answer:
-
188.27.190.35.in-addr.arpa name = 188.27.190.35.bc.googleusercontent.com.
-
Authoritative answers can be found from:
你看,虽然查到了 PTR 记录,但结果并非 geekbang.org,而是188.27.190.35.bc.googleusercontent.com。其实,这也是为什么,案例开始时将包含googleusercontent 的丢弃后,ping 就慢了。因为 iptables 实际上是把 PTR 响应给丢了,导致 PTR 请求超时。
三、 tcpdump更多用法
tcpdump 是最常用的网络分析工具。它基于 libpcap ,利用内核中的 AF_PACKET 套接字,抓取网络接口中传输的网络包;并提供了强大的过滤规则,帮你从大量的网络包中,挑出最想关注的信息。
tcpdump 为你展示了每个网络包的详细细节,这就要求,在使用前,你必须要对网络协议有基本了解。而要了解网络协议的详细设计和实现细节,RFC 当然是最权威的资料。不过,RFC 的内容,对初学者来说可能并不友好。如果你对网络协议还不太了解,推荐你去学《TCP/IP 详解》,特别是第一卷的 TCP/IP 协议族。这是每个程序员都要掌握的核心基础知识。
tcpdump 工具的基本使用方法就是 tcpdump [选项] [过滤表达式],选项和表达式的外面都加了中括号,表明它们都是可选的
我在这里也帮你整理了一些最常见的用法,并且绘制成了表格,你可以参考使用。
接下来,我们再来看常用的过滤表达式。刚刚用过的是 udp port 53 or host 35.190.27.188 ,表示抓取 DNS 协议的请求和响应包,以及源地址或目的地址为 35.190.27.188 的包。其他常用的过滤选项,我也整理成了下面这个表格
最后,再次强调 tcpdump 的输出格式,我在前面已经介绍了它的基本格式:时间戳 协议 源地址.源端口 > 目的地址.目的端口 网络包详细信息。
时间戳 协议 源地址.源端口 > 目的地址.目的端口 网络包详细信息
其中,网络包的详细信息取决于协议,不同协议展示的格式也不同。所以,更详细的使用方法,还是需要你去查询 tcpdump 的 man 手册(执行 man tcpdump 也可以得到)。不过,讲了这么多,你应该也发现了。tcpdump 虽然功能强大,可是输出格式却并不直观。特别是,当系统中网络包数比较多(比如 PPS 超过几千)的时候,你想从 tcpdump抓取的网络包中分析问题,实在不容易。
对比之下,Wireshark 则通过图形界面,以及一系列的汇总分析工具,提供了更友好的使用界面,让你可以用更快的速度,摆平网络性能问题。接下来,我们就详细来看看它。
四、 Wireshark
Wireshark 也是最流行的一个网络分析工具,它最大的好处就是提供了跨平台的图形界面。跟 tcpdump 类似,Wireshark 也提供了强大的过滤规则表达式,同时,还内置了一系列的汇总分析工具。
比如,拿刚刚的 ping 案例来说,你可以执行下面的命令,把抓取的网络包保存到 ping.pcap 文件中:
tcpdump -nn udp port 53 or host 35.190.27.188 -w ping.pcap
接着,把它拷贝到你安装有 Wireshark 的机器中,再用 Wireshark 打开它。打开后,你就可以看到下面这个界面:
它不仅以更规整的格式展示了各个网络包的头部信息,还用不同颜色展示 DNS 和 ICMP 这两种不同的协议。你也可以一眼看出,中间的两条 PTR 查询并没有响应包。
接着,选择某一个网络包后,在其下方的网络包详情中还可以看到这个包在协议栈各层的详细信息。比如,以编号为 5 的 PTR 包为例:
你可以看到,IP 层的源地址和目的地址、传输层的 UDP 协议、应用层的 DNS 协议的概要信息。继续点击每层左边的箭头,就可以看到该层协议头的所有信息。比如点击 DNS 后,就可以看到 Transaction ID、Flags、Queries 等 DNS 协议各个字段的数值以及含义。
使用案例
接下来再看一个 HTTP 的例子,并理解 TCP 三次握手和四次挥手的工作原理。
这个案例我们将要访问的是 http://example.com/ 。
进入终端一,首先执行dig查出 example.com 的 IP,然后执行 tcpdump 过滤得到的 IP 地址,并将结果保存到 web.pcap 中。也直接使用域名,即 tcpdump -nn host example.com -w web.pcap。
-
$ dig +short example.com
-
93.184.216.34
-
$ tcpdump -nn host 93.184.216.34 -w web.pcap
接下来,切换到终端二,执行下面的 curl 命令,访问 http://example.com:
curl http://example.com
最后,再回到终端一,按下 Ctrl+C 停止 tcpdump,并把得到的 web.pcap 拷贝出来。使用 Wireshark 打开
由于 HTTP 基于 TCP ,所以你最先看到的三个包,分别是 TCP 三次握手的包。接下来,中间的才是 HTTP 请求和响应包,而最后的三个包,则是 TCP 连接断开时的三次挥手包。
从菜单栏中,点击 Statistics -> Flow Graph,然后,在弹出的界面中的 Flow type 选择TCP Flows,你可以更清晰的看到,整个过程中 TCP 流的执行过
这其实跟各种教程上讲到的,TCP 三次握手和四次挥手很类似
不过,对比这两张图,这里抓到的包跟上面的四次挥手并不完全一样,实际挥手过程只有三个包,而不是四个。
其实,之所以有三个包,是因为服务器端收到客户端的 FIN 后,服务器端同时也要关闭连接,这样就可以把 ACK 和 FIN 合并到一起发送,节省了一个包,变成了“三次挥手”。而通常情况下,服务器端收到客户端的 FIN 后,很可能还没发送完数据,所以就会先回复客户端一个 ACK 包。稍等一会儿,完成所有数据包的发送后,才会发送 FIN 包。这也就是四次挥手了。
抓包后, Wireshark 中就会显示下面这个界面
当然,Wireshark 的使用方法绝不只有这些,更多的使用方法,同样可以参考 官方文档 以及 WIKI。
[转帖]《Linux性能优化实战》笔记(20)—— 使用 tcpdump 和 Wireshark 分析网络流量的更多相关文章
- 深挖计算机基础:Linux性能优化学习笔记
参考极客时间专栏<Linux性能优化实战>学习笔记 一.CPU性能:13讲 Linux性能优化实战学习笔记:第二讲 Linux性能优化实战学习笔记:第三讲 Linux性能优化实战学习笔记: ...
- Linux性能优化实战学习笔记:第三十八讲
一.上节回顾 上一节,我们学习了 DNS 性能问题的分析和优化方法.简单回顾一下,DNS 可以提供域名和 IP 地址的映射关系,也是一种常用的全局负载均衡(GSLB)实现方法. 通常,需要暴露到公网的 ...
- 《Linux 性能优化实战—倪朋飞 》学习笔记 CPU 篇
平均负载 指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,即平均活跃进程数 可运行状态:正在使用CPU或者正在等待CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态 (Run ...
- Linux性能优化实战学习笔记:第三十一讲
一.上节回顾 上一节,我们一起回顾了常见的文件系统和磁盘 I/O 性能指标,梳理了核心的 I/O 性能观测工具,最后还总结了快速分析 I/O 性能问题的思路. 虽然 I/O 的性能指标很多,相应的性能 ...
- Linux性能优化实战学习笔记:第三十二讲
一.上节总结 专栏更新至今,四大基础模块的第三个模块——文件系统和磁盘 I/O 篇,我们就已经学完了.很开心你还没有掉队,仍然在积极学习思考和实践操作,并且热情地留言与讨论. 今天是性能优化的第四期. ...
- Linux性能优化实战学习笔记:第三十五讲
一.上节回顾 前面内容,我们学习了 Linux 网络的基础原理以及性能观测方法.简单回顾一下,Linux网络基于 TCP/IP 模型,构建了其网络协议栈,把繁杂的网络功能划分为应用层.传输层.网络层. ...
- Linux性能优化实战学习笔记:第三十六讲
一.上节总结回顾 上一节,我们回顾了经典的 C10K 和 C1000K 问题.简单回顾一下,C10K 是指如何单机同时处理 1 万个请求(并发连接 1 万)的问题,而 C1000K 则是单机支持处理 ...
- Linux性能优化实战学习笔记:第四十讲
一.上节回顾 上一节,我们学习了碰到分布式拒绝服务(DDoS)的缓解方法.简单回顾一下,DDoS利用大量的伪造请求,导致目标服务要耗费大量资源,来处理这些无效请求,进而无法正常响应正常用户的请求. 由 ...
- Linux性能优化实战学习笔记:第四十五讲
一.上节回顾 专栏更新至今,四大基础模块的最后一个模块——网络篇,我们就已经学完了.很开心你还没有掉队,仍然在积极学习思考和实践操作,热情地留言和互动.还有不少同学分享了在实际生产环境中,碰到各种性能 ...
- Linux性能优化实战学习笔记:第四十七讲
一.上节回顾 上一节,我们梳理了,应用程序容器化后性能下降的分析方法.一起先简单回顾下.容器利用 Linux 内核提供的命名空间技术,将不同应用程序的运行隔离起来,并用统一的镜像,来管理应用程序的依赖 ...
随机推荐
- JavaScript 常见错误与异常处理
一.为什么要了解常见JS错误 1.调试和故障排除: 了解常见的JavaScript错误可以帮助你更好地调试和故障排除代码.当你遇到错误时,能够快速识别错误类型并找到解决方法,可以节省大量的时间和精力. ...
- 中文语音识别转文字的王者,阿里达摩院FunAsr足可与Whisper相颉顽
君不言语音识别技术则已,言则必称Whisper,没错,OpenAi开源的Whisper确实是世界主流语音识别技术的魁首,但在中文领域,有一个足以和Whisper相颉顽的项目,那就是阿里达摩院自研的Fu ...
- 文心一言 VS 讯飞星火 VS chatgpt (137)-- 算法导论11.3 3题
三.用go语言,考虑除法散列法的另一种版本,其中 h(k) = k mod m,m=$2^p-1$,k为按基数 $2^p$ 表示的字符串.试证明:如果串可由串 y 通过其自身的字符置换排列导出,则x和 ...
- 文心一言 VS 讯飞星火 VS chatgpt (36)-- 算法导论5.3 6题
六.请解释如何实现算法 PERMUTE-BY-SORTING,以处理两个或更多优先级相同的情形.也就是说,即使有两个或更多优先级相同,你的算法也应该产生一个均匀随机排列. 文心一言: 算法 PERMU ...
- Typora+Docsify快速入门
Typora是什么? Typora中文版是一款好用极简的跨平台Markdown编辑器,软件使用这款软件能够帮助用户轻松将文本转换到HTML,软件从底层向上设计,软件支持markdown的标准语法, ...
- 详解数据库SQL中的三个语句:DROP、TRUNCATE 、DELETE
本文分享自华为云社区<GaussDB数据库SQL系列-DROP & TRUNCATE & DELETE>,作者:Gauss松鼠会小助手2 . 一.前言 在数据库中,SQL作 ...
- DWS轻量化更新黑科技:宽表加工优化
本文分享自华为云社区<GaussDB(DWS)性能调优:宽表加工优化方案>,作者:譡里个檔 . 1. 业务背景 宽表加工性能慢,在Gauss(DWS)中可以使用DWS的轻量化更新的黑科技实 ...
- 无法安装此app,因为无法验证其完整性 ,解决方案
最近有很多兄弟萌跟我反应"无法安装此app,因为无法验证其完整性 ",看来这个问题无法避免了,今天统一回复下,出现提示主要有以下几种可能 1.安装包不完整 首先申请我所有分享的破解 ...
- 一文了解 DataLeap 中的 Notebook
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 概述 Notebook 是一种支持 REPL 模式的开发环境.所谓「REPL」,即「读取-求值-输出」循环:输入一 ...
- Docker 安装 kafka
简单安装为了集成 SpringBoot,真实使用,增加增加更多配置,比如将log映射出来 1.安装 zookeeper [root@centos-linux ~]# docker pull wurst ...