常用的网络工具 Wireshark 和 tcpdump
WireShark
为什么要抓包
1、 定位网络问题;
2、 分析接口数据;
3、 学习网络协议, 使用抓包工具分析网络数据更直观。
大部分场合都可以通过程序调试来定位问题, 但有些场景使用抓包来定位接口问题更准
确、 更方便, 如以下场景:
1、 你发送数据给后台, 但后台没有收到, 可以对接口进行抓包分析, 看是后台处理有
问题, 还是没有将数据发出去, 或是发送数据格式有误;
2、 你和后台接口联调测通, 但业务数据对不上, 你认为是后台问题, 后台认为是你发
的问题, 可以抓包确认问题所在;
3、 线上出现 bug 需要定位, 但你没在公司, 没有代码可调试, 可直接抓包分析;
4、 系统性能不佳, 抓包看下接口响应时长, 是不是后台出现性能问题。
常用的抓包工具有: F12(浏览器自带的抓包工具) 、 Fiddler、 Charles, Wireshark。 而
Wireshark 在支持的协议, 用户友好度、 价格(开源) 、 程序支持、 支持的操作系统上都很
好, 所以 Wireshark 也是我们最常用的抓包工具和报文分析工具。
下载与安装
在 https://www.wireshark.org/的官方主页点击
进入下载页面, 选择适合自己的版本下载即可
Wireshark 的安装很简单, 就是一般的 windows 程序的安装流程, 如遇问题自行百度解
决。
数据包的捕获和基本用法
基本用法
运行 Wireshark, 稍等, 就会让我们选择捕获哪个设备(连接) 的数据包
当前我们活跃的是“以太网” , 双击这一行, Wireshark 开始捕获数据, 并在窗口中显
示, 可以看见随着时间前进, 窗口中不断刷新。 等上几秒钟, 结束捕获, 单机工具栏中的
按钮, 或者“捕获” 下拉菜单中选择“停止” 选项即可。
这个时候可以看见, Wireshark 窗口中显示了大量的数据:
数据包列表: 最上面的面板用表格显示了当前捕获文件中的所有数据包, 其中包括了数
据包序号、 数据包被捕获的相对时间、 数据包的源地址和目标地址、 数据包的协议以及在数
据包中找到的概况信息等列。
包详情: 中间的面板分层次地显示了一个数据包中的内容, 并且可以通过展开或是收缩
来显示这个数据包中所捕获到的全部内容。
包数据的字节形式显示: 最下面的面板显示了一个数据包未经处理的原始样子, 也就是
其在链路上传播时的样子。 这些原始数据当然不容易理解。
在数据包列表中, 可以很明显看见每行的五颜六色, 这些颜色其实是 Wireshark 用来区
分不同的协议的。 可以通过 Coloring Rules (着色规则) 窗口可以很容易地查看或修改每个协
议所对应的颜色。 如果想要打开这个窗口, 可以在“视图” 下拉菜单中选择的“着色规则”
选项即可。
同时捕获的数据包可以导出为文件, 也可以将数据包文件导入 Wireshark 进行分析。
过滤器
过滤器可以让你找出你所希望进行分析的数据包。 简单来说, 一个过滤器就是定义了一
定条件, 用来包含或者排除数据包的表达式。 如果你不希望看到一些数据包, 你可以写一个
过滤器来屏蔽它们。 如果你希望只看到某些数据包, 你可以写一个只显示这些数据包的过滤
器。
Wireshark 主要提供两种主要的过滤器。
· 捕获过滤器:当进行数据包捕获时, 只有那些满足给定的包含/排除表达式
的数据包会被捕获。
显示过滤器:该过滤器根据指定的表达式用于在一个已捕获的数据包集合中, 隐藏不想
显示的数据包, 或者只显示那些需要的数据包。
捕获过滤器
捕获过滤器用于进行数据包捕获的实际场合, 使用它的一个主要原因就是性能。 如果你
知道你并不需要分析某个类型的流量, 你可以简单地使用捕获过滤器过滤掉它, 从而节省那
些会被用来捕获这些数据包的资源。
比如, 我们现在要捕获我们机器上所有 UDP 类型的数据包, 怎么做? 在“捕获” 下拉
菜单中选择“选型” , 弹出窗口中
选择或者输入 UDP, 然后单击“开始” 按钮进行捕获。
捕获过滤器的 BPF 语法
捕获过滤器应用于 WinPcap/NPcap, 并使用 Berkeley Packet Filter(BPF) 语法。
这个语法被广泛用于多种数据包嗅探软件, 主要因为大部分数据包嗅探软件都依赖于使
用 BPF 的 libpcap/WinPcap 库。 掌握 BPF 语法对你在数据包层级更深入地探索网络来说,
非常关键。
使用 BPF 语法创建的过滤器被称为表达式, 并且每个表达式包含一个或多个原语。 每
个原语包含一个或多个限定词, 然后跟着一个 ID 名字或者数字
Type 指出名字或数字所代表的意, 例如: host、 port
Dir 指明传输方向是前往还是来自 例如: src、 dst
Proto 限定所要匹配的协议 例如: ether、 ip、 tcp、 udp、 http、 ftp
例如:
dst host 192.168.0.10 && tcp port 80
这是一个捕获过滤器样例, 其中“dst host 192.168.0.10” 就构成了一个原语, 我们的样
例里有两个原语, 两个原语用逻辑运算符“&&” 组合了起来。 逻辑运算符共有三个:
连接运算符: 与 (&&)
选择运算符: 或 (||)
否定运算符: 非 (!)
对我们的样例来说, 表示捕获的数据包应该满足条件为: 目的主机是 192.168.0.10, 通
信协议是 tcp, 源端口或者目的端口是 80。
主机名和地址过滤器
我们所创建的大多数过滤器都会关注于一个或一些特定的网络设备。 根据这个情况, 可
以根据设备的 MAC 地址、 IPv4 地址、 IPv6 地址或者 DNS 主机名配置过滤规则。 比如:
捕获所有和主机 IPv4 地址相关的流量:
host 192.168.0.10
捕获所有和主机 Ipv6 地址相关的流量:
host fe80::1945:cbf1:1393:8f17
使用基于一台设备的主机名 host 限定词进行过滤:
host remoteserver
考虑到一台主机的 IP 地址可能会变化, 你可以通过加入 ether 协议限定词, 对它的 MAC
地址进行过滤:
Ether host 24-41-8C-26-04-9F
当然还可在 host 之前加 src 或者 dst 进行传输方向的限定。
端口和协议过滤器
只对 8080 端口进行流量捕获:
port 8080
想要捕获除 8080 端口外的所有流量
!port 8080
端口过滤器一样和传输方向限定符一起使用, 比如:
dst port 80
协议过滤器可以让我们基于特定协议进行数据包过滤。 BPF 语法甚至提供给我们的一项
强大功能, 就是我们可以通过检查协议头中的每一字节来创建基于那些数据的特殊过滤器。
比如:
tcp[13]&4=4
表示捕获的数据是 tcp 协议的数据包, 且 tcp 数据包中第 13 个字节的第 4 位被设置了。
显示过滤器
显示过滤器应用于捕获文件, 用来告诉 Wireshark 只显示那些符合过滤条件的数据包。
你可以在包列表面板上方的 Filter 文本框中, 输入一个显示过滤器。
显示过滤器的语法不同于捕获过滤器, 比如我们通过捕获功能, 捕获了本机所有的数据
包
现在我们不需要看 UDP 类型的数据包, 只需输入:
!udp
可以看见所有的 udp 类型的数据包不再显示了:
现在我们多加一个限定, 只显示 ip 地址为 40.90.189.152(新加坡 Microsoft 数据中心)
的数据包
可以看见, 显示的数据包就变为: 不是 udp 数据包, 同时源地址或者目的地址是
40.90.189.152。
在我们上面的过滤条件“!udp and ip.addr==40.90.189.152” 中, 牵涉到了过滤条件的比
较操作符和逻辑操作符:
比较操作符可以让你进行值的比较。 举例来说, 当你在检查一个 TCP/P 网络中的问题
时, 你可能经常需要检查和某一个 IP 地址相关的数据包。 等于操作符可以让你创建一个只
显示 192.168.0.1 这个 IP 地址相关数据包的过滤器。
ip.addr==192.168.0.1
比较操作符还有:
等于 ==
不等于 !=
大于 >
小于 <
大于或等于 >=
小于或等于 <=
逻辑操作符有:
and 两个条件需同时满足
or 其中一个条件被满足
xor 有且仅有一个条件被满足
not 没有条件被满足
尽管在理论上编写过滤器表达式很简单, 但针对不同问题创建过滤器时, 依然需要许多
特定的关键词与操作符。 可以到 Wireshark 的官网查看:
https://www.wireshark.org/docs/dfref
比如 tcp 相关的, 可以通过单击具体条目查看更多:
预定义过滤器
过滤器可以事先设置好, 不需要每次使用时都重新输入, 捕获过滤器在菜单“捕获” -
“捕获过滤器” 中设置, 显示过滤器在菜单“分析” -“Display Filters” 中设置。
TCPDUMP
tcpdump 可以抓所有层的数据, 功能十分强大, tcpdump Linux 作为网络服务器, 特别
是作为路由器和网关时, 数据的采集和分析是不可少的。 TcpDump 是 Linux 中强大的网络数
据采集分析工具之一。 用简单的话来定义 tcpdump, 就是:dump the traffic on a network, 根
据使用者的定义对网络上的数据包进行截获的包分析工具。 作为互联网上经典的的系统管理
员或者运维人员必备工具, tcpdump 以其强大的功能, 灵活的截取第略, 成为每个高级的系
统管理员/运维人员分析网格, 排查问题等所必备的工具之一。 注意 tcpdump 必须以超级管
理员的身份登录系统才能使用。
tcpdump 的参数比较多:
tcp
各个参数的意义如下:
A: 以 ascii 编码打印每个报文(不包括链路的头) 。
a: 将网络地址和广播地址转变成名字。
c: 抓取指定数目的包。
C: 用于判断用 -w 选项将报文写入的文件的大小是否超过这个值, 如果超过了就新建
文件(文件名后缀是 1、 2、 3 依次增加) ;
d: 将匹配信息包的代码以人们能够理解的汇编格式给出;
dd: 将匹配信息包的代码以 c 语言程序段的格式给出;
ddd: 将匹配信息包的代码以十进制的形式给出;
D: 列出当前主机的所有网卡编号和名称, 可以用于选项 -i;
e: 在输出行打印出数据链路层的头部信息;
f: 将外部的 Internet 地址以数字的形式打印出来;
F<表达文件>: 从指定的文件中读取表达式,忽略其它的表达式;
i<网络界面>: 监听主机的该网卡上的数据流, 如果没有指定, 就会使用最小网卡编号
的网卡(在选项-D 可知道, 但是不包括环路接口) , linux 2.2 内核及之后的版本支持 any 网
卡, 用于指代任意网卡;
l: 如果没有使用 -w 选项, 就可以将报文打印到 标准输出终端(此时这是默认) ;
n: 显示 ip, 而不是主机名;
nn: 显示 port, 而不是服务名;
N: 不列出域名;
O: 不将数据包编码最佳化;
p: 不让网络界面进入混杂模式;
q: 快速输出, 仅列出少数的传输协议信息;
r<数据包文件>: 从指定的文件中读取包(这些包一般通过-w 选项产生);
s<数据包大小>: 指定抓包显示一行的宽度, -s0 表示可按包长显示完整的包, 经常和-A
一起用, 默认截取长度为 60 个字节, 但一般 ethernet MTU 都是 1500 字节。 所以, 要抓取
大于 60 字节的包时, 使用默认参数就会导致包数据丢失;
S: 用绝对而非相对数值列出 TCP 关联数;
t: 在输出的每一行不打印时间戳;
tt: 在输出的每一行显示未经格式化的时间戳记;
T<数据包类型>: 将监听到的包直接解释为指定的类型的报文, 常见的类型有 rpc (远
程过程调用) 和 snmp(简单网络管理协议) ;
v: 输出一个稍微详细的信息, 例如在 ip 包中可以包括 ttl 和服务类型的信息;
vv: 输出详细的报文信息;
x/-xx/-X/-XX: 以十六进制显示包内容, 几个选项只有细微的差别, 详见 man 手册;
w<数据包文件>: 直接将包写入文件中, 并不分析和打印出来;
expression: 用于筛选的逻辑表达式。
在 tcpdump 中, tcpdump 利用正则表达式作为过滤报文的条件, 如果一个报文满足表
达式的条件, 则这个报文将会被捕获。 如果没有给出任何条件, 则网络上所有的信息包将会
被截获。
在表达式中一般如下几种类型的关键字, 一种是关于类型的关键字, 主要包括 host,
port, 例如 host 210.27.48.2, 指明 210.27.48.2 是一台主机, port 23 指明端口号是 23。 如
果没有指定类型, 缺省的类型是 host。
第二种是确定传输方向的关键字, 主要包括 src , dst 这些关键字指明了传输的方向。 举
例说明, src 210.27.48.2 ,指明 ip 包中源地址是 210.27.
48.2 , dst net 202.0.0.0 指明目的网络地址是 202.0.0.0 。 如果没有指明方向关键字, 则
缺省是 src or dst 关键字。
第三种是协议的关键字, 主要包括 fddi,ip ,arp,rarp,tcp,udp 等类型。
如果没有指定任何协议, 则 tcpdump 将会监听所有协议的信息包。
表达式还可以通过
! or not
&& or and
|| or or
进行连接
比如,
tcpdump -i eth0 tcp port 3306 -w ./mysql.cap
捕获本机网络设备 eth0 上 tcp 协议, 端口 3306 的数据包, 并写入当前目录下的 mysql.cap
文件。
不过 tcpdump 的输出不够直观, 所以我们一般用 tcpdump 抓包以后下载到本地用
Wireshark 打开分析。