如何使用tcpdump捕获和分析网络流量?
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
每行包含以下内容:
- Unix时间戳(
20:58:26.765637
) - 协议(IP)
- 源主机名或IP和端口号(
10.0.0.50.80
) - 目标主机名或IP和端口号(
10.0.0.1.53181
) - TCP标志(
Flags [F.]
)。标志表示连接的状态。这可以包含多个值,例如此示例中的[F.]表示FIN-ACK。此字段可以有以下值:- S – SYN。建立连接的第一步。
- F – FIN。连接终止。
- . – ACK。成功接收到确认数据包。
- P – PUSH。告诉接收方处理数据包而不是缓冲。
- R – RST。通信停止。
- 数据包中数据的序列号(
seq 1
) - 确认号(
ack 2
) - 窗口大小(
win 453
)。接收缓冲区中可用的字节数。其后是TCP选项。 - 数据负载长度(
length 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可以捕获数据包的接口,请使用-D
标志。
# tcpdump -D
或者
# Tcpdump --list-interfaces
1.eth0
2.nflog(Linux netfilter log(NFLOG)接口)
3.nfqueue(Linux netfilter队列(NFQUEUE)接口)
4.eth1
5.any(捕获所有接口的伪设备)
6.lo [Loopback]
这对于没有列出接口的命令的系统特别有用。
要捕获通过特定接口流动的数据包,请使用-i
标志和接口名称。如果没有-i
接口,tcpdump将选择遇到的第一个网络接口。
# tcpdump -i eth1
tcpdump:输出已忽略,使用-v或-vv以进行完整的协议解码
在eth1上监听,链路类型为EN10MB(以太网),捕获大小为262144字节
01:06:09.278817 IP vagrant-ubuntu-trusty-64 > 10.0.0.51:ICMP echo请求,id 4761,seq 1,长度64
01:06:09.279374 IP 10.0.0.51 > vagrant-ubuntu-trusty-64:ICMP echo回复,id 4761,seq 1,长度64
01:06:10.281142 IP vagrant-ubuntu-trusty-64 > 10.0.0.51:ICMP echo请求,id 4761,seq 2,长度64
-v
标志增加了您在数据包上看到的信息,-vv
提供更多详细信息。
默认情况下,tcpdump将IP地址解析为主机名,并使用服务名称而不是端口号。如果DNS无法正常工作或您不希望tcpdump执行名称查找,请使用-n
选项。
# tcpdump -n
在eth0上监听,链路类型为EN10MB(以太网),捕获大小为262144字节
04:19:07.675216 IP 10.0.2.15.22 > 10.0.2.2.50422:标志[P.],序列2186733178:2186733278,确认204106815,窗口37232,长度100
04:19:07.675497 IP 10.0.2.2.50422 > 10.0.2.15.22:标志[.],确认100,窗口65535,长度0
04:19:07.675747 IP 10.0.2.15.22 > 10.0.2.2.50422:标志[P.],序列100:136,确认1,窗口37232,长度36
04:19:07.675902 IP 10.0.2.2.50422 > 10.0.2.15.22:标志[.],确认136,窗口65535,长度0
04:19:07.676142 IP 10.0.2.15.22 > 10.0.2.2.50422:标志[P.],序列136:236,确认1,窗口37232,长度100
要仅捕获一组行,例如5行,请使用-c
标志:
# tcpdump -c 5
04:19:07.675216 IP 10.0.2.15.22 > 10.0.2.2.50422:标志[P.],序列2186733178:2186733278,确认204106815,窗口37232,长度100
04:19:07.675497 IP 10.0.2.2.50422 > 10.0.2.15.22:标志[.],确认100,窗口65535,长度0
04:19:07.675747 IP 10.0.2.15.22 > 10.0.2.2.50422:标志[P.],序列100:136,确认1,窗口37232,长度36
04:19:07.675902 IP 10.0.2.2.50422 > 10.0.2.15.22:标志[.],确认136,窗口65535,长度0
04:19:07.676142 IP 10.0.2.15.22 > 10.0.2.2.50422:标志[P.],序列136:236,确认1,窗口37232,长度100
捕获了5个数据包
默认的tcpdump输出使用Unix时间戳。要捕获具有可读时间戳的数据包:
# tcpdump -tttt
2020-07-06 04:30:12.203638 IP 10.0.2.15.22 > 10.0.2.2.50422:标志[P.],序列2186734102:2186734138,确认204107103,窗口37232,长度36
2020-07-06 04:30:12.203910 IP 10.0.2.2.50422 > 10.0.2.15.22:标志[.],确认36,窗口65535,长度0
2020-07-06 04:30:12.204292 IP 10.0.2.15.22 > 10.0.2.2.50422:标志[P.],序列36:72,确认1,窗口37232,长度36
2020-07-06 04:30:12.204524 IP 10.0.2.2.50422 > 10.0.2.15.22:标志[.],确认72,窗口65535,长度0
2020-07-06 04:30:12.204658 IP 10.0.2.15.22 > 10.0.2.2.50422:标志[P.],序列72:108,确认1,窗口37232,长度36
tcpdump过滤表达式
过滤表达式可选择将显示哪些数据包头。如果未应用过滤器,则显示所有数据包头。常用的过滤器有端口、主机、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: 标志 [SEW],序号 53967733,窗口大小 65535,选项 [mss 1460,nop,wscale 5,nop,nop,TS val 256360128 ecr 0,sackOK,eol],长度 0
23:54:24.978650 IP 10.0.0.50.80 > 10.0.0.1.53971: 标志 [S.E],序号 996967790,确认号 53967734,窗口大小 28960,选项 [mss 1460,sackOK,TS val 5625522 ecr 256360128,nop,wscale 6],长度 0
23:54:24.978699 IP 10.0.0.1.53972 > 10.0.0.50.80: 标志 [SEW],序号 226341105,窗口大小 65535,选项 [mss 1460,nop,wscale 5,nop,nop,TS val 256360128 ecr 0,sackOK,eol],长度 0
23:54:24.978711 IP 10.0.0.50.80 > 10.0.0.1.53972: 标志 [S.E],序号 1363851389,确认号 226341106,窗口大小 28960,选项 [mss 1460,sackOK,TS val 5625522 ecr 256360128,nop,wscale 6],长度 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: 标志 [P.],序号 3862934963:3862934999,确认号 65355639,窗口大小 37232,长度 36
03:48:06.087806 IP 10.0.2.2.50225 > 10.0.2.15.22: 标志 [.],确认号 36,窗口大小 65535,长度 0
03:48:06.088087 IP 10.0.2.15.22 > 10.0.2.2.50225: 标志 [P.],序号 36:72,确认号 1,窗口大小 37232,长度 36
03:48:06.088274 IP 10.0.2.2.50225 > 10.0.2.15.22: 标志 [.],确认号 72,窗口大小 65535,长度 0
03:48:06.088440 IP 10.0.2.15.22 > 10.0.2.2.50225: 标志 [P.],序号 72:108,确认号 1,窗口大小 37232,长度 36
捕获特定协议类型的数据包,例如icmp,在eth1接口上:
# tcpdump -i eth1 icmp
04:03:47.408545 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo请求,标识 2812,序号 75,长度 64
04:03:47.408999 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo回复,标识 2812,序号 75,长度 64
04:03:48.408697 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo请求,标识 2812,序号 76,长度 64
04:03:48.409208 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo回复,标识 2812,序号 76,长度 64
04:03:49.411287 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo请求,标识 2812,序号 77,长度 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: 标志 [F.],序号 500773341,确认号 2116767648,窗口大小 4117,选项 [nop,nop,TS val 257786173 ecr 5979014],长度 0
00:18:17.155104 IP 10.0.0.1.54225 > 10.0.0.50.80: 标志 [S],序号 904045691,窗口大小 65535,选项 [mss 1460,nop,wscale 5,nop,nop,TS val 257786173 ecr 0,sackOK,eol],长度 0
00:18:17.157337 IP 10.0.0.1.54221 > 10.0.0.50.80: 标志 [P.],序号 4282813257:4282813756,确认号 1348066220,窗口大小 4111,选项 [nop,nop,TS val 257786174 ecr 5979015],长度 499: HTTP: GET / HTTP/1.1
00:18:17.157366 IP 10.0.0.1.54225 > 10.0.0.50.80: 标志 [.],确认号 1306947508,窗口大小 4117,选项 [nop,nop,TS val 257786174 ecr 5983566],长度 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:监听eth1,链路类型为EN10MB(以太网),捕获大小为262144字节
捕获到10个数据包
过滤器接收到10个数据包
内核丢弃了0个数据包
您可以使用-r
标志读取此文件:
tcpdump -r icmp.pcap
从文件icmp.pcap中读取,链接类型为EN10MB(以太网)
05:33:20.852732 IP vagrant-ubuntu-trusty-64 > 10.0.0.51:ICMP回显请求,id 3261,seq 33,长度64
05:33:20.853245 IP 10.0.0.51 > vagrant-ubuntu-trusty-64:ICMP回显回复,id 3261,seq 33,长度64
05:33:21.852586 IP vagrant-ubuntu-trusty-64 > 10.0.0.51:ICMP回显请求,id 3261,seq 34,长度64
05:33:21.853104 IP 10.0.0.51 > vagrant-ubuntu-trusty-64:ICMP回显回复,id 3261,seq 34,长度64
05:33:22.852615 IP vagrant-ubuntu-trusty-64 > 10.0.0.51:ICMP回显请求,id 3261,seq 35,长度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:标志[P.],序列号2366590408:2366590907,确认号175457677,窗口4111,选项[nop,nop,TS val 255253117 ecr 5344866],长度499:HTTP:GET / HTTP/1.1
E..'..@.@.%.
...
..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易于设置,一旦您理解输出、各种标志和过滤器,它可以用于解决网络问题和securing your network。