如何使用 tcpdump 捕获和分析网络流量?

tcpdump 是一个很棒的网络嗅探命令行工具。 它是捕获和分析 TCP/IP 数据包的行业标准。

tcpdump 工具在解决网络问题时可以提供很大的帮助。 可以将数据包保存到文件中并在以后进行分析。 偶尔运行此工具以监视您的网络是个好主意。

tcpdump 输出是什么样的?

转储 允许您检查 TCP/IP 数据包的标头。 它为每个数据包打印一行,并且命令一直运行,直到您按 Ctrl+C 终止。

让我们检查示例输出中的一行:

20:58:26.765637 IP 10.0.0.50.80 > 10.0.0.1.53181: Flags [F.], seq 1, ack 2, win 453, options [nop,nop,TS val 3822939 ecr 249100129], length 0

每行包括

  • Unix 时间戳 (20:58:26.765637)
  • 协议(IP)
  • 源主机名或 IP 和端口号 (10.0.0.50.80)
  • 目标主机名或 IP,以及端口号 (10.0.0.1.53181)
  • TCP标志(标志 [F.]). 标志指示连接的状态。 这可以包括多个值,如本例所示 [F.] 对于 FIN-ACK。 该字段可以具有以下值:
    • S——同步。 建立连接的第一步。
    • F——鳍。 连接终止。
    • . – 确认。 确认数据包已成功接收。
    • P——推。 告诉接收方处理数据包而不是缓冲它们。
    • R——RST。 通讯停止了。
  • 数据包中数据的序号。 (序列 1)
  • 确认号 (ack 2)
  • 窗口大小(win 453)。 接收缓冲区中可用的字节数。 接下来是 TCP 选项。
  • 数据负载的长度。 (长度为 0)

安装

在基于 Debian 的发行版上,可以使用 APT 命令安装 tcpdump:

# apt install tcpdump -y

在基于 RPM 的发行版上,可以使用 YUM 安装 tcpdump:

# yum install tcpdump -y

或者如果是 RHEL 8,则使用 DNF

# dnf install tcpdump -y

tcpdump 命令选项

您需要成为 root 用户才能运行 tcpdump。 它包括许多选项和过滤器。 不带任何选项运行 tcpdump 将捕获流经默认接口的所有数据包。

查看系统上可用的网络接口列表以及 tcpdump 可以捕获数据包的网络接口列表。

# tcpdump -D

或者

# Tcpdump --list-interfaces
1.eth0
2.nflog (Linux netfilter log (NFLOG) interface)
3.nfqueue (Linux netfilter queue (NFQUEUE) interface)
4.eth1
5.any (Pseudo-device that captures on all interfaces)
6.lo [Loopback]

这在没有命令列出接口的系统上特别有用。

要捕获流经特定接口的数据包,请使用带有接口名称的 -i 标志。 如果没有 -i 接口,tcpdump 将选择它遇到的第一个网络接口。

# tcpdump -i eth1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
01:06:09.278817 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 4761, seq 1, length 64
01:06:09.279374 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 4761, seq 1, length 64
01:06:10.281142 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 4761, seq 2, length 64

-v 标志增加了您看到的有关数据包的信息,-vv 为您提供了更多详细信息。

默认情况下,tcpdump 将 IP 地址解析为主机名,并且还使用服务名称而不是端口号。 如果 DNS 损坏或您不希望 tcpdump 执行名称查找,请使用 -n 选项。

# tcpdump -n
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
04:19:07.675216 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 2186733178:2186733278, ack 204106815, win 37232, length 100
04:19:07.675497 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 100, win 65535, length 0
04:19:07.675747 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 100:136, ack 1, win 37232, length 36
04:19:07.675902 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 136, win 65535, length 0
04:19:07.676142 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 136:236, ack 1, win 37232, length 100

要仅捕获一组行,比如 5,请使用 -c 标志:

#tcpdump -c 5
04:19:07.675216 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 2186733178:2186733278, ack 204106815, win 37232, length 100
04:19:07.675497 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 100, win 65535, length 0
04:19:07.675747 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 100:136, ack 1, win 37232, length 36
04:19:07.675902 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 136, win 65535, length 0
04:19:07.676142 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 136:236, ack 1, win 37232, length 100
5 packets captured

默认的 tcpdump 输出使用 Unix 时间戳。 要捕获具有人类可读时间戳的数据包:

# tcpdump -tttt
2020-07-06 04:30:12.203638 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 2186734102:2186734138, ack 204107103, win 37232, length 36
2020-07-06 04:30:12.203910 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 36, win 65535, length 0
2020-07-06 04:30:12.204292 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 36:72, ack 1, win 37232, length 36
2020-07-06 04:30:12.204524 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 72, win 65535, length 0
2020-07-06 04:30:12.204658 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 72:108, ack 1, win 37232, length 36

tcpdump 过滤器表达式

过滤器表达式选择将显示哪些数据包标头。 如果未应用过滤器,则显示所有数据包标头。 常用的过滤器有port、host、src、dst、tcp、udp、icmp。

  你应该使用 Hubitat 来自动化你的智能家居吗?

端口过滤器

使用端口过滤器查看到达特定端口的数据包:

# Tcpdump -i eth1 -c 5 port 80
23:54:24.978612 IP 10.0.0.1.53971 > 10.0.0.50.80: Flags [SEW], seq 53967733, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 256360128 ecr 0,sackOK,eol], length 0
23:54:24.978650 IP 10.0.0.50.80 > 10.0.0.1.53971: Flags [S.E], seq 996967790, ack 53967734, win 28960, options [mss 1460,sackOK,TS val 5625522 ecr 256360128,nop,wscale 6], length 0
23:54:24.978699 IP 10.0.0.1.53972 > 10.0.0.50.80: Flags [SEW], seq 226341105, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 256360128 ecr 0,sackOK,eol], length 0
23:54:24.978711 IP 10.0.0.50.80 > 10.0.0.1.53972: Flags [S.E], seq 1363851389, ack 226341106, win 28960, options [mss 1460,sackOK,TS val 5625522 ecr 256360128,nop,wscale 6], length 0

主机过滤器

捕获所有到达或离开 IP 地址为 10.0.2.15 的主机的数据包:

# tcpdump host 10.0.2.15
03:48:06.087509 IP 10.0.2.15.22 > 10.0.2.2.50225: Flags [P.], seq 3862934963:3862934999, ack 65355639, win 37232, length 36
03:48:06.087806 IP 10.0.2.2.50225 > 10.0.2.15.22: Flags [.], ack 36, win 65535, length 0
03:48:06.088087 IP 10.0.2.15.22 > 10.0.2.2.50225: Flags [P.], seq 36:72, ack 1, win 37232, length 36
03:48:06.088274 IP 10.0.2.2.50225 > 10.0.2.15.22: Flags [.], ack 72, win 65535, length 0
03:48:06.088440 IP 10.0.2.15.22 > 10.0.2.2.50225: Flags [P.], seq 72:108, ack 1, win 37232, length 36

在 eth1 接口上抓取特定协议类型的数据包,例如 icmp:

# tcpdump -i eth1 icmp
04:03:47.408545 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 2812, seq 75, length 64
04:03:47.408999 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 2812, seq 75, length 64
04:03:48.408697 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 2812, seq 76, length 64
04:03:48.409208 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 2812, seq 76, length 64
04:03:49.411287 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 2812, seq 77, length 64

组合过滤器表达式

您可以将这些过滤器表达式与 AND、OR 和 NOT 运算符结合起来。 这将使您能够编写可以更精确地隔离数据包的命令:

  如何设置 Microsoft 团队

来自特定 IP 并发往特定端口的数据包:

# tcpdump -n -i eth1 src 10.0.0.1 and dst port 80
00:18:17.155066 IP 10.0.0.1.54222 > 10.0.0.50.80: Flags [F.], seq 500773341, ack 2116767648, win 4117, options [nop,nop,TS val 257786173 ecr 5979014], length 0
00:18:17.155104 IP 10.0.0.1.54225 > 10.0.0.50.80: Flags [S], seq 904045691, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 257786173 ecr 0,sackOK,eol], length 0
00:18:17.157337 IP 10.0.0.1.54221 > 10.0.0.50.80: Flags [P.], seq 4282813257:4282813756, ack 1348066220, win 4111, options [nop,nop,TS val 257786174 ecr 5979015], length 499: HTTP: GET / HTTP/1.1
00:18:17.157366 IP 10.0.0.1.54225 > 10.0.0.50.80: Flags [.], ack 1306947508, win 4117, options [nop,nop,TS val 257786174 ecr 5983566], length 0

要捕获除 ICMP 之外的所有数据包,请使用 NOT 运算符:

# tcpdump -i eth1 not icmp

将包头保存到文件

由于 tcpdump 的输出可以在屏幕上快速滚动,您可以将数据包标头存储到带有 -w 标志的文件中。 保存输出的文件使用 pcap 格式,扩展名为 .pcap。

  如何在 iPad 上使用应用程序的多个窗口

PCAP 代表数据包捕获。 以下命令将 eth1 接口上的 10 行输出保存到 icmp.pcap。

# tcpdump -i eth1 -c 10 -w icmp.pcap
tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
10 packets captured
10 packets received by filter
0 packets dropped by kernel

您可以使用 -r 标志读取此文件:

tcpdump -r icmp.pcap
reading from file icmp.pcap, link-type EN10MB (Ethernet)
05:33:20.852732 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 3261, seq 33, length 64
05:33:20.853245 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 3261, seq 33, length 64
05:33:21.852586 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 3261, seq 34, length 64
05:33:21.853104 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 3261, seq 34, length 64
05:33:22.852615 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 3261, seq 35, length 64

查看数据包详细信息

到目前为止,我们只看到了数据包标头,要查看数据包内容,请使用 -A 选项。 这将以 ASCII 格式打印数据包内容,这有助于网络故障排除。 此外,-X 标志可用于以十六进制格式显示输出。 如果连接是加密的,这可能没有多大帮助。

# tcpdump -c10 -i eth1 -n -A port 80
23:35:53.109306 IP 10.0.0.1.53916 > 10.0.0.50.80: Flags [P.], seq 2366590408:2366590907, ack 175457677, win 4111, options [nop,nop,TS val 255253117 ecr 5344866], length 499: HTTP: GET / HTTP/1.1
E..'[email protected]@.%.
...
..2...P..M.
uE............
.6.}.Q.bGET / HTTP/1.1
Host: 10.0.0.50
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
If-Modified-Since: Tue, 04 Mar 2014 11:46:45 GMT

结论

tcpdump 很容易设置,一旦您理解了输出、各种标志和过滤器,它就可以用来解决网络问题和保护您的网络。