tcpdump fu

数据包捕获是进行网络分析最基本和最强大的方法之一。通过拦截和检查穿过网络的原始数据,您可以了解网络中发生的几乎任何事情。现代网络分析工具能够以人性化的方式捕获、解释和描述这种网络流量。

tcpdump 是最初的数据包捕获(或“嗅探”)工具之一,它提供这些分析功能,即使现在它与许多其他实用程序共享这一领域,它仍然是最强大和最灵活的工具之一。

如果您认为 tcpdump 已经被像 Wireshark 这样的 GUI 工具淘汰,请再想一想。Wireshark 是一个很棒的应用程序;只是在每种情况下它都不是适合这项工作的工具。作为一种精细、通用、轻量级的命令行实用程序——非常像 cat、less 和 hexdump——tcpdump 满足了不同类型的需求。

tcpdump 最强大的优势之一是它的便利性。它使用“一次性命令”方法,有助于快速获得现场答案。它通过 SSH 会话工作,不需要 X 窗口系统,并且在您需要它时更有可能在那里。而且,由于它使用标准的命令行约定(例如写入 STDOUT,可以重定向),tcpdump 可以以各种创造性、有趣和极其有用的方式使用。

在本文中,我将介绍数据包捕获的一些基础知识,并提供 tcpdump 语法和用法的分解。我将展示如何使用 tcpdump 来精确查找特定的数据包,并揭示它们包含的有用信息。我提供了一些真实世界的示例,说明 tcpdump 如何帮助您触手可及地掌握网络上发生的详细信息,以及为什么 tcpdump 仍然是任何管理员工具箱中必备的工具。

基本概念

在您开始掌握 tcpdump 之前,您应该了解一些适用于所有数据包嗅探器的基本原理

  • 数据包捕获是被动的——它不会传输或更改网络流量。

  • 您只能捕获您的系统接收的数据包。在典型的交换网络上,这排除了其他主机之间的单播流量(未发送到或来自您机器的数据包)。

  • 除非网络接口处于混杂模式,否则您只能捕获寻址到您系统的数据包。

假设您有兴趣看到不仅仅是您的本地流量,因此 tcpdump 会自动打开混杂模式(这需要 root 权限)。但是,为了让您的网卡首先接收数据包,您仍然必须在流量所在的位置,可以这么说。

tcpdump 命令的结构

一个 tcpdump 命令由两部分组成:一组选项,后跟一个过滤器表达式(图 1)。

tcpdump -i eth1 -vvn icmp or udp (where

图 1. tcpdump 命令示例

该表达式标识要捕获哪些数据包,选项部分定义了这些数据包的显示方式以及程序行为的其他方面。

选项

tcpdump 选项遵循标准的命令行标志/开关语法约定。一些标志接受参数,例如 -i 用于指定捕获接口,而另一些是独立的开关,可以集群,例如 -v 用于增加详细程度,-n 用于关闭名称解析。

tcpdump 的 man 手册列出了所有可用选项,但这里有一些值得注意的选项

  • -i interface:要监听的接口。

  • -v-vv-vvv:更详细。

  • -q:较不详细。

  • -e:打印链路层(以太网)报头。

  • -N:显示相对主机名。

  • -t:不打印时间戳。

  • -n:禁用名称查找。

  • -s0 (或 -s 0):使用最大“snaplen”——捕获完整数据包(tcpdump 最近版本中的默认值)。

这些都不是必需的。用户提供的选项只是修改默认程序行为,即从第一个接口捕获,然后在屏幕上以单行格式打印匹配数据包的描述。

过滤器表达式

过滤器表达式是用于“匹配”数据包的布尔值(真或假)标准。所有不匹配表达式的数据包都将被忽略。

过滤器表达式语法强大而灵活。它主要由称为原语的关键字组成,这些关键字代表各种数据包匹配限定符,例如协议、地址、端口和方向。这些可以使用 and/or 链接在一起,使用括号分组和嵌套,并使用 not 取反,以实现几乎任何标准。

由于原语具有友好的名称并完成了大量繁重的工作,因此过滤器表达式通常是不言自明的,并且易于阅读和构建。pcap-filter man 手册中完整描述了语法,但这里有一些过滤器表达式示例

  • tcp

  • port 25 and not host 10.0.0.3

  • icmp or arp or udp

  • vlan 3 and ether src host aa:bb:cc:dd:ee:ff

  • arp or udp port 53

  • icmp and \(dst host mrorange or dst host mrbrown\)

与选项一样,过滤器表达式不是必需的。空的过滤器表达式只是匹配所有数据包。

理解 tcpdump 输出

输出有多大意义取决于您对所讨论协议的理解程度。tcpdump 定制其输出以匹配给定数据包的协议。

例如,当使用 -t-n 调用 tcpdump 时(时间戳和名称查找已关闭),ARP 数据包的显示方式如下


arp who-has 10.0.0.1 tell 10.0.0.2
arp reply 10.0.0.1 is-at 00:01:02:03:04:05

ARP 是一种简单的协议,用于将 IP 解析为 MAC 地址。如您在上面看到的,tcpdump 以相应的简单格式描述了这些数据包。另一方面,DNS 数据包的显示方式完全不同


IP 10.0.0.2.50435 > 10.0.0.1.53: 19+ A? linuxjournal.com. (34)
IP 10.0.0.1.53 > 10.0.0.2.50435: 19 1/0/0 A 76.74.252.198 (50)

乍一看这可能很神秘,但是当您了解协议层的工作方式时,它会更有意义。DNS 本身就是比 ARP 更复杂的协议,但它也在更高层上运行。这意味着它在其他较低层协议之上运行,这些协议也显示在输出中。

与 ARP(一种不可路由的第 3 层协议)不同,DNS 是一种互联网范围的协议。它依赖于 UDP 和 IP 在互联网上承载和路由它,这使其成为第 5 层协议(UDP 是第 4 层,IP 是第 3 层)。

底层的 UDP/IP 信息(包括源和目标 IP/端口)显示在冒号的左侧,其余的 DNS 特定信息显示在右侧。

即使此 DNS 信息仍然以高度压缩的格式显示,如果您了解 DNS 的基础知识,您也应该能够识别出基本要素。第一个数据包是对 linuxjournal.com 的查询,第二个数据包是答案,给出了地址 76.74.252.198。这些是来自简单 DNS 查找生成的数据包类型。

请参阅 tcpdump man 手册的“OUTPUT FORMAT”部分,以获得所有受支持的协议特定输出格式的完整描述。某些协议的输出格式比其他协议更好,但我发现 tcpdump 在通常情况下在显示有关给定协议的最有用信息方面做得相当不错。

捕获文件

除了将其正常行为(将数据包描述打印到屏幕)之外,tcpdump 还支持一种操作模式,其中它将数据包写入文件。当使用 -w 选项指定输出捕获文件时,将激活此模式。

当写入文件时,tcpdump 使用与写入屏幕时完全不同的格式。当写入屏幕时,将打印数据包的格式化文本描述。当写入文件时,原始数据包按原样记录,无需分析。

除了进行实时捕获之外,tcpdump 还可以使用 -r 选项从现有的捕获文件读取作为输入。由于 tcpdump 捕获文件使用普遍支持的“pcap”格式,因此它们也可以被其他应用程序(包括 Wireshark)打开。

这使您可以选择在一台主机上使用 tcpdump 捕获数据包,但在另一台主机上通过传输和加载捕获文件来执行分析。这使您可以在本地工作站上使用 Wireshark,而无需将其连接到您需要从中捕获的网络和位置。

分析基于 TCP 的应用程序协议

tcpdump 是一个基于数据包的分析器,它非常适合无连接的、基于数据包的协议,如 IP、UDP、DHCP、DNS 和 ICMP。但是,它不能直接分析“面向连接”的协议,如 HTTP、SMTP 和 IMAP,因为它们的工作方式完全不同。

它们没有“数据包”的概念。相反,它们通过 TCP 的基于流的连接运行,TCP 提供了一个抽象的通信层。这些应用程序协议实际上更像是交互式控制台程序,而不是基于数据包的网络协议。

TCP 透明地处理提供这些可靠的、端到端、会话式连接所需的所有底层细节。这包括将基于流的数据封装到可以在网络上发送的数据包(称为段)中。所有这些细节都隐藏在应用层之下。

为了捕获基于 TCP 的应用程序协议,除了捕获数据包之外,还需要额外的步骤。因为每个 TCP 段只是应用程序数据的一部分,所以它不能单独用于获取任何有意义的信息。您首先必须从各个段/数据包的组合集中重新组装 TCP 会话(或流)。应用程序协议数据直接包含在会话中。

tcpdump 没有直接从数据包组装 TCP 会话的选项,但是您可以使用我称之为“tcpdump 字符串技巧”的方法来“伪造”它。

tcpdump 字符串技巧

通常,当我捕获流量时,只是为了进行临时分析。如果数据向我展示了我正在寻找的东西并帮助我获得一些见解,那么数据不需要是完美的。

在这些情况下,速度和便利性至高无上。以下技巧与这些原则一致,并且是我最喜欢的 tcpdump 技术之一。它的工作原理是因为

  1. TCP 段通常按时间顺序发送。

  2. 基于文本的应用程序协议生成带有文本负载的 TCP 段。

  3. 文本负载周围的数据(例如数据包标头)通常不是文本。

  4. UNIX 命令 strings 从流中过滤掉二进制数据,仅保留文本(可打印字符)。

  5. 当使用 -w - 调用 tcpdump 时,它会将原始数据包打印到 STDOUT。

将所有内容放在一起,您将获得一个转储实时 HTTP 会话数据的命令


tcpdump -l -s0 -w - tcp dst port 80 | strings

上面的 -l 选项打开了行缓冲,这确保了数据立即打印到屏幕上。

这里发生的事情是 tcpdump 将原始二进制数据打印到屏幕上。这使用了 -w 选项的一种变体,其中特殊文件名 - 写入 STDOUT 而不是文件。通常,这样做会显示各种乱码,但这就是 strings 命令的用武之地——它只允许被识别为文本的数据通过到屏幕。

有一些注意事项需要注意。首先,同时接收的来自多个会话的数据会同时显示,从而使您的输出混乱。您使过滤器表达式越精细,这个问题就越少。您还应该为会话的客户端和服务器端运行单独的命令(在单独的 shell 中)


tcpdump -l -s0 -w - tcp dst port 80 | strings
tcpdump -l -s0 -w - tcp src port 80 | strings

此外,当二进制数据序列也恰好看起来像文本字符时,您应该期望看到一些乱码字符。您可以通过增加 min-len(请参阅 strings man 手册)来减少这种情况。

此技巧同样适用于其他基于文本的协议。

HTTP 和 SMTP 分析

使用上一节中的字符串技巧,即使 tcpdump 实际上不了解任何关于 HTTP 的信息,您也可以捕获 HTTP 数据。然后,您可以以多种方式进一步“分析”它。

例如,如果您想实时查看“davepc”正在访问的所有网站,您可以在防火墙上运行此命令(假设内部接口是 eth1)


tcpdump -i eth1 -l -s0 -w - host davepc and port 80 \
  | strings | grep 'GET\|Host'

在此示例中,我正在使用一个简单的 grep 命令来仅显示带有 GET 或 Host 的行。这些字符串出现在 HTTP 请求中,并共同显示正在访问的 URL。

这对于 SMTP 同样有效。您可以在您的邮件服务器上运行此命令以监视电子邮件发送者和接收者


tcpdump -l -s0 -w - tcp dst port 25 | strings \
  | grep -i 'MAIL FROM\|RCPT TO'

这些只是一些简单的示例,用于说明可能的用途。显然,您可以超越 grep。您可以进一步编写 Perl 脚本来完成各种复杂的事情。但是,您可能不会走得太远,因为在这一点上,有更好的工具实际上是为此类事情设计的。

tcpdump 的真正价值在于能够随意交互式地执行这些类型的操作。它是在您需要时随时查看网络任何方面的能力,而无需付出太多努力。

调试路由和 VPN 链接

当通过显示数据包在何处出现以及在何处未出现来调试 VPN 和其他网络连接时,tcpdump 非常方便。假设您在 10.0.50.0/24 和 192.168.5.0/24 之间设置了标准的、可路由的网络到网络 VPN(图 2)。

illustration of a standard routable network-to-network VPN

图 2. VPN 拓扑示例

如果它运行正常,来自任一网络的主机都应该能够相互 ping 通。但是,如果您在从主机 A ping 主机 D 时没有收到回复,例如,您可以使用 tcpdump 来精确定位故障发生的位置


tcpdump -tn icmp and host 10.0.50.2

在此示例中,在从 10.0.50.2 ping 到 192.168.5.38 期间,无论 tcpdump 命令从四个系统中的哪个系统运行,每个往返都应显示为如下所示的一对数据包


IP 10.0.50.2 > 192.168.5.38: ICMP echo request, 
 ↪id 46687, seq 1, length 64
IP 192.168.5.38 > 10.0.50.2: ICMP echo reply, 
 ↪id 46687, seq 1, length 64

如果请求数据包到达主机 C(远程网关)但未到达 D,则表明 VPN 本身正在工作,但可能存在路由问题。如果主机 D 收到请求但不生成回复,则它可能已阻止 ICMP。如果它确实生成了回复,但它没有返回到 C,则 D 可能没有配置正确的网关以返回到 10.0.50.0/24。

使用 tcpdump,您可以跟踪 ping 通过所有八个可能的故障点,因为它在网络中来回传输。

结论

我希望本文引起了您对 tcpdump 的兴趣,并为您提供了一些新的想法。希望您也喜欢这些示例,这些示例只是触及了可能性的表面。

除了其许多内置功能和选项外,正如我在几个示例中展示的那样,tcpdump 可以通过管道传输到其他命令来用作数据包数据管道,从而进一步扩展可能性——即使您确实设法耗尽了其广泛的“广告宣传”功能。使用 tcpdump 的方式仅受您的想象力限制。

tcpdump 也是一个令人难以置信的学习工具。没有比观看网络的实际数据包更好的方法来了解网络和协议的工作原理了。

不要忘记查看 tcpdump 和 pcap-filter man 手册以获取更多详细信息和信息。

tcpdump/libpcap 的遗产

在过去的 25 年中,tcpdump 一直是事实上的数据包捕获工具。它确实催生了整个基于嗅探和分析数据包的网络实用程序类型。在 tcpdump 之前,数据包捕获具有如此高的处理需求,以至于在很大程度上是不切实际的。tcpdump 引入了一些关键的创新和优化,这些创新和优化有助于使数据包捕获对常规系统和具有大量流量的网络都更可行。

之后出现的实用程序不仅遵循了 tcpdump 的领先地位,而且还直接合并了其数据包捕获功能。这成为可能,因为很早以前,tcpdump 的作者就决定将数据包捕获代码移动到一个单独的可移植库中,称为 libpcap。

Wireshark、ntop、snort、iftop、ngrep 以及当今可用的数百种其他应用程序和实用程序都基于 libpcap。甚至大多数用于 Windows 的数据包捕获应用程序也基于 libpcap 的一个端口,称为 WinPcap。

资源

tcpdump 和 libpcap: http://www.tcpdump.org

Wireshark: http://www.wireshark.org

TCP/IP 模型: http://en.wikipedia.org/wiki/TCP/IP_model

加载 Disqus 评论