网络数据包分析利器:tcpdump 命令详解
tcpdump
是一款卓越的网络嗅探命令行工具,在捕获和分析 TCP/IP 数据包领域,它堪称业界标准。 掌握 tcpdump
的使用,对于排查网络故障,监控网络流量至关重要。
此工具在解决网络难题时能够提供强有力的支持。 它不仅能实时捕获数据包,还能将其保存至文件,便于日后深入分析。 为了保持对网络状态的敏锐洞察,定期运行 tcpdump
进行网络监控是一个明智的选择。
解读 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
上面这一行包含了以下关键信息:
时间戳 | (20:58:26.765637) – Unix 时间戳,精确到微秒。 |
协议 | (IP) – 表明数据包使用的网络协议。 |
源地址和端口 | (10.0.0.50.80) – 发送数据包的主机 IP 地址和端口号。 |
目标地址和端口 | (10.0.0.1.53181) – 接收数据包的主机 IP 地址和端口号。 |
TCP 标志 | (Flags [F.]) – 用于指示连接状态的 TCP 标志。 [F.] 表示 FIN-ACK 标志,用于关闭连接。 常见的 TCP 标志包括:
|
序列号 | (seq 1) – 数据包中数据的序列号。 |
确认号 | (ack 2) – 确认号,用于确认收到的数据。 |
窗口大小 | (win 453) – 接收缓冲区中可用的字节数。 |
TCP 选项 | (options [nop,nop,TS val 3822939 ecr 249100129]) – TCP 协议的各种选项。 |
数据长度 | (length 0) – 数据负载的长度,此处为 0。 |
安装 tcpdump
在基于 Debian 的 Linux 发行版上,您可以使用 apt
命令来安装 tcpdump
:
# apt install tcpdump -y
对于基于 RPM 的 Linux 发行版,可以使用 yum
命令进行安装:
# yum install tcpdump -y
或者,在 RHEL 8 系统中,可以使用 dnf
命令:
# dnf install tcpdump -y
tcpdump
命令的常用选项
要运行 tcpdump
,您需要具备 root 权限。 该工具提供了丰富的选项和过滤器。 若不带任何选项运行,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 时间戳。 若要捕获具有人类可读时间戳的数据包,可以使用 -tttt
选项:
# 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
。
端口过滤器
使用端口过滤器可以查看到达特定端口的数据包:
# 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
运算符结合使用,以编写更精确的数据包筛选命令:
从特定 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
。
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
的设置过程非常简单。 一旦您理解了它的输出信息、各种标志以及过滤器,就可以使用它来解决网络问题并保护您的网络安全。