Linux 命令行 tcpdump 使用入门

这款灵活而强大的命令行工具可以帮助您轻松解决网络故障。
444 位读者喜欢这篇文章。

作为一名系统管理员,根据我的经验,我经常发现网络连接问题难以排除故障。对于这些情况,tcpdump 是一个很好的助手。

Tcpdump 是一个命令行实用程序,允许您捕获和分析通过系统的网络流量。它通常用于帮助排除网络问题,也是一种安全工具。

tcpdump 是一款强大而通用的工具,包含许多选项和过滤器,可用于各种情况。由于它是一个命令行工具,因此非常适合在没有 GUI 的远程服务器或设备上运行,以收集稍后可以分析的数据。它也可以在后台启动或作为使用 cron 等工具的计划作业。

在本文中,我们将介绍 tcpdump 的一些最常见功能。

1. 在 Linux 上安装

Tcpdump 包含在多个 Linux 发行版中,因此您很可能已经安装了它。使用以下命令检查您的系统上是否安装了 tcpdump

$ which tcpdump
/usr/sbin/tcpdump

如果未安装 tcpdump,您可以使用发行版的软件包管理器进行安装。例如,在 CentOS 或 Red Hat Enterprise Linux 上,像这样

$ sudo dnf install -y tcpdump

Tcpdump 需要 libpcap,这是一个用于网络数据包捕获的库。如果未安装,它将自动添加为依赖项。

您已准备好开始捕获一些数据包。

2. 使用 tcpdump 捕获数据包

要捕获数据包以进行故障排除或分析,tcpdump 需要提升的权限,因此在以下示例中,大多数命令都以 sudo 为前缀。

首先,使用命令 tcpdump --list-interfaces (或简写 -D)查看哪些接口可用于捕获

$ sudo tcpdump -D
1.eth0
2.virbr0
3.eth1
4.any (Pseudo-device that captures on all interfaces)
5.lo [Loopback]

在上面的示例中,您可以看到我的机器中所有可用的接口。特殊的接口 any 允许在任何活动接口中捕获。

让我们使用它来开始捕获一些数据包。通过运行以下命令捕获任何接口中的所有数据包

$ sudo tcpdump --interface any
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
09:56:18.293641 IP rhel75.localdomain.ssh > 192.168.64.1.56322: Flags [P.], seq 3770820720:3770820916, ack 3503648727, win 309, options [nop,nop,TS val 76577898 ecr 510770929], length 196
09:56:18.293794 IP 192.168.64.1.56322 > rhel75.localdomain.ssh: Flags [.], ack 196, win 391, options [nop,nop,TS val 510771017 ecr 76577898], length 0
09:56:18.295058 IP rhel75.59883 > gateway.domain: 2486+ PTR? 1.64.168.192.in-addr.arpa. (43)
09:56:18.310225 IP gateway.domain > rhel75.59883: 2486 NXDomain* 0/1/0 (102)
09:56:18.312482 IP rhel75.49685 > gateway.domain: 34242+ PTR? 28.64.168.192.in-addr.arpa. (44)
09:56:18.322425 IP gateway.domain > rhel75.49685: 34242 NXDomain* 0/1/0 (103)
09:56:18.323164 IP rhel75.56631 > gateway.domain: 29904+ PTR? 1.122.168.192.in-addr.arpa. (44)
09:56:18.323342 IP rhel75.localdomain.ssh > 192.168.64.1.56322: Flags [P.], seq 196:584, ack 1, win 309, options [nop,nop,TS val 76577928 ecr 510771017], length 388
09:56:18.323563 IP 192.168.64.1.56322 > rhel75.localdomain.ssh: Flags [.], ack 584, win 411, options [nop,nop,TS val 510771047 ecr 76577928], length 0
09:56:18.335569 IP gateway.domain > rhel75.56631: 29904 NXDomain* 0/1/0 (103)
09:56:18.336429 IP rhel75.44007 > gateway.domain: 61677+ PTR? 98.122.168.192.in-addr.arpa. (45)
09:56:18.336655 IP gateway.domain > rhel75.44007: 61677* 1/0/0 PTR rhel75. (65)
09:56:18.337177 IP rhel75.localdomain.ssh > 192.168.64.1.56322: Flags [P.], seq 584:1644, ack 1, win 309, options [nop,nop,TS val 76577942 ecr 510771047], length 1060

---- SKIPPING LONG OUTPUT -----

09:56:19.342939 IP 192.168.64.1.56322 > rhel75.localdomain.ssh: Flags [.], ack 1752016, win 1444, options [nop,nop,TS val 510772067 ecr 76578948], length 0
^C
9003 packets captured
9010 packets received by filter
7 packets dropped by kernel
$ 

Tcpdump 会继续捕获数据包,直到收到中断信号。您可以通过按 Ctrl+C 来中断捕获。正如您在本示例中看到的,tcpdump 捕获了 9,000 多个数据包。在本例中,由于我使用 ssh 连接到此服务器,因此 tcpdump 捕获了所有这些数据包。要限制捕获的数据包数量并停止 tcpdump,请使用 -c(表示 计数)选项

$ sudo tcpdump -i any -c 5
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
11:21:30.242740 IP rhel75.localdomain.ssh > 192.168.64.1.56322: Flags [P.], seq 3772575680:3772575876, ack 3503651743, win 309, options [nop,nop,TS val 81689848 ecr 515883153], length 196
11:21:30.242906 IP 192.168.64.1.56322 > rhel75.localdomain.ssh: Flags [.], ack 196, win 1443, options [nop,nop,TS val 515883235 ecr 81689848], length 0
11:21:30.244442 IP rhel75.43634 > gateway.domain: 57680+ PTR? 1.64.168.192.in-addr.arpa. (43)
11:21:30.244829 IP gateway.domain > rhel75.43634: 57680 NXDomain 0/0/0 (43)
11:21:30.247048 IP rhel75.33696 > gateway.domain: 37429+ PTR? 28.64.168.192.in-addr.arpa. (44)
5 packets captured
12 packets received by filter
0 packets dropped by kernel
$ 

在本例中,tcpdump 在捕获五个数据包后自动停止捕获。这在不同的场景中很有用——例如,如果您正在排除连接问题,并且捕获一些初始数据包就足够了。当我们应用过滤器来捕获特定数据包时(如下所示),这甚至更有用。

默认情况下,tcpdump 将 IP 地址和端口解析为名称,如前面的示例所示。在排除网络问题时,通常更容易使用 IP 地址和端口号;使用选项 -n 禁用名称解析,使用 -nn 禁用端口解析

$ sudo tcpdump -i any -c5 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
23:56:24.292206 IP 192.168.64.28.22 > 192.168.64.1.35110: Flags [P.], seq 166198580:166198776, ack 2414541257, win 309, options [nop,nop,TS val 615664 ecr 540031155], length 196
23:56:24.292357 IP 192.168.64.1.35110 > 192.168.64.28.22: Flags [.], ack 196, win 1377, options [nop,nop,TS val 540031229 ecr 615664], length 0
23:56:24.292570 IP 192.168.64.28.22 > 192.168.64.1.35110: Flags [P.], seq 196:568, ack 1, win 309, options [nop,nop,TS val 615664 ecr 540031229], length 372
23:56:24.292655 IP 192.168.64.1.35110 > 192.168.64.28.22: Flags [.], ack 568, win 1400, options [nop,nop,TS val 540031229 ecr 615664], length 0
23:56:24.292752 IP 192.168.64.28.22 > 192.168.64.1.35110: Flags [P.], seq 568:908, ack 1, win 309, options [nop,nop,TS val 615664 ecr 540031229], length 340
5 packets captured
6 packets received by filter
0 packets dropped by kernel

如上所示,捕获输出现在显示 IP 地址和端口号。这还可以防止 tcpdump 发出 DNS 查找,这有助于在排除网络问题时降低网络流量。

现在您已经能够捕获网络数据包,让我们探讨一下此输出的含义。

3. 了解输出格式

Tcpdump 能够捕获和解码许多不同的协议,例如 TCP、UDP、ICMP 等等。虽然我们无法在此处涵盖所有协议,但为了帮助您入门,让我们探讨一下 TCP 数据包。您可以在 tcpdump 的 手册页 中找到有关不同协议格式的更多详细信息。tcpdump 捕获的典型 TCP 数据包如下所示

08:41:13.729687 IP 192.168.64.28.22 > 192.168.64.1.41916: Flags [P.], seq 196:568, ack 1, win 309, options [nop,nop,TS val 117964079 ecr 816509256], length 372

字段可能会因发送的数据包类型而异,但这是通用格式。

第一个字段 08:41:13.729687, 表示根据本地时钟接收到的数据包的时间戳。

接下来,IP 表示网络层协议——在本例中为 IPv4。对于 IPv6 数据包,该值为 IP6

下一个字段 192.168.64.28.22 是源 IP 地址和端口。后面是目标 IP 地址和端口,由 192.168.64.1.41916 表示。

在源和目标之后,您可以找到 TCP 标志 Flags [P.]。此字段的典型值包括

标志类型 描述
S SYN 连接开始
F FIN 连接结束
P PUSH 数据推送
R RST 连接重置
. ACK 确认

此字段也可以是这些值的组合,例如 [S.] 表示 SYN-ACK 数据包。

接下来是数据包中包含的数据的序列号。对于捕获的第一个数据包,这是一个绝对数字。后续数据包使用相对数字,以便于跟踪。在本例中,序列为 seq 196:568,,这意味着此数据包包含此流的字节 196 到 568。

后面是确认号:ack 1。在本例中,由于这是发送数据的一方,因此为 1。对于接收数据的一方,此字段表示此流上期望的下一个字节(数据)。例如,此流中下一个数据包的确认号将为 568。

下一个字段是窗口大小 win 309,它表示接收缓冲区中可用的字节数,后跟 TCP 选项,例如 MSS(最大段大小)或窗口缩放。有关 TCP 协议选项的详细信息,请查阅 传输控制协议 (TCP) 参数

最后,我们有数据包长度 length 372,它表示有效负载数据的长度(以字节为单位)。长度是序列号中最后一个字节和第一个字节之间的差值。

现在,让我们学习如何过滤数据包以缩小结果范围,并更轻松地排除特定问题。

4. 过滤数据包

如上所述,tcpdump 可以捕获太多数据包,其中一些数据包甚至与您要排除的故障无关。例如,如果您正在排除 Web 服务器的连接问题,那么您对 SSH 流量不感兴趣,因此从输出中删除 SSH 数据包可以更轻松地处理实际问题。

tcpdump 最强大的功能之一是能够使用各种参数(例如源和目标 IP 地址、端口、协议等)过滤捕获的数据包。让我们看看一些最常见的参数。

协议

要根据协议过滤数据包,请在命令行中指定协议。例如,仅捕获 ICMP 数据包,请使用以下命令

$ sudo tcpdump -i any -c5 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes

在另一个终端中,尝试 ping 另一台机器

$ ping opensource.com
PING opensource.com (54.204.39.132) 56(84) bytes of data.
64 bytes from ec2-54-204-39-132.compute-1.amazonaws.com (54.204.39.132): icmp_seq=1 ttl=47 time=39.6 ms

回到 tcpdump 捕获中,请注意 tcpdump 仅捕获和显示与 ICMP 相关的数据包。在本例中,tcpdump 不会显示解析名称 opensource.com 时生成的名称解析数据包

09:34:20.136766 IP rhel75 > ec2-54-204-39-132.compute-1.amazonaws.com: ICMP echo request, id 20361, seq 1, length 64
09:34:20.176402 IP ec2-54-204-39-132.compute-1.amazonaws.com > rhel75: ICMP echo reply, id 20361, seq 1, length 64
09:34:21.140230 IP rhel75 > ec2-54-204-39-132.compute-1.amazonaws.com: ICMP echo request, id 20361, seq 2, length 64
09:34:21.180020 IP ec2-54-204-39-132.compute-1.amazonaws.com > rhel75: ICMP echo reply, id 20361, seq 2, length 64
09:34:22.141777 IP rhel75 > ec2-54-204-39-132.compute-1.amazonaws.com: ICMP echo request, id 20361, seq 3, length 64
5 packets captured
5 packets received by filter
0 packets dropped by kernel

主机

要将捕获限制为仅与特定主机相关的数据包,请使用 host 过滤器

$ sudo tcpdump -i any -c5 -nn host 54.204.39.132
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
09:54:20.042023 IP 192.168.122.98.39326 > 54.204.39.132.80: Flags [S], seq 1375157070, win 29200, options [mss 1460,sackOK,TS val 122350391 ecr 0,nop,wscale 7], length 0
09:54:20.088127 IP 54.204.39.132.80 > 192.168.122.98.39326: Flags [S.], seq 1935542841, ack 1375157071, win 28960, options [mss 1460,sackOK,TS val 522713542 ecr 122350391,nop,wscale 9], length 0
09:54:20.088204 IP 192.168.122.98.39326 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 122350437 ecr 522713542], length 0
09:54:20.088734 IP 192.168.122.98.39326 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 122350438 ecr 522713542], length 112: HTTP: GET / HTTP/1.1
09:54:20.129733 IP 54.204.39.132.80 > 192.168.122.98.39326: Flags [.], ack 113, win 57, options [nop,nop,TS val 522713552 ecr 122350438], length 0
5 packets captured
5 packets received by filter
0 packets dropped by kernel

在本例中,tcpdump 仅捕获和显示与主机 54.204.39.132 之间往来的数据包。

端口

要根据所需的服务或端口过滤数据包,请使用 port 过滤器。例如,要捕获与 Web (HTTP) 服务相关的数据包,请使用以下命令

$ sudo tcpdump -i any -c5 -nn port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
09:58:28.790548 IP 192.168.122.98.39330 > 54.204.39.132.80: Flags [S], seq 1745665159, win 29200, options [mss 1460,sackOK,TS val 122599140 ecr 0,nop,wscale 7], length 0
09:58:28.834026 IP 54.204.39.132.80 > 192.168.122.98.39330: Flags [S.], seq 4063583040, ack 1745665160, win 28960, options [mss 1460,sackOK,TS val 522775728 ecr 122599140,nop,wscale 9], length 0
09:58:28.834093 IP 192.168.122.98.39330 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 122599183 ecr 522775728], length 0
09:58:28.834588 IP 192.168.122.98.39330 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 122599184 ecr 522775728], length 112: HTTP: GET / HTTP/1.1
09:58:28.878445 IP 54.204.39.132.80 > 192.168.122.98.39330: Flags [.], ack 113, win 57, options [nop,nop,TS val 522775739 ecr 122599184], length 0
5 packets captured
5 packets received by filter
0 packets dropped by kernel

源 IP/主机名

您还可以根据源或目标 IP 地址或主机名过滤数据包。例如,要捕获来自主机 192.168.122.98 的数据包

$ sudo tcpdump -i any -c5 -nn src 192.168.122.98
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
10:02:15.220824 IP 192.168.122.98.39436 > 192.168.122.1.53: 59332+ A? opensource.com. (32)
10:02:15.220862 IP 192.168.122.98.39436 > 192.168.122.1.53: 20749+ AAAA? opensource.com. (32)
10:02:15.364062 IP 192.168.122.98.39334 > 54.204.39.132.80: Flags [S], seq 1108640533, win 29200, options [mss 1460,sackOK,TS val 122825713 ecr 0,nop,wscale 7], length 0
10:02:15.409229 IP 192.168.122.98.39334 > 54.204.39.132.80: Flags [.], ack 669337581, win 229, options [nop,nop,TS val 122825758 ecr 522832372], length 0
10:02:15.409667 IP 192.168.122.98.39334 > 54.204.39.132.80: Flags [P.], seq 0:112, ack 1, win 229, options [nop,nop,TS val 122825759 ecr 522832372], length 112: HTTP: GET / HTTP/1.1
5 packets captured
5 packets received by filter
0 packets dropped by kernel

请注意,tcpdump 捕获了源 IP 地址为 192.168.122.98 的多个服务的数据包,例如名称解析(端口 53)和 HTTP(端口 80)。响应数据包未显示,因为它们的源 IP 不同。

相反,您可以使用 dst 过滤器按目标 IP/主机名进行过滤

$ sudo tcpdump -i any -c5 -nn dst 192.168.122.98
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
10:05:03.572931 IP 192.168.122.1.53 > 192.168.122.98.47049: 2248 1/0/0 A 54.204.39.132 (48)
10:05:03.572944 IP 192.168.122.1.53 > 192.168.122.98.47049: 33770 0/0/0 (32)
10:05:03.621833 IP 54.204.39.132.80 > 192.168.122.98.39338: Flags [S.], seq 3474204576, ack 3256851264, win 28960, options [mss 1460,sackOK,TS val 522874425 ecr 122993922,nop,wscale 9], length 0
10:05:03.667767 IP 54.204.39.132.80 > 192.168.122.98.39338: Flags [.], ack 113, win 57, options [nop,nop,TS val 522874436 ecr 122993972], length 0
10:05:03.672221 IP 54.204.39.132.80 > 192.168.122.98.39338: Flags [P.], seq 1:643, ack 113, win 57, options [nop,nop,TS val 522874437 ecr 122993972], length 642: HTTP: HTTP/1.1 302 Found
5 packets captured
5 packets received by filter
0 packets dropped by kernel

复杂表达式

您还可以使用逻辑运算符 andor 组合过滤器,以创建更复杂的表达式。例如,要仅过滤来自源 IP 地址 192.168.122.98 和服务 HTTP 的数据包,请使用以下命令

$ sudo tcpdump -i any -c5 -nn src 192.168.122.98 and port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
10:08:00.472696 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [S], seq 2712685325, win 29200, options [mss 1460,sackOK,TS val 123170822 ecr 0,nop,wscale 7], length 0
10:08:00.516118 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [.], ack 268723504, win 229, options [nop,nop,TS val 123170865 ecr 522918648], length 0
10:08:00.516583 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [P.], seq 0:112, ack 1, win 229, options [nop,nop,TS val 123170866 ecr 522918648], length 112: HTTP: GET / HTTP/1.1
10:08:00.567044 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [.], ack 643, win 239, options [nop,nop,TS val 123170916 ecr 522918661], length 0
10:08:00.788153 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [F.], seq 112, ack 643, win 239, options [nop,nop,TS val 123171137 ecr 522918661], length 0
5 packets captured
5 packets received by filter
0 packets dropped by kernel

您可以通过使用括号对过滤器进行分组来创建更复杂的表达式。在这种情况下,请用引号括起整个过滤器表达式,以防止 shell 将它们与 shell 表达式混淆

$ sudo tcpdump -i any -c5 -nn "port 80 and (src 192.168.122.98 or src 54.204.39.132)"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
10:10:37.602214 IP 192.168.122.98.39346 > 54.204.39.132.80: Flags [S], seq 871108679, win 29200, options [mss 1460,sackOK,TS val 123327951 ecr 0,nop,wscale 7], length 0
10:10:37.650651 IP 54.204.39.132.80 > 192.168.122.98.39346: Flags [S.], seq 854753193, ack 871108680, win 28960, options [mss 1460,sackOK,TS val 522957932 ecr 123327951,nop,wscale 9], length 0
10:10:37.650708 IP 192.168.122.98.39346 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 123328000 ecr 522957932], length 0
10:10:37.651097 IP 192.168.122.98.39346 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 123328000 ecr 522957932], length 112: HTTP: GET / HTTP/1.1
10:10:37.692900 IP 54.204.39.132.80 > 192.168.122.98.39346: Flags [.], ack 113, win 57, options [nop,nop,TS val 522957942 ecr 123328000], length 0
5 packets captured
5 packets received by filter
0 packets dropped by kernel

在本例中,我们仅过滤 HTTP 服务(端口 80)和源 IP 地址 192.168.122.9854.204.39.132 的数据包。这是检查同一流的两端的快速方法。

5. 检查数据包内容

在前面的示例中,我们仅检查数据包标头中的信息,例如源、目标、端口等。有时,这就是我们排除网络连接问题所需的全部内容。但是,有时我们需要检查数据包的内容,以确保我们发送的消息包含我们需要的内容,或者我们收到了预期的响应。要查看数据包内容,tcpdump 提供了两个额外的标志:-X 以十六进制和 ASCII 打印内容,或 -A 以 ASCII 打印内容。

例如,像这样检查 Web 请求的 HTTP 内容

$ sudo tcpdump -i any -c10 -nn -A port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
13:02:14.871803 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [S], seq 2546602048, win 29200, options [mss 1460,sackOK,TS val 133625221 ecr 0,nop,wscale 7], length 0
E..<..@.@.....zb6.'....P...@......r............
............................
13:02:14.910734 IP 54.204.39.132.80 > 192.168.122.98.39366: Flags [S.], seq 1877348646, ack 2546602049, win 28960, options [mss 1460,sackOK,TS val 525532247 ecr 133625221,nop,wscale 9], length 0
E..<..@./..a6.'...zb.P..o..&...A..q a..........
.R.W.......	................
13:02:14.910832 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 133625260 ecr 525532247], length 0
E..4..@.@.....zb6.'....P...Ao..'...........
.....R.W................
13:02:14.911808 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 133625261 ecr 525532247], length 112: HTTP: GET / HTTP/1.1
E.....@.@..1..zb6.'....P...Ao..'...........
.....R.WGET / HTTP/1.1
User-Agent: Wget/1.14 (linux-gnu)
Accept: */*
Host: opensource.com
Connection: Keep-Alive

................
13:02:14.951199 IP 54.204.39.132.80 > 192.168.122.98.39366: Flags [.], ack 113, win 57, options [nop,nop,TS val 525532257 ecr 133625261], length 0
E..4.F@./.."6.'...zb.P..o..'.......9.2.....
.R.a....................
13:02:14.955030 IP 54.204.39.132.80 > 192.168.122.98.39366: Flags [P.], seq 1:643, ack 113, win 57, options [nop,nop,TS val 525532258 ecr 133625261], length 642: HTTP: HTTP/1.1 302 Found
E....G@./...6.'...zb.P..o..'.......9.......
.R.b....HTTP/1.1 302 Found
Server: nginx
Date: Sun, 23 Sep 2018 17:02:14 GMT
Content-Type: text/html; charset=iso-8859-1
Content-Length: 207
X-Content-Type-Options: nosniff
Location: https://open-source.net.cn/
Cache-Control: max-age=1209600
Expires: Sun, 07 Oct 2018 17:02:14 GMT
X-Request-ID: v-6baa3acc-bf52-11e8-9195-22000ab8cf2d
X-Varnish: 632951979
Age: 0
Via: 1.1 varnish (Varnish/5.2)
X-Cache: MISS
Connection: keep-alive

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="https://open-source.net.cn/">here</a>.</p>
</body></html>
................
13:02:14.955083 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [.], ack 643, win 239, options [nop,nop,TS val 133625304 ecr 525532258], length 0
E..4..@.@.....zb6.'....P....o..............
.....R.b................
13:02:15.195524 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [F.], seq 113, ack 643, win 239, options [nop,nop,TS val 133625545 ecr 525532258], length 0
E..4..@.@.....zb6.'....P....o..............
.....R.b................
13:02:15.236592 IP 54.204.39.132.80 > 192.168.122.98.39366: Flags [F.], seq 643, ack 114, win 57, options [nop,nop,TS val 525532329 ecr 133625545], length 0
E..4.H@./.. 6.'...zb.P..o..........9.I.....
.R......................
13:02:15.236656 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [.], ack 644, win 239, options [nop,nop,TS val 133625586 ecr 525532329], length 0
E..4..@.@.....zb6.'....P....o..............
.....R..................
10 packets captured
10 packets received by filter
0 packets dropped by kernel

这对于排除 API 调用问题很有帮助,前提是这些调用使用纯 HTTP。对于加密连接,此输出的用处较小。

6. 将捕获内容保存到文件

tcpdump 提供的另一个有用功能是将捕获内容保存到文件,以便您可以稍后分析结果。例如,这允许您在夜间以批处理模式捕获数据包,并在早上验证结果。当有太多数据包需要分析时,它也很有帮助,因为实时捕获可能发生得太快。

要将数据包保存到文件而不是在屏幕上显示,请使用选项 -w(表示 写入

$ sudo tcpdump -i any -c10 -nn -w webserver.pcap port 80
[sudo] password for ricardo: 
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
10 packets captured
10 packets received by filter
0 packets dropped by kernel

此命令将输出保存到名为 webserver.pcap 的文件中。.pcap 扩展名代表“数据包捕获”,是此文件格式的约定。

如本示例所示,屏幕上不会显示任何内容,并且捕获会在捕获 10 个数据包后完成,如选项 -c10 所示。如果您想要一些反馈以确保正在捕获数据包,请使用选项 -v

Tcpdump 创建的文件是二进制格式,因此您无法直接使用文本编辑器打开它。要读取文件的内容,请使用 -r(表示 读取)选项执行 tcpdump

$ tcpdump -nn -r webserver.pcap
reading from file webserver.pcap, link-type LINUX_SLL (Linux cooked)
13:36:57.679494 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [S], seq 3709732619, win 29200, options [mss 1460,sackOK,TS val 135708029 ecr 0,nop,wscale 7], length 0
13:36:57.718932 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [S.], seq 1999298316, ack 3709732620, win 28960, options [mss 1460,sackOK,TS val 526052949 ecr 135708029,nop,wscale 9], length 0
13:36:57.719005 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 135708068 ecr 526052949], length 0
13:36:57.719186 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 135708068 ecr 526052949], length 112: HTTP: GET / HTTP/1.1
13:36:57.756979 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [.], ack 113, win 57, options [nop,nop,TS val 526052959 ecr 135708068], length 0
13:36:57.760122 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [P.], seq 1:643, ack 113, win 57, options [nop,nop,TS val 526052959 ecr 135708068], length 642: HTTP: HTTP/1.1 302 Found
13:36:57.760182 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [.], ack 643, win 239, options [nop,nop,TS val 135708109 ecr 526052959], length 0
13:36:57.977602 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [F.], seq 113, ack 643, win 239, options [nop,nop,TS val 135708327 ecr 526052959], length 0
13:36:58.022089 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [F.], seq 643, ack 114, win 57, options [nop,nop,TS val 526053025 ecr 135708327], length 0
13:36:58.022132 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [.], ack 644, win 239, options [nop,nop,TS val 135708371 ecr 526053025], length 0
$ 

由于您不再直接从网络接口捕获数据包,因此读取文件不需要 sudo

您还可以使用我们讨论过的任何过滤器来过滤文件中的内容,就像您处理实时数据一样。例如,通过执行以下命令,检查捕获文件中来自源 IP 地址 54.204.39.132 的数据包

$ tcpdump -nn -r webserver.pcap src 54.204.39.132
reading from file webserver.pcap, link-type LINUX_SLL (Linux cooked)
13:36:57.718932 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [S.], seq 1999298316, ack 3709732620, win 28960, options [mss 1460,sackOK,TS val 526052949 ecr 135708029,nop,wscale 9], length 0
13:36:57.756979 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [.], ack 113, win 57, options [nop,nop,TS val 526052959 ecr 135708068], length 0
13:36:57.760122 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [P.], seq 1:643, ack 113, win 57, options [nop,nop,TS val 526052959 ecr 135708068], length 642: HTTP: HTTP/1.1 302 Found
13:36:58.022089 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [F.], seq 643, ack 114, win 57, options [nop,nop,TS val 526053025 ecr 135708327], length 0

下一步是什么?

tcpdump 的这些基本功能将帮助您开始使用这款强大而通用的工具。要了解更多信息,请查阅 tcpdump 网站手册页

tcpdump 命令行界面为捕获和分析网络流量提供了极大的灵活性。如果您需要图形工具来理解更复杂的流程,请查看 Wireshark

Wireshark 的一个好处是它可以读取 tcpdump 捕获的 .pcap 文件。您可以使用 tcpdump 在没有 GUI 的远程计算机上捕获数据包,并使用 Wireshark 分析结果文件,但这将在另一篇文章中介绍。


本文最初于 2018 年 10 月发布,并由 Seth Kenlon 更新。

标签
Avatar
Ricardo Gerardi 是 Enable Sysadmin 和 Enable Architect 的技术社区倡导者。他之前是 Red Hat Canada 的首席顾问,专门从事 Ansible 和 OpenShift 的 IT 自动化。

5 条评论

作为一名网络工程师,这是我在这个博客上读过的最棒的文章之一。

感谢您分享知识。

确实如此。这是到目前为止我读过的最好的帖子。

回复 作者:Eduardo Toro (未验证)

分享得好,Ricardo。在认识 Wireshark 之前我就使用过这个工具。这让我想怀旧一下 Tdpdump

我猜这是因为自动更正,但您多次使用“packages”代替我理解的“packets”。我错了吗?非常好的文章,除了这个小瑕疵。

感谢您的反馈!您是对的。我会修复它。

回复 作者:Psteve (未验证)

© . All rights reserved.