2、抓包原理:网卡工作模式、混杂模式、BPF过滤器基础、抓包缓冲区设置

说实话,很多人一上来就打开Wireshark点开始抓包,觉得挺简单的。但抓出来的东西对不对、全不全,心里其实没底。我见过不少同事,抓了半天包,结果发现网卡根本没收到目标流量——白忙活一场。

这一章,咱们就把抓包的底层原理掰开揉碎讲清楚。你搞懂了网卡怎么收包、过滤器怎么干活、缓冲区怎么设置,后面分析的时候才能心里有数。

2.1 网卡的工作模式

网卡这东西,平时挺老实的。它只干一件事:看每个经过的数据帧的目标MAC地址,是不是自己。不是自己的,直接扔掉。这叫非混杂模式,也叫正常模式。

但你想啊,如果网卡只收自己的包,那Wireshark还有什么用?我们要抓的,往往是别人家的流量。所以,必须让网卡换个模式干活。

网卡三种工作模式对比

模式 行为 典型场景
非混杂模式 只收目标MAC是自己的帧 普通上网、日常办公
混杂模式 收所有经过的帧,不管MAC是谁 Wireshark抓包、网络监控
多播模式 额外接收多播地址的帧 视频会议、组播应用

我个人习惯,在开始抓包前,先用 ip link 或者Windows的 getmac 看一眼网卡状态。确认混杂模式已经打开,不然抓回来的包永远是残缺的。

2.2 混杂模式——抓包的灵魂

说白了,混杂模式就是让网卡变成一个「聋子」——不对,是变成一个「什么都听的收音机」。它不再挑三拣四,所有经过网线的数据帧,统统收进来。

你想想看,在交换机环境下,流量不是广播给所有人的。交换机只把帧发给目标端口。这时候你开混杂模式也没用,因为帧根本到不了你的网卡。这就是为什么抓交换机之间的流量,得用端口镜像(Port Mirroring)或者接个Hub。

注意: 混杂模式只解决「到了网卡但被过滤掉」的问题,不解决「流量根本不到你网卡」的问题。很多新手在这上面栽跟头。我曾经排查一个数据库慢查询问题,抓了半天只抓到广播包,后来才发现交换机没配端口镜像。

在Linux上开启混杂模式,一行命令搞定:

ip link set eth0 promisc on

Windows上更简单,Wireshark的WinPcap/Npcap驱动会自动帮你打开。但要注意,某些虚拟机环境或者云服务器,底层可能不支持混杂模式。我遇到过阿里云上抓包,怎么都抓不到别人的流量——因为虚拟化层直接给你拦了。

2.3 BPF过滤器——精准抓包的核心

网卡开了混杂模式,所有流量都涌进来了。但很多时候,我们只关心某一种流量。比如只抓HTTP的,或者只抓某个IP的。这时候就需要BPF过滤器。

BPF全称是Berkeley Packet Filter,伯克利包过滤器。它是个虚拟机,运行在内核里。Wireshark把过滤表达式编译成BPF字节码,然后内核帮你做第一道筛选。只有符合条件的包,才从内核拷贝到用户态的Wireshark进程里。

为什么要这么做?因为如果不过滤,所有包都往用户态拷贝,CPU扛不住,磁盘也写不完。我见过有人抓全流量,一分钟就写了几十GB,然后Wireshark直接卡死。

我的经验: 抓包前先想清楚你要看什么。只抓特定端口、特定协议、特定IP。BPF过滤器写得好,抓包效率翻倍。

常用的BPF表达式,我列几个你肯定用得上的:

  • host 192.168.1.1 —— 只抓这个IP的流量
  • port 80 —— 只抓80端口的流量
  • tcp —— 只抓TCP协议
  • icmp —— 只抓ping包
  • not arp —— 排除ARP广播,减少噪音
  • tcp port 443 and host 10.0.0.5 —— 组合条件

Wireshark的「捕获过滤器」用的就是BPF语法。注意,它和「显示过滤器」不一样。捕获过滤器是抓的时候就扔掉不要的包,显示过滤器是抓完了再在界面上隐藏。前者省资源,后者只是视觉隐藏。

捕获过滤器 vs 显示过滤器

类型 作用时机 语法 资源消耗
捕获过滤器 抓包时,内核态 BPF表达式 低,丢弃的包不进内存
显示过滤器 抓包后,用户态 Wireshark表达式 高,所有包已存在内存

我个人习惯,在抓大流量的时候,一定用捕获过滤器先筛一遍。比如只抓 tcp port 443,这样抓回来的文件小,分析起来也快。

2.4 抓包缓冲区设置——别让丢包坑了你

这个知识点,很多人忽略。但恰恰是它,决定了你抓到的包是不是完整的。

Wireshark抓包的时候,数据从网卡到内核,再到Wireshark进程,中间有个缓冲区。如果流量太大,缓冲区满了,新来的包就会被丢掉。你看到的抓包结果,中间可能缺了一段,但你完全不知道。

Wireshark里有个地方可以设置缓冲区大小:Capture → Options → Buffer size。默认是1MB或2MB,对于百兆网络还行,千兆网络下根本不够用。

我曾经踩过的坑: 有一次排查一个间歇性的网络抖动问题,抓了10次包,每次都觉得少了点什么。后来发现缓冲区只有1MB,流量一上来就丢包。改成64MB之后,问题立刻复现了。所以,缓冲区大小不是越大越好,但太小了一定会坑你。

怎么判断有没有丢包?Wireshark的统计里有个「捕获文件属性」,里面会显示「丢弃的包」数量。如果这个数字不是0,说明你的缓冲区不够大,或者磁盘写入速度跟不上。

我建议的缓冲区设置经验:

  • 百兆网络:8MB ~ 16MB
  • 千兆网络:64MB ~ 128MB
  • 万兆网络:256MB以上,最好配合专用抓包硬件

另外,磁盘写入速度也很关键。机械硬盘写大流量文件,很容易成为瓶颈。我一般把抓包文件写到SSD上,或者用内存盘(tmpfs/ramdisk)临时存一下,抓完再拷出来分析。

2.5 本章知识体系总览

下面这张图,把抓包原理的核心逻辑串起来了。从网卡收包,到BPF过滤,再到缓冲区暂存,最后到Wireshark展示。你顺着这个流程走一遍,就知道每个环节该注意什么。

抓包原理核心流程 物理链路(网线/无线) 网卡(混杂模式) BPF过滤器(内核态) 丢弃 抓包缓冲区 Wireshark(用户态) 关键点:混杂模式决定能不能收到 → BPF决定要不要留 → 缓冲区决定会不会丢

嗯,这张图你多看两眼。每次抓包遇到问题,回来对照一下,基本就能定位到是哪个环节出了岔子。