【龙蜥社区&浪潮信息】2023年eBPF技术实践白皮书

—eBPF是一项起源于Linux内核的革命性技术,可以在特权上下文中(如操作系统内核)运行沙盒程序。它可以安全有效地扩展内核的功能,并且不需要更改内核源代码或加载内核模块。


—内核因具有监督和控制整个系统的特权,一直是实现可观察性、安全性和网络功能的理想场所。同时,由于对稳定性和安全性的高要求,内核发展相对缓慢,与内核之外实现的功能相比,创新速度较慢。


—eBPF从根本上改变了上述情况,它允许在内核中运行沙箱程序,即通过运行eBPF程序向正在运行中的操作系统添加额外的功能,并通过验证引擎和即时编译器保证安全性和执行效率,由此衍生出了一系列的产品和项目,涉及下一代网络、可观察性和安全技术。


—如今,eBPF在多种应用场景中起到重要作用:在现代数据中心和云原生环境中提供高性能网络和负载均衡,以低开销提取细粒度的安全可观察性数据,帮助应用程序开发人员跟踪应用程序的运行状态,高效进行性能故障定位,保证应用程序和容器运行时安全等。


—eBPF引领的创新才刚刚开始,一切皆有可能。


A.eBPF架构


eBPF包括用户空间程序和内核程序两部分,用户空间程序负责加载BPF字节码至内核,内核中的BPF程序负责在内核中执行特定事件,用户空间程序与内核BPF程序可以使用map结构实现双向通信,这为内核中运行的BPF程序提供了更加灵活的控制。eBPF的工作逻辑如下:


1、eBPFProgram通过LLVM/Clang编译成eBPF定义的字节码。


2、通过系统调用bpf()将字节码指令传入内核中。


3、由Verifier检验字节码的安全性、合规性。


4、在确认字节码程序的安全性后,JITCompiler会将其转换成可以在当前系统运行的机器码。


5、根据程序类型的不同,把可运行机器码挂载到内核不同的位置/HOOK点。


6、等待触发执行,其中不同的程序类型、不同的HOOK点的触发时机是不相同的;并且在eBPF程序运行过程中,用户空间可通过eBPFmap与内核进行双向通信。


B.eBPF加载过程


1、字节码读取


通常eBPF字节码文件都是ELF格式,各section中保存着字节码所有的信息,包括字节码指令、map定义、BTF信息,以及需要重定位的变量和函数等;eBPF加载时,依照ELF格式读取字节码文件,把各种信息按照一定的格式保存起来。


2、重定位


重定位是指在编译、加载的过程中把字节码中一些临时数据以更准确的信息进行替换,比如用map句柄替换map索引,用map地址替换map句柄。经过多轮重定位,可以确保eBPF程序在内核中运行所需数据的正确性和完整性。需要重定位的对象有:map、函数调用、Helper函数调用、字段、Extern内核符号和kconfig。


3、Verifier


Verifier是一个静态代码安全检查器,用于检查eBPF程序的安全性,保证eBPF程序不会破坏内核,影响内核的稳定性。


C.挂载与执行


1)eBPF在内核提供了大量的挂载点,算上kprobe挂载点,几乎可以在内核代码的任意函数挂载一段eBPF程序。不同eBPF程序类型的挂载点各不相同,挂载点是根据设计与需求提前在内核指定位置通过提前嵌入代码实现的,初始时函数指针是空,挂载eBPF程序后,对指针赋值,指向eBPF内核程序。


2)为了安全性,挂载eBPF程序需要root权限或CAP_BPFcapability,不过目前也有设计允许非root权限帐号载入eBPF程序,比如将kernel.unprivileged_bpf_disabledsysctl设置为false的情况下,非root帐号能够使用bpf()系统调用。


3)eBPF内核程序基于事件触发,当内核执行到对应的挂载点时就会执行挂载在此处的eBPF程序。eBPF执行过程中会用到一个很重要的数据结构map,map的主要功能是用来实现BPF程序执行过程中用户空间程序与内核BPF程序之间的双向通信,这也为内核中运行的BPF程序提供了更加灵活的控制。

【龙蜥社区&浪潮信息】2023年eBPF技术实践白皮书
上一篇

【德勤】逐浪数字经济合规新世界:中国企业出海发展建议白皮书2023版

2023-11-21
下一篇

2023光刻机产业发展简析报告

2023-11-23