【Linux】软件工程师的屠龙技—eBPF(编辑中)

目录

简介

工作原理

在内核中运行

与内核组件交互

常见应用场景

框架与工具

使用例子


简介

eBPF(extended Berkeley Packet Filter),即“增强版伯克利数据包过滤器”或“伯克利数据包过滤器扩展版”,是一种在Linux内核中运行沙盒程序的技术。

叫这个名字的原因是:

  • eBPF起源于BSD包过滤器(Berkeley Packet Filter),最初用于高效地过滤网络数据包。
  • 随着技术的演进,从2014年Linux内核3.18版开始,BPF发展为“扩展BPF”(eBPF),增加了许多新特性和功能。

工作原理

eBPF源于BPF,但经过重新设计,它不再局限于网络协议栈,而是成为了一个内核顶级的子系统,演进为一个通用执行引擎。eBPF分为用户空间程序和内核程序两部分:

  • 用户空间程序负责加载BPF字节码至内核,如需要也会负责读取内核回传的统计信息或者事件详情。
  • 内核中的BPF字节码负责在内核中执行特定事件,如需要也会将执行的结果通过maps或者perf-event事件发送至用户空间。

在内核中运行

eBPF可以理解为是kernel中实现的一个虚拟机机制(因为要在内核执行代码进行监控、沙盒、网络过滤、程序跟踪、性能分析和调试,出错了容易导致内核崩溃引起各种bug,所以需要搞成虚拟机,在虚拟机里面运行保证安全,其拥有自定义的64位RISC指令集,可以在linux内核中运行即时编译的BPF程序,支持访问内核功能和内存的部分子集)。具体原理为:

  • 它会将类C代码编译为BPF字节码,类似Java字节码。
  • 然后将对应的程序代码挂到内核的钩子上。当钩子函数被调用时,内核将在eBPF虚拟机这个沙盒中执行字节码。

如下图,代码Hook像一个钩子,可以钩子内核代码的任意位置,然后就在这个勾住的位置上执行自己定义的代码逻辑:数据过滤,调试。

与内核组件交互

eBPF通过“挂钩点”(hook)来与内核的不同组件进行交互。最常见的挂钩点包括:

  • 网络层‌:eBPF最初的用途是数据包过滤。使用eBPF,开发者可以为网络接口卡(NIC)添加过滤器,实现精细的网络流量控制。
  • 跟踪点(Tracing)‌:通过在特定的函数入口或出口插入eBPF钩子,可以实现对内核行为的实时监控和分析。
  • 安全审计‌:eBPF能够跟踪系统调用的执行,对可能的安全威胁进行实时检测。

常见应用场景

eBPF已被广泛应用于各种场景中,主要包括:

  • 性能监控‌:通过跟踪系统调用、函数调用、I/O延迟、CPU使用情况等,帮助开发人员深入分析系统性能瓶颈。
  • 安全审计‌:eBPF可以用来实时监控系统调用,检测潜在的恶意活动或安全漏洞。
  • 网络优化与防火墙‌:eBPF能够捕获网络数据包,进行流量分析和网络优化、DDoS防护、恶意流量拦截等安全场景。通过XDP(eXpress Data Path)和其他eBPF程序,可以在内核中实现高效的网络数据包过滤和处理,减少网络延迟并提高吞吐量。
  • 故障诊断‌:eBPF能够实时收集系统性能数据,为开发人员捕获系统级别的错误信息、性能瓶颈,快速定位问题。

例子:

(摘自:内核技术介绍 | 软件工程师的屠龙技—eBPF_哔哩哔哩_bilibili)

比如:

调试性能,排查了应用层的问题之后,就怀疑内核部分的问题,就可以在内核用eBPF把我们的调试代码挂在我们怀疑的地方去调试。

例如:

计算层面

我们可以调查为何进程无法跑满、充分利用cpu,通过ebpf跟踪内核的调度器代码,我们可以发现cpu的调度队列上是否有堆积,发现利用cpu最多的热点函数上什么?

内存层面

我们可以跟踪系统内存分配事件,观察是否存在内存泄露、申请内存频次、触发缺页导致内存用量上升的热点函数

存储层面

我们可以跟踪各类io操作在文件系统和磁盘设备层面的细节行为,比如各类io操作频次、读写量的大小、发现耗时阻塞的io操作等等。

网络层面

我们可以跟踪一个网络数据包在整个内核协议栈中上怎么流动的,在哪里被修改,在哪里被丢弃,在哪里被发送等 

安全层面

我们看可以通过跟踪敏感系统函数,发现恶意的程序行为,记录下来审计,甚至阻止它

其他

几乎任何和内核相关的疑难问题都可以通过ebpf分析,比如执行权限问题,动态连接库问题,各种奇奇怪怪的模糊报错原因等。

也可以作为学习linux源码的工具

框架与工具

  • bcc:一个高性能的eBPF编译器集合,提供了丰富的API和工具,简化了eBPF程序的开发和使用。
  • bpftrace:一个类DTrace的工具,用于快速编写观察脚本。它依赖于较少的组件,一个二进制文件即可运行。
  • libbpf:用于用户态与内核eBPF API交互的核心库。

使用例子

使用bpftrace,例子在bpftrace的源码仓库。

我们使用ps命令查看系统上进程的运行情况,但是对于短时间内的启停的信息往往难以捕捉到,而ebpf是基于实际的调用触发的,因此任意一个目标事件我们都不会遗漏,同时我们还可以对结果进行过滤,查看特定进程启动子进程的情况,可以同时跟踪进程的结束函数,对每个进程的运行时间进行统计汇总等等。

综上所述,eBPF是一种强大的Linux内核技术,它允许开发人员在内核的安全环境中运行自定义代码,从而实现对系统的全面监控和调试。随着技术的不断发展,eBPF的应用场景将越来越广泛,为开发人员提供更多的可能性和便利。

posted on 2025-03-07 01:17  bdy  阅读(7)  评论(0)    收藏  举报  来源

导航