如何使用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

类似文章