Linux 面试题:tcpdump 抓包原理与常见过滤表达式

在 Linux 运维和后端开发岗位的面试中,网络排查能力始终是重点考察方向,而 tcpdump 作为最经典的命令行抓包工具,几乎是面试必问的知识点。面试官不仅关心你是否会用几条过滤表达式,更在意你是否理解它背后的抓包原理,以及在真实故障场景中如何定位问题。本文围绕 tcpdump 的底层机制与高频过滤表达式展开,帮助你在面试中答出深度。

一、tcpdump 的抓包原理

1.1 从网卡到用户态:数据包的完整路径

tcpdump 本身并不“创造”数据包,它做的事情是从内核中“截获”已经流经网络协议栈的数据包。理解这条路径是回答原理类问题的关键。

当一块网卡收到一个以太网帧时,硬件会通过 DMA 将数据写入内核预先分配好的环形缓冲区(Ring Buffer),然后触发中断通知 CPU。内核的网络驱动在中断处理中把数据包封装成 sk_buff(socket buffer)结构,随后沿着协议栈向上传递:链路层 → 网络层 → 传输层 → 应用层。

tcpdump 的介入点位于链路层和网络层之间。它通过 AF_PACKET 套接字(早期使用 PF_PACKET)直接访问网络设备驱动层的数据,从而在数据包被协议栈进一步处理之前就拿到一份副本。这也是为什么 tcpdump 能抓到非本机目标的广播包、ARP 包,甚至目标 MAC 不是本机的混杂模式流量。

1.2 内核中的 BPF 过滤器

如果每个数据包都要复制到用户态再由 tcpdump 过滤,性能开销会非常大。Linux 的解决方案是 BPF(Berkeley Packet Filter),现在通常称为 eBPF 的前身或经典 BPF。

当你输入 tcpdump port 80 时,tcpdump 并不会简单地把这个字符串当作命令行参数记住,而是会把它编译成一段 BPF 字节码,然后通过 setsockoptSO_ATTACH_FILTER 选项把这段字节码挂载到 AF_PACKET 套接字上。此后,每个到达该套接字的数据包都会先在内核中执行这段 BPF 程序,只有返回非零值(表示“匹配”)的包才会被复制到用户态。这样,无关流量在内核层面就被丢弃了,极大降低了 CPU 和内存开销。

1.3 混杂模式与普通模式

默认情况下,网卡只接收目的 MAC 地址是自己或广播/组播的帧。tcpdump 通过 PACKET_MR_PROMISC 选项可以请求网卡进入混杂模式(Promiscuous Mode),此时网卡会接收所有经过它的帧,无论目的地址是谁。在交换式网络中,这意味着你能看到本机网卡上能收到的所有流量,但不等于能看到整个局域网的所有流量——那需要端口镜像或集线器环境。

面试中常被追问:“tcpdump 能抓到本机不相关的流量吗?”答案是:在混杂模式下可以抓到同一冲突域或镜像端口上的流量,但在普通交换网络中,默认只能看到本机参与或经过本机的流量。

1.4 抓包对性能的影响

由于 BPF 在内核中过滤,tcpdump 对系统性能的影响通常可控。但在高流量场景下,如果过滤表达式写得过于宽泛(比如不加任何过滤),大量数据包被复制到用户态,会导致 CPU 软中断升高、丢包甚至影响业务。因此面试中如果被问到“线上抓包要注意什么”,一定要提到:尽量使用精确过滤、限制抓包数量(-c)、限制抓包大小(-s)、避免长时间全量抓包,必要时配合 -w 写入文件而不是直接打印。

二、常见过滤表达式

tcpdump 的过滤表达式遵循 BPF 语法,由类型(type)、**方向(dir)协议(proto)**三个维度的原语组合而成,支持 andornot(或 &&||!)进行逻辑组合。

2.1 按主机过滤

tcpdump host 192.168.1.100          # 源或目的为该主机
tcpdump src host 192.168.1.100      # 仅源地址
tcpdump dst host 192.168.1.100      # 仅目的地址
tcpdump host 192.168.1.100 and host 10.0.0.1   # 两台主机之间的流量

注意:host 后面可以跟 IP 或域名,但域名会在抓包前解析一次,生产环境建议直接用 IP。

2.2 按端口过滤

tcpdump port 80                     # 源或目的端口为 80
tcpdump src port 1024               # 源端口
tcpdump dst port 443                # 目的端口
tcpdump portrange 8000-9000         # 端口范围
tcpdump port 80 or port 443         # 多个端口

面试高频题:“如何同时抓多个不连续端口?”答案是使用 or 连接,或者写成 tcpdump 'port 80 or port 443 or port 8080'

2.3 按协议过滤

tcpdump tcp                         # 仅 TCP
tcpdump udp                         # 仅 UDP
tcpdump icmp                        # 仅 ICMP
tcpdump arp                         # 仅 ARP
tcpdump ip                          # 仅 IPv4
tcpdump ip6                         # 仅 IPv6

协议过滤可以和其他条件组合,例如 tcpdump tcp port 22 and host 10.0.0.5

2.4 按网络过滤

tcpdump net 192.168.1.0/24          # 整个网段
tcpdump src net 10.0.0.0/8          # 源网段
tcpdump dst net 172.16.0.0/12       # 目的网段

2.5 按数据包特征过滤

这是体现深度的地方,面试中能答出这些往往加分:

tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0'   # 抓 SYN 或 FIN 包
tcpdump 'tcp[tcpflags] & tcp-syn != 0'             # 仅 SYN 包
tcpdump 'tcp[tcpflags] & tcp-rst != 0'             # 仅 RST 包
tcpdump 'ip[8] < 64'                               # TTL 小于 64
tcpdump 'greater 1000'                             # 包长大于 1000 字节
tcpdump 'less 100'                                 # 包长小于 100 字节
tcpdump 'tcp port 80 and (tcp[((tcp[12] & 0xf0) >> 2)] = 0x47)'  # HTTP GET 请求

最后一条虽然复杂,但面试中如果被问到“如何只抓 HTTP GET 请求”,能说出基于 TCP 头部长度偏移定位 payload 首字节的思路,会让人印象深刻。

2.6 常用组合与实战场景

# 抓取某主机与某服务之间的 TCP 流量,写入文件
tcpdump -i eth0 -w capture.pcap host 192.168.1.100 and port 3306

# 抓取非本机 SSH 的流量,限制 100 个包,不解析域名
tcpdump -i any -c 100 -nn tcp port 22 and not host 127.0.0.1

# 抓取 ICMP 包并显示详细信息
tcpdump -i eth0 -v icmp

# 抓取 VLAN 标签流量
tcpdump -i eth0 -e vlan

其中 -i any 表示监听所有接口,-nn 表示不解析主机名和端口名(避免 DNS 反查拖慢抓包),-c 限制数量,-w 写入文件,-r 读取文件,-s 设置 snaplen(0 表示抓完整包)。

三、面试中的常见追问

问:tcpdump 和 Wireshark 有什么区别?
答:tcpdump 是命令行工具,依赖 BPF 在内核过滤,适合服务器环境;Wireshark 是图形化工具,解析能力更强,适合离线分析。两者可以配合使用:tcpdump 抓包存为 pcap,再用 Wireshark 打开分析。

问:为什么抓到的包不完整?
答:可能是 snaplen 设置过小(默认 262144 字节,旧版本默认 68 或 96 字节),或者抓包时发生丢包。可以用 -s 0 抓完整包,用 -w 写文件减少用户态处理压力。

问:如何判断抓包时是否丢了包?
答:tcpdump 退出时会打印 “packets captured” 和 “packets received by filter”,如果两者差距大,说明内核到用户态之间丢了包,通常是过滤太宽或磁盘写入太慢。

掌握 tcpdump 的原理和过滤表达式,不仅能应对面试,更是线上排障的硬功夫。建议在实验环境中多用 -w 抓包再用 Wireshark 分析,把每一条过滤表达式对应到真实的 TCP 握手、HTTP 请求和异常 RST 场景中,理解会深刻得多。

未经允许不得转载:任鹏个人博客 » Linux 面试题:tcpdump 抓包原理与常见过滤表达式

赞 (0) 打赏

评论 0

取消
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏