Wireshark 是著名网络抓包工具。它就像是网络世界里的一台“高速摄像机”,能够截获在 TCP/IP 协议栈中传输的所有流量,把一瞬间发生在网络传输过程如实地“拍摄下来”,事后再“慢慢回放”;并能按协议类型、地址、端口号等任意过滤,功能非常强大,是学习网络协议的必备工具。
发展简史
1997 年底,就职于一家小型 ISP 工作的 Gerald Combs 需要一个能够追踪网络流量的工具作为其工作上的辅助。因此他开始撰写一款名为 Ethereal(Wireshark 的前身) 软件。
在经过几次中断开发之后,终于在 1998 年 7 月发布了第一个版本 v0.2.0,自此之后,Combs 收到了来自全世界的补丁、错误回报与鼓励信件。Ethereal 的发展就此开始,数以千计的人开始参与到 Ethereal 的开发。
2006 年 6 月,Combs 接受了由 CACE 提供的新工作,而 Ethereal 的商标属于 Network Integration Service,因此他将 Ethereal 更名为现在的 Wireshark。
主窗口
Wireshark 主窗口大致可以分为 5 个模块:显示过滤器、封包列表、封包详细、包字节面板以及状态栏。
- 显示过滤器(Display Filter)
使用过滤是非常重要的, Wireshark 默认会得到大量抓包信息,以至于不太容易定位到自己需要的部分,被搞得晕头转向。而过滤器会帮助我们在大量的数据中迅速找到我们需要的信息。
如果正在尝试分析问题,可以关闭所有其他使用网络的应用以减少流量,有助于减少排查的难度。
如上图所示的「显示过滤器」,用来在已经捕获的封包列表中过滤出所需要的记录。例如,输入 “dns” 就会只看到 DNS 报文。在输入的时候,Wireshark 也会帮助我们完成过滤条件。也可以将其保存,便于二次使用。
建立显示过滤表达式
Wireshark 提供了简单而强大的过滤语法,可以用它们建立复杂的过滤表达式,「封包详情」的每个字段都可以作为过滤使用,应用这些作为过滤将会仅显示包含该字段的数据包,方便二次排查。下面先来看下用于建立过滤表达式的比较操作符。
也可以通过逻辑操作符将过滤表达式组合在一起使用,组成组合过滤表达式。如下图:
- 封包列表 (Packet List Pane)
「封包列表」面板显示所有当前已捕捉的包,列表的每行显示捕捉文件的一个包。选中其中一行,该包的详细信息将会展示在「封包详情」面板。
包列表有很多列可供选择,默认列如下:
- No 包的编号,编号不会发生改变,即使进行了过渡也同样如此;
- Time 包的时间戳。包时间戳的格式可以自行设置;
- Source 显示包的源地址;
- Destination 显示包的目标地址;
- Protocol 显示包的协议类型的简写;
- Info 包内容的附加信息。
「封包列表」将是我们分析抓包的主要“战场”,图中显示了 TCP 三次握手过程,关于这部分将在后面再详细介绍。
另外,封包列表可以针对协议设置不同的显示色便于区分。你可以通过 View -> Coloring Rules 修改这些显示颜色的规则。
- 封包详情(Packet Details Pane)
「封包详情」面板显示在「封包列表」面板被选中的包的详情。面板显示了包的协议及协议字段,协议及字段以树状方式组织,可以展开或折叠它们查看详情。
下图以 TCP 数据包为例,Wireshark 抓包数据对照 TCP 报文。
- Source Port(源端口)/Destination Port(目的端口)
每个 TCP 包都包含源端口号和目的端口号,用于寻找发送端和接收端的应用进程。这两个值加上 IP 首部中的源端 IP 地址和目的端 IP 地址确定一条唯一的 TCP 连接。
- Sequence number(序号)/Acknowledgment number(确认号)
序号用于标识从 TCP 发送端向 TCP 接收端发送的数据字节流,表示在这个报文段中的第一个数据字节。序号是 32bit 的无符号数,达到 2^32 - 1 后又从 1 开始。
确认号包含发送确认的一端所期望收到的下一个序号。
- Header Length(首部长度)
首部长度给出首部中 32bit 字的数目。需要这个值是因为任选字段的长度是可变的。这个字段占 4bit,因此 TCP 最多 60 字节的首部。如果没有任选字段,正常的长度是 20 字节。
- 6 个标志比特
URG 紧急指针(urgent pointer)
ACK 确认序号有效
PSH 接收方应该尽快将这个报文段交给应用层
SYN 同步序号用来发起一个连接
FIN 发端完成发送任务
- 窗口大小
TCP 的流量控制由连接的每一端通过声明的窗口大小来提供。窗口的大小为字节数,起始于确认序号字段指明的值,这个值是接收端期望接收的字节。
...
- 有关 TCP 的更详细分析请参考《TCP/IP 详解卷一》
- 包字节面板(Dissector Pane)
「包字节面板」以 16 进制转储方式显示当前选择包的数据。通常在 16 进制转储形式中,左侧显示包数据偏移量,中间栏 16 进制表示,右侧显示为对应的 ASCII 字符。
根据包数据的不同,「包字节面板」可能会有多个页面,例如:有时候 Wireshark 会将多个分片重组为一个,这时候会在面板底部出现一个附加按钮供你选择查看。
右击选项按钮会显示一个上下文菜单显示所有可用页的清单。
- 状态栏(Status)
状态栏的左侧通常会显示上下文相关信息,包括名称、大小以及捕捉持续时间等。右侧显示当前包数目。
TCP 三次握手抓包分析
我们知道所有的 TCP 连接一开始都要经过三次握手。客户端与服务器在交换应用数据之前,必须就起始分组序列号,以及其他一些连接相关的细节达成一致。出于安全考虑,序号由两端随机生成。
SYN,客户端选择一个随机序号 x,并发送一个 SYN 分组,其中可能还包括其他 TCP 标志和选项。
SYN ACK,服务器给 x + 1,并选择自己的一个随机序号 y,追加自己的标志和选项,然后返回响应。
ACK,客户端给 x 和 y 加 1 并发送握手期间的最后一个 ACK 分组。
三次握手完成后,客户端与服务器之间就可以通信了。客户端可以在发送 ACK 分组之后立即发送数据,而服务器必须等接收到 ACK 分组之后才能发送数据。这个启动通信的过程适用于所有的 TCP 连接,因此对所有使用 TCP 的应用具有非常大的性能影响,当然这里关注的并不是 TCP 性能。
回到 Wireshark 抓包列表,找到 TCP 三次握手包信息,这个过程大家可以自行测试。
分别选中每个包之后,然后到“封包详情”查看对应的 TCP 数据包信息,先来看下 TCP 的第一次握手:
客户端发起建立 TCP 连接请求,随机选择一个序号 x ,并发送一个 SYN 分组到服务端。
服务端接收到客户端建立 TCP 连接的请求后,将客户端序号 0 加 1,并选择自己的一个随机序号 y,追加自己的标志和选项,然后返回响应。TCP 的第二次握手如下:
客户端接收到服务端同意建立连接的响应后,将 x 和 y 加 1 并发送握手期间的最后一个 ACK 分组。TCP 的第三次握手如下:
通过 Wireshark 我们可以清晰的看到在经过 SYN、SYN/ACK 及 ACK 三个包之后,客户端与服务端的 TCP 连接通道就建立起来了。
我们知道 HTTP 协议也是运行在 TCP/IP 基础之上的,依靠 TCP/IP 协议来实现数据的可靠传输,有了可靠的 TCP 连接通道之后,HTTP 协议就可以开始工作了。
于是,客户端按照 HTTP 协议规定的格式,通过 TCP 发送了一个 “GET / HTTP/1.1” 的请求报文,就是「封包列表」的第四个包,如下图:
随后,服务端回复了第五个包,在 TCP 协议层面确认:“刚才的报文服务端已经收到(根据 ACK)”。不过这个 TCP 数据包对于 HTTP 协议是透明的。
服务器收到 HTTP 协议报文格式后,在内部处理这个请求,看看客户端发送的这个请求要干什么。然后根据客户端的请求需求将对应资源封装成 HTTP 格式的报文发送给客户端,这就是封包列表的第六个包 “HTTP/1/1 200 OK”(底层走的依然是 TCP 协议)。
同样客户端也要给服务器回复一个 TCP 的 ACK 确认包,表示响应报文已经收到。即第七个包。
小结
网络封包分析工具就像是“电力电子”行业用来测量电流、电压以及电阻等工作的万用表。在过去,网络封包分析工具是高度商业化的(费用非常高昂),Ethereal 的出现改变了这一切,并且已然成为全世界最广泛的网络分析工具。
Wireshark 无论是对于网络知识的学习还是从事该行业的运维或技术人员,都是一个非常好的辅助工具。
最后
文章通过分析 TCP 三次握手的小例子简述了 Wireshark 的基本使用。有关它更详细的使用说明请参照下方给出的相关资料:
可能有的朋友还用过 Fiddler、Charles 等网络分析工具,它们之间该如何选择或区别呢?这里我也简单总结给大家,便于在实际中更好的运用。
文中如有不妥或有更好的分析结果,欢迎您的分享留言或指正。