使用 tcpdump 和 wireshark 分析 tcp 流 - 今日头条

本文由 简悦 SimpRead 转码, 原文地址 www.toutiao.com

使用 tcpdump 和 wireshark 分析 tcp 流 Tcpdump 抓包 tcpdump -w packets.pcap -n -i eth0 tcp

https://p26.toutiaoimg.com/origin/pgc-image/b4581ddefc5042e0b48b54a8bc0163a4?from=pc

使用 tcpdump 和 wireshark 分析 tcp 流

1
tcpdump -w packets.pcap -n -i eth0 tcp port 60 and dst host 10.22.47.66
  • -i: 指定网络接口
  • -n: 不做域名解析,使用 ip
  • -w: 抓包存储为可供 wireshark 解析的 pcap 格式
  • tcp port 60 and dst host 10.22.47.66: 条件表达式

条件表达式语法可以参考: man pcap-filter,下面是一些常见的例子:

只抓 udp 的包:

1
tcpdump -i eth0 'udp'

只想查看源机器和目的机器的包:

1
tcpdump -i eth0 'dst 8.8.8.8'

只想查看目标机器端口是 53 或 80 的包:

1
tcpdump -i eth0 'dst port 53 or dst port 80'

抓到那些通过 eth0 网卡的,且来源是 roclinux.cn 服务器或者目标是 roclinux.cn 服务器的网络包:

1
tcpdump -i eth0 'host roclinux.cn'

抓通过 eth0 网卡的,且 roclinux.cn 和 baidu.com 之间通讯的网络包,或者,roclinux.cn 和 qiyi.com 之间通讯的网络包:

1
tcpdump -i eth0 'host roclinux.cn and (baidu.com or qiyi.com)'

获取使用 ftp 端口和 ftp 数据端口的网络包:

1
tcpdump 'port ftp or ftp-data'

获取 roclinux.cn 和 baidu.com 之间建立 TCP 三次握手中第一个网络包,即带有 SYN 标记位的网络包,另外,目的主机不能是 qiyi.com:

1
tcpdump 'tcp[tcpflags] & tcp-syn != 0 and not dst host qiyi.com'

打印 IP 包长超过 576 字节的网络包:

1
tcpdump 'ip[2:2] > 576'

proto [expr : size],只要掌握了这个语法格式,就能看懂上面的三个稀奇古怪的表达式了。

proto 就是 protocol 的缩写,表示这里要指定的是某种协议的名称,比如 ip、tcp、ether。其实 proto 这个位置,总共可以指定的协议类型有 15 个之多,包括:

  • ether – 链路层协议
  • fddi – 链路层协议
  • tr – 链路层协议
  • wlan – 链路层协议
  • ppp – 链路层协议
  • slip – 链路层协议
  • link – 链路层协议
  • ip
  • arp
  • rarp
  • tcp
  • udp
  • icmp
  • ip6
  • radio

expr 用来指定数据报偏移量,表示从某个协议的数据报的第多少位开始提取内容,默认的起始位置是 0;而 size 表示从偏移量的位置开始提取多少个字节,可以设置为 1、2、4。 如果只设置了 expr,而没有设置 size,则默认提取 1 个字节。比如 ip[2:2],就表示提取出第 3、4 个字节;而 ip[0] 则表示提取 ip 协议头的第一个字节。

在我们提取了特定内容之后,我们就需要设置我们的过滤条件了,我们可用的 “比较操作符” 包括:>,<,>=,<=,=,!=,总共有 6 个。

1
ip[0] & 0xf != 5

IP 协议的第 0-4 位,表示 IP 版本号,可以是 IPv4(值为 0100)或者 IPv6(0110);第 5-8 位表示首部长度,单位是 “4 字节”,如果首部长度为默认的 20 字节的话,此值应为 5。

Wireshark 支持多种 OS,包括 Windows, Mac 和 Linux,我在这里是使用的 Mac 版本。

1
2
3
4
5
6
7
8
$ brew search wireshark
==> Formulae
wireshark

==> Casks
wireshark  wireshark-chmodbpf

$ brew cask install wireshark

在过滤条件中填写 tcp.flags.syn==1,或者 tcp.flags.fin==1, 找到 tcp 连接的首包或者尾包,这样的 tcp 流会相对比较完整;

https://p26.toutiaoimg.com/origin/pgc-image/73dba5af43084764ba8026529ef1628e?from=pc

在找到的包上点右键,选择 Follow=>TCP Stream, 找到这条完整的 tcp 流:

https://p26.toutiaoimg.com/origin/pgc-image/6c1e73ec3660417fab15e1df45a761da?from=pc