FeelingLife FeelingLife
首页
  • Go

    • Go基础知识
  • Python

    • Python进阶
  • 操作系统
  • 计算机网络
  • MySQL
  • 学习笔记
  • 常用到的算法
  • Docker
  • Kubernetes
  • Observability
  • 容器底层
其他技术
  • 友情链接
  • 收藏
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

xuqil

一介帆夫
首页
  • Go

    • Go基础知识
  • Python

    • Python进阶
  • 操作系统
  • 计算机网络
  • MySQL
  • 学习笔记
  • 常用到的算法
  • Docker
  • Kubernetes
  • Observability
  • 容器底层
其他技术
  • 友情链接
  • 收藏
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 应用层
  • 运输层
  • 抓包

    • tcpdump简要使用
      • 是什么
        • tcpdump的起源
        • 主要作用
      • 工作原理
        • BPF
        • libpcap
        • WinPcap
        • eBPF
      • 抓包文件的类型有哪些
        • pcap
        • cap
        • pcapng
      • 怎么用
        • 帮助文档
        • tcpdump 内容解析
        • 类位置参数
        • 过滤主机
        • 过滤网段
        • 过滤端口
        • 过滤协议
        • 过滤协议版本
        • 可选参数
        • 常用参数
        • 设置不解析域名提升速度
        • 过滤结果输出到文件
        • 指定抓取固定数量的报文
        • 从文件中读取包数据
        • 控制详细内容的输出
        • 控制时间的显示
        • 显示数据包的头部
        • 过滤指定网卡的数据包
        • 过滤特定流向的数据包
        • 其他常用的一些参数
        • 过滤规则组合
        • 逻辑运算符
        • 条件运算符
        • 特殊过滤规则
        • 根据 tcpflags 进行过滤
        • 基于包大小进行过滤
        • 过滤广播/多播数据包
  • 网络编程

  • 云网络

  • 虚拟网络

  • 常见面试题
  • 《计算机网络知识》
  • 抓包
xuqil
2024-09-08
目录

tcpdump简要使用

# tcpdump简要使用

# 是什么

tcpdump是一个网络数据包分析工具,主要用于捕获和分析通过网络接口传输的数据包。它在网络故障排查、性能分析、安全分析等方面非常有用。

# tcpdump的起源 (opens new window)

该程序大致基于 SMI 的“etherfind”,尽管 etherfind 代码已全部消失。它最初由 Van Jacobson 编写,作为正在进行的研究项目的一部分,旨在调查和改进 TCP 和 Internet 网关性能。该程序最初取自 Sun 的 etherfind 的部分后来由 LBL 的 Steven McCanne 重写。为了确保 tcpdump 中不会有专有代码的痕迹,Steve 根据手册条目给出的规范编写了这些部分,而没有访问 tcpdump 或 etherfind 的源代码。

# 主要作用

  • 数据包捕获:tcpdump 可以捕获通过指定网络接口的所有网络流量。
  • 过滤流量:可以通过表达式指定需要捕获的特定流量,比如指定的 IP 地址、端口、协议(TCP/UDP)等。
  • 实时查看或保存捕获结果:可以实时查看捕获的数据包,也可以将捕获的数据包保存到文件中,供以后分析。
  • 解析协议:可以解码多种网络协议,包括 TCP、UDP、ICMP、HTTP、DNS 等,帮助分析网络数据。

# 工作原理

该部分摘自极客时间的《网络排查案例课 (opens new window)》

tcpdump可以工作在各种 Unix 类的操作系统上,包括 Linux、FreeBSD、macOS、Solaris 等,也是目前使用最为广泛的抓包工具之一。但是tcpdump要过滤报文的话,还要依赖一个底层能力:BPF (opens new window)。

# BPF

BPF 全称是 Berkeley Packet Filter(也叫BSD Packet Filter),它是tcpdump等抓包工具的底层基础。在 BPF 出现之前,虽然各家操作系统都有自己的抓包工具,但也都有这样或那样的不足。比如,有些系统把所有网络报文一股脑儿塞给用户空间程序,开销非常大;而有些系统虽然有报文过滤功能,但是工作很不稳定。 为了解决这些问题,1992年,也还是在劳伦斯伯克利国家实验室,当初tcpdump的两个作者史蒂文·麦克凯恩(Steven McCanne)和范·雅各布森(Van Jacobson)发表了关于 BPF 的论文 (opens new window),它以一种新的基于寄存器的虚拟机方式,实现了高效稳定的报文过滤功能。从此以后,抓包技术这棵大树有了一个甚为强大的根基,而构建在 BPF 之上的libpcap、tcpdump等不断枝繁叶茂,进一步使得抓包工作变得方便、稳定。

# libpcap

BPF 实现了抓包虚拟机,但它是如何被用户空间程序使用的呢?于是,libpcap出现了,它提供了 API 给用户空间程序(包括tcpdump、Wireshark等),使得后者能方便地调用 BPF 实现抓包过滤等功能。也就是说,libpcap是 BPF 的一层 API 封装。

tcpdump调用了libpcap接口,后者调用 BPF 实现了报文过滤和抓取。我们来看一下示意图:

image-20240907214902144

# WinPcap

Windows 上也可以做到类似 Linux 这样的抓包,其底层就是依赖 WinPcap,它是libpcap的 Windows 版本。

# eBPF

Linux 从3.18版本开始支持 extended BPF,简称 eBPF。这是一个更加通用的内核接口,不仅能支持网络抓包,还能支持网络以外的内核观测点的信息收集等工作。所以事实上,eBPF 已经是一个通用工具,而不再局限在网络工具这个角色定位上了。

# 抓包文件的类型有哪些

# pcap

这个是libpcap的格式,也是tcpdump和Wireshark等工具默认支持的文件格式。pcap格式的文件中除了报文数据以外,也包含了抓包文件的元信息,比如版本号、抓包时间、每个报文被抓取的最大长度,等等。

# cap

cap文件可能含有一些libpcap标准之外的数据格式,它是由一些tcpdump以外的抓包程序生成的。比如 Citrix 公司的netscaler负载均衡器,它的nstrace命令生成的抓包文件,就是以.cap为扩展名的。这种文件除了包含pcap标准定义的信息以外,还包含了 LB 的前端连接和后端连接之间的mapping信息。Wireshark是可以读取这些.cap文件的,只要在正确的版本上。

# pcapng

pcap格式虽然满足了大部分需求,但是它也有一些不足。比如,现在多网口的情况已经越来越常见了,我们也经常需要从多个网络接口去抓取报文,那么在抓包文件里,如果不把这些报文跟所属的网口信息展示清楚,那我们的分析,岂不是要张冠李戴了吗? 为了弥补pcap格式的不足,人们需要有一种新的文件格式,pcapng就出现了。有了它,单个抓包文件就可以包含多个网络接口上,抓取到的报文了。

# 怎么用

# 帮助文档

tcpdump的官网:https://www.tcpdump.org/index.html,里面可以找到tcpdump最新的版本和相关手册。

查看tcpdump帮助文档:

$ man tcpdump
1

image-20240907215911503

大部分使用方式都可以从中找到,但不是很友好。

我们可以使用这种语法参考:

$ tcpdump [ option ] [ protocol ] [ direction ] [ type ]
1
  • option可选参数:一般使用-指定,是一些常规参数。
  • protocol协议过滤器(位置参数,可选):根据协议进行过滤,可选的值有: tcp,udp,icmp,ip,ip6,arp,rarp,ether,wlan,fddi,tr,decnet。当然,值之间可以使用各种逻辑运算法进行组合使用,例如tcp or udp。
  • direction数据流向过滤器(位置参数,可选):根据数据流向进行过滤,可选的值有:src, dst。当然,值之间也可以使用各种逻辑运算法进行组合使用,例如src or dst。
  • type主机及端口过滤器(位置参数,可选):根据主机、网络 IP、端口等进行过滤。需要key value形式,关键词key有:host、net、port、portrange。

# tcpdump 内容解析

tcpdump port 80 -n
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:44:48.868348 IP 192.168.122.11.80 > 192.168.122.20.42662: Flags [F.], seq 1622076305, ack 1353075739, win 509, options [nop,nop,TS val 3549743074 ecr 1743063663], length 0
1
2
3
4

主要看这段内容:

12:44:48.868348 IP 192.168.122.11.80 > 192.168.122.20.42662: Flags [F.], seq 1622076305, ack 1353075739, win 509, options [nop,nop,TS val 3549743074 ecr 1743063663], length 0
1
  1. 第一列:时分秒毫秒 12:44:48.86834。

  2. 第二列:网络协议 IP。

  3. 第三列:发送方的 IP 地址+端口号,其中192.168.122.11是 IP,而80是端口号(源 IP+源端口号)。

  4. 第四列:箭头>, 表示数据流向。

  5. 第五列:接收方的 IP 地址+端口号,其中192.168.122.20是 IP,而42662是端口号(目标 IP+目标端口号)。

  6. 第六列:冒号:。

  7. 第七列:数据包内容,包括Flags 标识符,seq 号,ack 号,win 窗口,数据长度 length。

    Flags 标识符有如下几种:

    1. [S] : SYN(开始连接)
    2. [P] :PSH(推送数据)
    3. [F] :FIN (结束连接)
    4. [R] :RST(重置连接)
    5. [.] :没有 Flag (意思是除上面四种类型外的其他情况,有可能是 ACK 也有可能是 URG)

# 类位置参数

# 过滤主机

  • 不使用参数:相当于不过滤,啥都抓取。

    $ tcpdump
    
    1
  • 通过host参数指定主机ip或主机名进行过滤

    # 指定主机 IP
    $ tcpdump host 192.168.122.11
    # 指定主机名
    $ tcpdump host 11.dev.com
    
    1
    2
    3
    4
  • 指定源主机/目标主机

    # src host 用于指定源主机
    $ tcpdump src host 192.168.122.11 
    # dst host 用于指定目标主机
    $ tcpdump dst host 192.168.122.11
    # dst or src host 用于指定源主机或目标主机(两个条件之一成立即可)
    $ tcpdump dst or src host 192.168.122.11
    
    1
    2
    3
    4
    5
    6

# 过滤网段

  • 根据网段进行过滤

    $ tcpdump net 192.168.122.0/24
    
    1
  • 指定源网段/目标网段

    $ tcpdump src net 192.168.122.0/24
    $ tcpdump dst net 192.168.122.0/24
    
    1
    2

# 过滤端口

  • 使用 port 指定特定端口进行过滤

    # 过滤80端口
    $ tcpdump port 80
    
    1
    2
  • 指定源端口/目标端口号

    # 过滤源端口号为 80 的包
    $ tcpdump src port 80
    # 过滤目标端口号为 80 的包
    $ tcpdump dst port 80
    # 过滤目标/源端口号为 80 的包
    $ tcpdump dst or src port 80 
    
    1
    2
    3
    4
    5
    6
  • 指定多个端口号

    # 指定 80 端口和 8080 端口
    $ tcpdump port 80 or port 8080
    # 可以简写成这样
    $  tcpdump port 80 or 8080
    
    1
    2
    3
    4
  • 端口号范围

    $ tcpdump portrange 80-8080
    $ tcpdump src portrange 80-8080
    $ tcpdump dst portrange 80-8080
    
    1
    2
    3
  • 知名端口

    # http 为知名端口,即80
    $ tcpdump port http
    
    1
    2

# 过滤协议

可以支持的协议有:tcp,udp,icmp,ip,ip6,arp,rarp,ether,wlan,fddi,tr,decnet等等。

  • 只过滤icmp的包

    $ tcpdump icmp
    
    1
  • 只看tcp的包

    $ tcpdump tcp
    
    1

# 过滤协议版本

tcpdump tcp默认包含了 IPv4 和 IPv6 的tcp,需要对 IPv4 和 IPv6 进行区分,可以使用proto关联。

  • 过滤 IPv4 的包

    # 显式指定 tcp
    $ tcpdump 'ip && tcp'
    # 通过编号指定 tcp
    $ tcpdump ip proto 6
    
    1
    2
    3
    4

    数字 6 表示的是tcp在ip报文中的编号。其他协议与数字的映射关系如下:

    • tcp:6
    • icmp:1
    • udp:17
  • 过滤 IPv6 的包

    # ip6 表示 IPv6
    $ tcpdump 'ip6 proto tcp'
    #  通过编号指定 tcp
    $ tcpdump ip6 proto 6
    
    1
    2
    3
    4

# 可选参数

# 常用参数

  • -w 文件名,可以把报文保存到文件;
  • -c 数量,可以抓取固定数量的报文,这在流量较高时,可以避免一不小心抓取过多报文;
  • -s 长度,可以只抓取每个报文的一定长度;
  • -n,不做地址转换(比如IP地址转换为主机名,port 80 转换为http);
  • -v/-vv/-vvv,可以打印更加详细的报文信息;
  • -e,可以打印二层信息,特别是MAC地址;
  • -p,关闭混杂模式。所谓混杂模式,也就是嗅探(Sniffering),就是把目的地址不是本机地址的网络报文也抓取下来。

# 设置不解析域名提升速度

上面过滤的结果基本都会显示域名,不利于我们分析,我们可以使用以下参数设置,不将ip转为域名打印。

  • -n:不把ip转化成域名,直接显示ip,避免执行 DNS lookups 的过程,速度会快很多。
  • -nn:不把协议和端口号转化成名字,速度也会快很多。
  • -N:不打印host的域名部分。比如域名为11.dev.com,那么只会打印11。

# 过滤结果输出到文件

通常,我们会将tcpdump抓到的包保存在.pcap后缀的文件里,然后使用wireshark进行分析。

可以使用-w参数接.pcap后缀的文件,就可以将结果保存到文件里。

$ tcpdump tcp -w dev-tcp.pcap
1

可以同时按Ctrl+c结束抓包。

# 指定抓取固定数量的报文

指定抓取固定数量的报文,防止抓取的流量过多或写入的文件过大。

# 指定只抓取10个包
$ tcpdump tcp -w dev-tcp.pcap -c 10
1
2

# 从文件中读取包数据

使用 -w 是写入数据到文件,而使用 -r 是从文件中读取数据。读取后,我们照样可以使用上述的过滤器语法进行过滤分析。

$ tcpdump -r dev_tcp.pcap  tcp
1

# 控制详细内容的输出

  • -v:产生详细的输出,比如包的TTL、id标识、数据包长度,以及IP包的一些选项。同时它还会打开一些附加的包完整性检测,比如对IP或ICMP包头部的校验和。
  • -vv:产生比-v更详细的输出,比如NFS回应包中的附加域将会被打印。
  • -vvv:产生比-vv更详细的输出。比如telent时所使用的 SB、SE 选项将会被打印。

# 控制时间的显示

  • -t:在每行的输出中不输出时间。
  • -tt:在每行的输出中会输出时间戳。
  • -ttt:输出每两行打印的时间间隔(以毫秒为单位)。
  • -tttt:在每行打印的时间戳之前添加日期的打印(此种选项,输出的时间最直观)。

# 显示数据包的头部

  • -x:以16进制的形式打印每个包的头部数据(但不包括数据链路层的头部)。
  • -xx:以16进制的形式打印每个包的头部数据(包括数据链路层的头部)。
  • -X:以16进制和 ASCII码形式打印出每个包的数据(但不包括连接层的头部),这在分析一些新协议的数据包很方便。
  • -XX:以16进制和 ASCII码形式打印出每个包的数据(包括连接层的头部),这在分析一些新协议的数据包很方便。

# 过滤指定网卡的数据包

  • -i:指定要过滤的网卡接口,如果要查看所有网卡,可以 -i any。

    $ tcpdump tcp -i ens33
    
    1

# 过滤特定流向的数据包

-Q: 选择是入方向还是出方向的数据包,可选项有:in、out、 inout。

# 只抓取出去的包
$ tcpdump tcp -i ens33 -Q out
# 只抓取进来的包
$ tcpdump tcp -i ens33 -Q in
# 抓取进去的包(不指定就是)
$ tcpdump tcp -i ens33 -Q inout
1
2
3
4
5
6

# 其他常用的一些参数

  • -A:以ASCII码方式显示每一个数据包(不显示链路层头部信息)。在抓取包含网页数据的数据包时, 可方便查看数据。
  • -l: 基于行的输出(不指定默认就是),便于你保存查看,或者交给其它工具分析。
  • -q :简洁地打印输出。即打印很少的协议相关信息,从而输出行都比较简短。
  • -s : tcpdump默认只会截取前 96 字节的内容,要想截取所有的报文内容,可以使用 -s number, number 就是你要截取的报文字节数,如果是 0 的话,表示截取报文全部内容。
  • -S : 使用绝对序列号,而不是相对序列号。
  • -C:file-size 指定切割文件的文件大小。tcpdump 在把原始数据包直接保存到文件中之前,检查此文件大小是否超过file-size ,如果超过了,将关闭此文件,另创一个文件继续用于原始数据包的记录.。新创建的文件名与-w 选项指定的文件名一致,,但文件名后多了一个数字,该数字会从1开始随着新创建文件的增多而增加。file-size的单位是百万字节(这里指1,000,000个字节)
  • -G:rotate_seconds指定文件轮转的时间(单位为秒)。例如rotate_seconds的值为3,表示每3秒会切割成另一个文件,一般与-C、-w一起使用。
  • -F:使用file文件作为过滤条件表达式的输入,此时命令行上的输入将被忽略。
  • -D :显示所有可用网络接口的列表。
  • -e :每行的打印输出中将包括数据包的数据链路层头部信息。
  • -E :揭秘IPSEC数据。
  • -L :列出指定网络接口所支持的数据链路层的类型后退出。
  • -Z:后接用户名,在抓包时会受到权限的限制。如果以 root 用户启动tcpdump,tcpdump将会有超级用户权限。
  • -d:打印出易读的包匹配码。
  • -dd:以C语言的形式打印出包匹配码。
  • -ddd:以十进制数的形式打印出包匹配码。

# 过滤规则组合

# 逻辑运算符

支持的逻辑运算符号:

  • and(与):所有的条件都需要满足,也可以表示为 &&。
  • or(或):只要有一个条件满足就可以,也可以表示为 ||。
  • not(非):取反,也可以使用 !。

例如,想需要抓一个来自192.168.122.20主机,目标端口号为 80 的包:

$ tcpdump src host 192.168.122.20 and dst port 80
1

当你在使用多个过滤器进行组合时,有可能需要用到括号,而括号在shell 中是特殊符号,因为你需要使用引号(单引号和双引号都可以)将其包含。例子如下:

$ tcpdump 'src 192.168.122.20 and (dst port 80 or 443)'
1

# 条件运算符

而在单个过滤器里,常常会判断一条件是否成立,这时候,就要使用下面的条件运算符:

  • =:判断二者相等
  • ==:判断二者相等
  • !=:判断二者不相等

我们想要过滤出 TCP RST 报文,那么可以用下面这种写法:

$ tcpdump 'tcp[tcpflags]&(tcp-rst) != 0'
1

# 特殊过滤规则

# 根据 tcpflags 进行过滤

我们想要过滤出 TCP RST 报文,那么可以用下面这种写法,相对来说比用数字做偏移量的写法,要更加容易理解和记忆:

$ tcpdump -w file.pcap 'tcp[tcpflags]&(tcp-rst) != 0'
1

如果是用偏移量的写法,会是下面这样:

$ tcpdump -w file.pcap 'tcp[13]&4 != 0'
1

# 基于包大小进行过滤

若你想查看指定大小的数据包,也是可以的

$ tcpdump less 32 
$ tcpdump greater 64 
$ tcpdump <= 128
1
2
3

# 过滤广播/多播数据包

$ tcpdump ether broadcast
$ tcpdump ether multicast

$ tcpdump ip broadcast
$ tcpdump ip multicast

$ tcpdump ip6 multicast
1
2
3
4
5
6
7
上次更新: 2024/09/08, 12:55:22
运输层
Linux的IO模型

← 运输层 Linux的IO模型→

最近更新
01
VXLAN互通实验
05-13
02
VXLAN
05-13
03
VLAN
05-13
更多文章>
Theme by Vdoing | Copyright © 2018-2025 FeelingLife | 粤ICP备2022093535号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式