eBPF 系列(一) 初识eBPF
什么是BPF,什么是eBPF ?
BPF全称是 Berkeley Packet Filter。使内核可以运行用户程序,不需要重新编译内核,而且os运行时动态加载到内核中。 eBPF 是 linux kernel 提供了一种扩展版本的BPF过滤系统,叫做 eBPF ( expand Berkeley Packet Filter ) 。
eBPF 允许在 linux 操作系统的内核态运行 sandbox 程序,用于实施观测或者修改内核进程。该功能在 linuex kernel 3.17 版本作为特性引入,扩充了现有的 BPF 功能,新增了指令集、提供 C 代码即时编译工具 JIT 和验证器 Verifier、提供 MAP 映射机制等能力,在原有 BPF 的基础上显著增强了安全性、性能、易用性。简单来说,用户可以通过 eBPF 在用户态编写程序在内核态的 hook 点进行运行,从而观测或者改变内核的行为,由于 eBPF 严格的程序校验器 Verifier 保证了程序可以安全的在内核态运行。
eBPF 有哪些使用场景 ( User Story ) ?
- Cillium 是 kubernetes 的 CNI 网络插件,它使用了基于 eBPF 技术的容器网络解决方案替代了类似 kube-proxy 组件所使用的 iptables 或者 ipvs 模式,使用 eBPF 程序来控制容器网络中数据包的转发行为,相对基于规则的 linux 网络路由转发功能,极大的提升了 service-mesh 的网络性能, 同时 Hubble 使用 cillium 组件中 eBPF 所观测到的网络数据来进行 kuernetes 网络可视化。
- 基于 XDP 的网络性能优化 由于 eBPF 程序具有改变内核数据的行为,因此从 linux kernel 4.8 开始合入了一种基于 eBPF 的高性能数据转发路径的特性—— XDP ( eXpress Data Path ) 用于绕过 linux 操作系统网络协议栈而直接进行包的处理、发送和接收,从而提高数据包处理性能。
- 网易轻舟的 eBPF 实践,使用 eBPF 设计了整个 kubernetes 的监控子系统具有 1.平台与内核无关 2. 对内核组件的任意监控 3. 对 pid / container / pod 级别的细粒度监控 3. 支持监控项在线升级和性能报警。同时网易轻舟内部的 sockops 组件使用 eBPF 绕过协议栈匹配加速进程通信。
- 使用 eBPF 的下一代边缘防火墙 bpfilter ,由于 iptables / netfilter 已知的策略匹配问题,使用 eBPF 来处理和过滤数据包可以降低 CPU 的资源消耗,在应用层有更自定义化的网络策略,可以抵抗以协议栈为目的的 DDoS 攻击,因此需要厂商在防火墙演进上都出现了基于 eBPF 的实践。
- 在 2022 BlackHat 大会上提出了基于 eBPF 的内核运行时完整性检测工具 KRIe ,通过放置 BPF_PROG_TYPE_KRPOBE 在关键调用内存上检测 栈指针 等修改从而放置 ROP 攻击,通过使用 eBPF 中的 kprobe 模式检测 hook points 和内核参数,并对控制流跳转点进行保护实现 CFI 功能。
eBPF 程序的运行原理
由于 eBPF 是 BPF 功能扩展特性,因此一个 eBPF 程序和 BPF 程序有相同的处理流程,这里以 BPF 程序从编写到执行的流程举例。
BPF 的运行流程图如下,通过在用户态使用 eBPF 开发 SDK 或者 C 语言通过编写 bpf 程序使用 llvm / Clang 进行编译成 bpf 伪字节码, 通过 bpf_loader 将 bpf 伪字节码加载到内核中交给 Verifier 验证器(用于验证内核空间的 bpf 程序是否安全可靠)和BPF JIT 编译器(编译过程将伪字节码或者也被叫做通用字节码转换成机器能够执行的本地机器码),最后对接 BPF 内置的 kernel hook 从完成对内核钩子的挂载。
eBPF 内核 Hook 点全景
由于 eBPF 本身是基于事件驱动的,通过在预制的内核或者应用中触发 hook 点来运行。目前预定义的 Hook 点包含 system calls / function entry 或者exit / kernel tracepoints / network events 等,编写 eBPF 程序时可以通过在预定义的 Hook 点处设置触发并且编写控制流程,以系统调用举例如下:
这里通过对预定义的系统调用进行注册,当收到对应 Hook 点的事件时就触发对应的动作,从而完成基本的控制或者监控流程。
当预定义的 Hook 点不存在时,可以使用 kernel probe (kprobe) 或者 user probe (uprobe) 去关联 eBPF 程序从实现对应位置的流程监控和控制。ebpf 官方给出的可能的 Hook 点全景图如下:
可以看到 eBPF 几乎可以在程序的任何位置进行 Hook,包括但不限于 kernel functions (kprobes)、userspace functions (uprobes)、 system calls、fentry/fexit、Tracepoints、network devices (tc/xdp)、network routes、sockets等
eBPF 学习及参考地图 (持续更新)
资源链接地图
- bcc 仓库文档 https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md
- openEuler 代码仓库 https://gitee.com/src-openeuler/kernel/blob/4dd59f4b704618cd501eba6ed33926d6270f3f3b/kernel.spec?skip_mobile=true
- cilium ebpf 仓库 https://github.com/cilium/ebpf
- libbpf 代码仓库 https://github.com/libbpf
- libbpf 初学者指南 https://www.containiq.com/post/libbpf
- bcc 介绍 https://lwn.net/Articles/742082/
- Runtime Checking for C Program with bpf https://www.doc.ic.ac.uk/~afd/rarepapers/KendallBccRuntimeCheckingsforC.pdf
- 从头开始开发一个 eBPF 程序 https://tonybai.com/2022/07/05/develop-hello-world-ebpf-program-in-c-from-scratch/
- linux source code 仓库 https://elixir.bootlin.com/linux/v4.18.1/source/include/linux/compiler.h
- 使用eBPF 调试 GO 程序 http://kerneltravel.net/blog/2020/debug-go-using-bpf/
- kprobe document https://docs.kernel.org/trace/kprobes.html
- ebpf blog https://hackmd.io/@YLowy/rJnNMaAY5
- ebpf 官方文档索引 https://ebpf.io/what-is-ebpf/
- krie https://i.blackhat.com/USA-22/Wednesday/US-22-Fournier-Return-To-Sender.pdf
- CFI with eBPF http://vger.kernel.org/lpc_bpf2018_talks/bounded-loops.pdf
- a new firewall with ebpf https://github.com/harporoeder/ebpfsnitch
- llvm https://llvm.org/
Reference
[1] https://ebpf.io/
[2] Linux Observability with BPF
[3] ebpf 官方文档索引 https://ebpf.io/what-is-ebpf/
Member discussion