文章目录


每日一博 - tcpdump小技巧_centos



what

tcpdump 网络工具, 通常用于故障诊断、网络分析 ,甩锅必备, 那还等什么

每日一博 - tcpdump小技巧_centos_02



网络包接收过程

每日一博 - tcpdump小技巧_linux_03

在接收包的过程中,数据包是先经过网络设备层然后才到协议层的。

每日一博 - tcpdump小技巧_十六进制_04

假如我们设置了 netfilter 规则,在接收包的过程中,工作在网络设备层的 tcpdump 先开始工作。还没等 netfilter 过滤,tcpdump 就抓到包了!

所以,在接收包的过程中,netfilter 过滤并不会影响 tcpdump 的抓包!



网络包发送过程

每日一博 - tcpdump小技巧_linux_05

在网络包的发送过程中,和接收过程恰好相反,是协议层先处理、网络设备层后处理。

每日一博 - tcpdump小技巧_linux_06

如果 netfilter 设置了过滤规则,那么在协议层就直接过滤掉了。在下层网络设备层工作的 tcpdump 将无法再捕获到该网络包。



工作原理

tcpdump 是 Linux 系统中非常有用的网络工具,运行在用户态,本质上是通过调用 libpcap 库的各种 api 来实现数据包的抓取功能.

用户态 tcpdump 命令是通过 socket 系统调用,在内核源码中用到的 ptype_all 中挂载了函数钩子上去。无论是在网络包接收过程中,还是在发送过程中,都会在网络设备层遍历 ptype_all 中的协议,并执行其中的回调。tcpdump 命令就是基于这个底层原理来工作的。

每日一博 - tcpdump小技巧_centos_07

通过上图我们可以发现当数据包到达网卡后,经过数据包过滤器(BPF)筛选后,拷贝至用户态的 tcpdump 程序,以供 tcpdump 工具进行后续的处理工作,输出或保存到 pcap 文件。

数据包过滤器(BPF)主要作用,就是根据用户输入的过滤规则,只将用户关心的数据包拷贝至 tcpdump,这样能够减少不必要的数据包拷贝,降低抓包带来的性能损耗。

每日一博 - tcpdump小技巧_抓包_08



基础用法

不加任何参数,默认情况下将抓取第一个非 lo 网卡上所有的数据包

[root@VM-0-7-centos ~]# tcpdump

抓取 eth0 网卡上的所有数据包

[root@VM-0-7-centos ~]# tcpdump  -i eth0

抓包时指定 -n 选项,不解析主机和端口名。

这个参数很关键,会影响抓包的性能,一般抓包时都需要指定该选项。

[root@VM-0-7-centos ~]#  tcpdump -n -i eth0

每日一博 - tcpdump小技巧_linux_09

抓取指定主机 192.168.1.100 的所有数据包

[root@VM-0-7-centos ~]#  tcpdump -ni eth0 host 192.168.1.100

抓取指定主机 10.1.1.2 发送的数据包

[root@VM-0-7-centos ~]# tcpdump -ni eth0 src host 10.1.1.2

抓取发送给 10.1.1.2 的所有数据包

[root@VM-0-7-centos ~]#  tcpdump -ni eth0 dst host 10.1.1.2

抓取 eth0 网卡上发往指定主机的数据包,抓到 10 个包就停止

这个参数也比较常用

[root@VM-0-7-centos ~]#  tcpdump -ni eth0 -c 10 dst host 192.168.1.200

抓取 eth0 网卡上所有 SSH 请求数据包,SSH 默认端口是 22

[root@VM-0-7-centos ~]#  tcpdump -ni eth0 dst port 22

抓取 eth0 网卡上 5 个 ping 数据包

[root@VM-0-7-centos ~]#  tcpdump -ni eth0 -c 5 icmp

每日一博 - tcpdump小技巧_centos_10

抓取 eth0 网卡上所有的 arp 数据包

[root@VM-0-7-centos ~]#  tcpdump -ni eth0 arp

使用十六进制输出,当你想检查数据包内容是否有问题时,十六进制输出会很有帮助。

[root@VM-0-7-centos ~]#  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 _.........\.

只抓取 eth0 网卡上 IPv6 的流量

[root@VM-0-7-centos ~]#  tcpdump -ni eth0 ip6

每日一博 - tcpdump小技巧_抓包_11

抓取指定端口范围的流量

[root@VM-0-7-centos ~]#  tcpdump -ni eth0 portrange 80-9000

抓取指定网段的流量

[root@VM-0-7-centos ~]#  tcpdump -ni eth0 net 192.168.1.0/24

每日一博 - tcpdump小技巧_十六进制_12

高级进阶

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

每日一博 - tcpdump小技巧_抓包_13

抓取指定客户端访问 ssh 的数据包

$ tcpdump -ni eth0 src 192.168.1.100 and dst port 22

抓取从某个网段来,到某个网段去的流量

$ tcpdump -ni eth0 src net 192.168.1.0/16 and dst net 10.0.0.0/8 or 172.16.0.0/16

抓取来自某个主机,发往非 ssh 端口的流量

$ tcpdump -ni eth0 src 10.0.2.4 and not dst port 22

当构建复杂查询的时候,你可能需要使用引号,单引号告诉 tcpdump 忽略特定的特殊字符,这里的 () 就是特殊符号,如果不用引号的话,就需要使用转义字符

$ tcpdump -ni eth0 'src 10.0.2.4 and (dst port 3389 or 22)'

每日一博 - tcpdump小技巧_十六进制_14

基于包大小进行筛选,如果你正在查看特定的包大小,可以使用这个参数

小于等于 64 字节:

$ tcpdump -ni less 64

大于等于 64 字节:

$ tcpdump -ni eth0 greater 64

等于 64 字节:

$ tcpdump -ni eth0 length == 64

过滤 TCP 特殊标记的数据包

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

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

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

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

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

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

抓取 TCP 连接中的 SYN 或 FIN 包

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

每日一博 - tcpdump小技巧_抓包_15

抓取所有非 ping 类型的 ICMP 包

$ tcpdump 'icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply'

抓取端口是 80,网络层协议为 IPv4, 并且含有数据,而不是 SYN、FIN 以及 ACK 等不含数据的数据包

$ tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'

解释一下这个复杂的表达式,具体含义就是,整个 IP 数据包长度减去 IP 头长度,再减去 TCP 头的长度,结果不为 0,就表示数据包有 data,如果还不是很理解,需要自行补一下 tcp/ip 协议

抓取 HTTP 报文,0x4754 是 GET 前两字符的值,0x4854 是 HTTP 前两个字符的值

$ tcpdump  -ni eth0 'tcp[20:2]=0x4745 or tcp[20:2]=0x4854'

每日一博 - tcpdump小技巧_tcpdump_16

常用选项

(一)基础选项

-i:指定接口
-D:列出可用于抓包的接口
-s:指定数据包抓取的长度
-c:指定要抓取的数据包的数量
-w:将抓包数据保存在文件中
-r:从文件中读取数据
-C:指定文件大小,与 -w 配合使用
-F:从文件中读取抓包的表达式
-n:不解析主机和端口号,这个参数很重要,一般都需要加上
-P:指定要抓取的包是流入还是流出的包,可以指定的值 in、out、inout

每日一博 - tcpdump小技巧_抓包_17

(二)输出选项

-e:输出信息中包含数据链路层头部信息
-t:显示时间戳,tttt 显示更详细的时间
-X:显示十六进制格式
-v:显示详细的报文信息,尝试 -vvv,v 越多显示越详细



过滤表达式

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

(一)操作对象

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

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

(二)条件组合

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

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

每日一博 - tcpdump小技巧_linux_18



netfilter 过滤的包 tcpdump是否可以抓的到

关于这个问题,得分接收和发送过程分别来看。

在网络包接收的过程中,由于 tcpdump 近水楼台,所以完全可以捕获到命中 netfilter 过滤规则的包。

每日一博 - tcpdump小技巧_linux_19

但是在发送的过程中,恰恰相反。网络包先经过协议层,这时候被 netfilter 过滤掉的话,底层工作的 tcpdump 还没等看见就啥也没了。

每日一博 - tcpdump小技巧_linux_20

每日一博 - tcpdump小技巧_抓包_21