Linux tcpdump

tcpdump是Linux系统中功能强大的网络工具, 运行在用户态,通过调用 libpcap 库的 api 来实现数据包的抓取。常用于故障诊断,网络分析,收集网络数据包,分析协议格式。

数据包到达网卡后,经过数据包过滤器(BPF),并根据用户输入的过滤规则筛选,把筛选出的数据包拷贝至用户态的 tcpdump 程序,以供 tcpdump 工具进行后续的处理工作,输出或保存到 pcap 文件。如图:

基础用法

  1. 不加任何参数,默认情况下将抓取第一个非 lo 网卡上所有的数据包
1
$ tcpdump 
  1. 抓取 eth0 网卡上的所有数据包
1
$ tcpdump -i eth0
  1. 抓包时指定 -n 选项,不解析主机和端口名。这个参数很关键,会影响抓包的性能,一般抓包时都需要指定该选项。
1
$ tcpdump -n -i eth0
  1. 抓取指定主机 192.168.1.100 的所有数据包
1
$ tcpdump -ni eth0 host 192.168.1.100
  1. 抓取指定主机 10.1.1.2 发送的数据包
1
$ tcpdump -ni eth0 src host 10.1.1.2
  1. 抓取发送给 10.1.1.2 的所有数据包
1
$ tcpdump -ni eth0 dst host 10.1.1.2
  1. 抓取 eth0 网卡上发往指定主机的数据包,抓到 10 个包就停止,这个参数也比较常用
1
$ tcpdump -ni eth0 -c 10 dst host 192.168.1.200
  1. 抓取 eth0 网卡上所有 SSH 请求数据包,SSH 默认端口是 22
1
$ tcpdump -ni eth0 dst port 22
  1. 抓取 eth0 网卡上 5 个 ping 数据包
1
$ tcpdump -ni eth0 -c 5 icmp
  1. 抓取 eth0 网卡上所有的 arp 数据包
1
$ tcpdump -ni eth0 arp
  1. 使用十六进制输出,当你想检查数据包内容是否有问题时,十六进制输出会很有帮助。
1
2
3
4
5
$ tcpdump -ni eth0 -c 1 arp -X
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
12:13:31.602995 ARP, Request who-has 172.17.92.133 tell 172.17.95.253, length 28
    0x0000:  0001 0800 0604 0001 eeff ffff ffff ac11  ................
    0x0010:  5ffd 0000 0000 0000 ac11 5c85            _.........\.
  1. 只抓取 eth0 网卡上 IPv6 的流量
1
$ tcpdump -ni eth0 ip6
  1. 抓取指定端口范围的流量
1
$ tcpdump -ni eth0 portrange 80-9000
  1. 抓取指定网段的流量
1
$ tcpdump -ni eth0 net 192.168.1.0/24

高级进阶

  1. 抓取指定客户端访问 ssh 的数据包
1
$ tcpdump -ni eth0 src 192.168.1.100 and dst port 22
  1. 抓取从某个网段来,到某个网段去的流量
1
$ tcpdump -ni eth0 src net 192.168.1.0/16 and dst net 10.0.0.0/8 or 172.16.0.0/16
  1. 抓取来自某个主机,发往非 ssh 端口的流量
1
$ tcpdump -ni eth0 src 10.0.2.4 and not dst port 22
  1. 过滤 TCP 特殊标记的数据包

抓取某主机发送的 RST 数据包:

1
$ tcpdump -ni eth0 src host 192.168.1.100 and 'tcp[tcpflags] & (tcp-rst) != 0'

抓取某主机发送的 SYN 数据包:

1
$ tcpdump -ni eth0 src host 192.168.1.100 and 'tcp[tcpflags] & (tcp-syn) != 0'

抓取某主机发送的 FIN 数据包:

1
$ tcpdump -ni eth0 src host 192.168.1.100 and 'tcp[tcpflags] & (tcp-fin) != 0'

抓取 TCP 连接中的 SYN 或 FIN 包

1
$ tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0'

常用选项

  1. 基础选项
  • -i:指定接口
  • -D:列出可用于抓包的接口
  • -s:指定数据包抓取的长度
  • -c:指定要抓取的数据包的数量
  • -w:将抓包数据保存在文件中
  • -r:从文件中读取数据
  • -C:指定文件大小,与 -w 配合使用
  • -F:从文件中读取抓包的表达式
  • -n:不解析主机和端口号,这个参数很重要,一般都需要加上
  • -P:指定要抓取的包是流入还是流出的包,可以指定的值 in、out、inout
  1. 输出选项
  • -e:输出信息中包含数据链路层头部信息
  • -t:显示时间戳,tttt 显示更详细的时间
  • -X:显示十六进制格式
  • -v:显示详细的报文信息,尝试 -vvv,v 越多显示越详细

过滤表达式

tcpdump 强大的功能和灵活的策略,主要体现在过滤器(BPF)强大的表达式组合能力。

  1. 操作对象

表达式中可以操作的对象有如下几种:

  • type: 表示对象的类型,比如:host、net、port、portrange,如果不指定 type 的话,默认是 host
  • dir:表示传输的方向,可取的方式为:src、dst。
  • proto:表示协议,可选的协议有:ether、ip、ip6、arp、icmp、tcp、udp。
  1. 条件组合

表达对象之间还可以通过关键字 and、or、not 进行连接,组成功能更强大的表达式。

  • or:表示或操作
  • and:表示与操作
  • not:表示非操作

参考