aquasecurity/libbpfgo
GitHub: aquasecurity/libbpfgo
libbpfgo 是基于 libbpf 的 Go 语言 eBPF 封装库,让 Go 开发者能够便捷地加载和管理 eBPF 程序及内核事件交互。
Stars: 845 | Forks: 100
# libbpfgo
[](https://github.com/aquasecurity/libbpfgo/releases)
[](https://goreportcard.com/report/github.com/aquasecurity/libbpfgo)
[](https://github.com/aquasecurity/libbpfgo/blob/main/LICENSE)
* [安装](#installing)
* [构建](#building)
* [概念](#concepts)
* [示例](#example)
* [发布](#releases)
* [了解更多](#learn-more)
libbpfgo 是一个用于 Linux [eBPF](https://ebpf.io/) 项目的 Go 库。它是为 [Tracee](https://github.com/aquasecurity/tracee) 创建的,Tracee 是我们使用 Go 编写的开源运行时安全和 eBPF 追踪工具。如果您对 eBPF 及其应用感兴趣,可以在 Github 上查看 Tracee:[https://github.com/aquasecurity/tracee](https://github.com/aquasecurity/tracee)。
libbpfgo 是基于 [libbpf](https://github.com/libbpf/libbpf) 构建的——这是一个用于从用户空间与 eBPF 程序交互的标准库——它是一个由 Linux 上游维护的 C 库。我们创建了 libbpfgo,将其作为 libbpf 项目的一个轻量级 Go 封装。
## 安装
libbpfgo 使用 CGO 与 libbpf 进行交互,并期望在运行或链接时与 libbpf 链接。仅仅导入 libbpfgo 不足以开始使用,您需要通过以下方式之一来满足所需的依赖项:
1. 在系统中将 libbpf 安装为共享对象。您的发行版可能已经打包了 libbpf,如果没有,您可以从源代码构建并安装。更多信息请访问[这里](https://github.com/libbpf/libbpf)。
2. 将 libbpf 作为 vendored 依赖项嵌入到您的 Go 项目中。这意味着 libbpf 代码将被静态链接到生成的二进制文件中,并且没有运行时依赖项。[Tracee](https://github.com/aquasecurity/tracee) 就采用了这种方法。
## 构建
目前您会发现以下 GNU Makefile 规则:
| Makefile 规则 | 描述 |
|--------------------------|-----------------------------------|
| all | 构建 libbpfgo(动态) |
| clean | 清理整个目录树 |
| selftest | 构建所有自测(静态) |
| selftest-run | 运行所有自测(静态) |
* 动态链接的 libbpf(来自操作系统的 libbpf)
| Makefile 规则 | 描述 |
|--------------------------|-----------------------------------|
| libbpfgo-dynamic | 构建动态 libbpfgo(libbpf) |
| libbpfgo-dynamic-test | 使用动态 libbpfgo 进行 'go test' |
| selftest-dynamic | 使用动态 libbpfgo 构建测试 |
| selftest-dynamic-run | 使用动态 libbpfgo 运行测试 |
* 静态编译(libbpf 子模块)
| Makefile 规则 | 描述 |
|--------------------------|-----------------------------------|
| libbpfgo-static | 构建静态 libbpfgo(libbpf) |
| libbpfgo-static-test | 使用静态 libbpfgo 进行 'go test' |
| selftest-static | 使用静态 libbpfgo 构建测试 |
| selftest-static-run | 使用静态 libbpfgo 运行测试 |
* 示例
```
$ make libbpfgo-static => libbpfgo statically linked with libbpf
$ make -C selftest/perfbuffers => single selftest build (static libbpf)
$ make -C selftest/perfbuffers run-dynamic => single selftest run (dynamic libbpf)
$ make selftest-static-run => will build & run all static selftests
```
## 概念
libbpfgo 试图通过抽象 C 的技术细节,让 Go 开发者能够自然地使用它。例如,它会将低级别的返回码转换为 Go 的 `error`,围绕 Go 的 `struct` 组织功能,并使用 `channel` 让您消费事件。
在较高级别上,这是使用该库的典型工作流程:
1. 将您的 bpf 程序编译为对象文件。
2. 初始化一个 `Module` 结构体——这是围绕您编译好的对象文件构建的 BPF 功能单元。
3. 使用 `BPFProg` 结构体从对象文件加载 bpf 程序。
4. 使用 `BPFProg` 的关联函数将 `BPFProg` 附加到系统设施,例如附加到“raw tracepoints”或“kprobes”。
5. 通过 `BPFMap` 结构体及其关联方法实例化和操作 BPF Maps。
6. 使用 `RingBuffer` 结构体及其关联对象,实例化和操作 Perf Buffer,用于将事件从您的 BPF 程序传递到驱动的用户空间程序。
## 示例
```
// initializing
import bpf "github.com/aquasecurity/libbpfgo"
...
bpfModule := bpf.NewModuleFromFile(bpfObjectPath)
bpfModule.BPFLoadObject()
// maps
mymap, _ := bpfModule.GetMap("mymap")
mymap.Update(key, value)
// ring buffer
rb, _ := bpfModule.InitRingBuffer("events", eventsChannel, buffSize)
rb.Poll(300)
e := <-eventsChannel
```
## 发布
libbpfgo 尚未制定定期发布的时间表。目前还没有进行过主要版本发布,但对于所有主要版本号相同的版本,我们将保持 API 的向后兼容性。在准备发布时会创建里程碑。
- __主要版本__ 会在破坏向后兼容性或完成重要里程碑(例如达到与 libbpf 的 API 同步)时发布。
- __次要版本__ 会结合对 libbpf API 的新支持进行发布。
- __修订版本__ 会结合重要的个别或一组错误修复进行发布。
- __libbpf 支持编号__ 表示为确保 libbpfgo 兼容性而必须链接的 _最低_ libbpf 版本。例如,`v0.2.1-libbpf-0.4.0` 表示 libbpfgo 的 0.2.1 版本需要 v0.4.0 或更新版本的 libbpf。
*注意*:某些发行版可能对其 libbpf 包进行了本地修改,其版本可能包含与上游版本不同的向后移植和/或修复。在这些情况下,我们建议以静态编译的方式使用 libbpfgo。
## 了解更多
请查看我们的 github 里程碑以了解项目路线图。总体目标是在 Go 中尽可能无缝地完整实现/公开 libbpf 的 API。
- [如何使用 libbpfgo 构建 eBPF 程序](https://blog.aquasec.com/libbpf-ebpf-programs)。
- [selftests](./selftest) 是使用 libbpfgo 的小型程序,可能是很好的使用示例。
- [tracee-ebpf](https://github.com/aquasecurity/tracee/tree/main/cmd/tracee-ebpf) 是本项目的一个稳健使用者。
- 欢迎通过创建新的[讨论](https://github.com/aquasecurity/libbpfgo/discussions)来提问,我们很乐意提供帮助。
[](https://github.com/aquasecurity/libbpfgo/releases)
[](https://goreportcard.com/report/github.com/aquasecurity/libbpfgo)
[](https://github.com/aquasecurity/libbpfgo/blob/main/LICENSE)
* [安装](#installing)
* [构建](#building)
* [概念](#concepts)
* [示例](#example)
* [发布](#releases)
* [了解更多](#learn-more)
libbpfgo 是一个用于 Linux [eBPF](https://ebpf.io/) 项目的 Go 库。它是为 [Tracee](https://github.com/aquasecurity/tracee) 创建的,Tracee 是我们使用 Go 编写的开源运行时安全和 eBPF 追踪工具。如果您对 eBPF 及其应用感兴趣,可以在 Github 上查看 Tracee:[https://github.com/aquasecurity/tracee](https://github.com/aquasecurity/tracee)。
libbpfgo 是基于 [libbpf](https://github.com/libbpf/libbpf) 构建的——这是一个用于从用户空间与 eBPF 程序交互的标准库——它是一个由 Linux 上游维护的 C 库。我们创建了 libbpfgo,将其作为 libbpf 项目的一个轻量级 Go 封装。
## 安装
libbpfgo 使用 CGO 与 libbpf 进行交互,并期望在运行或链接时与 libbpf 链接。仅仅导入 libbpfgo 不足以开始使用,您需要通过以下方式之一来满足所需的依赖项:
1. 在系统中将 libbpf 安装为共享对象。您的发行版可能已经打包了 libbpf,如果没有,您可以从源代码构建并安装。更多信息请访问[这里](https://github.com/libbpf/libbpf)。
2. 将 libbpf 作为 vendored 依赖项嵌入到您的 Go 项目中。这意味着 libbpf 代码将被静态链接到生成的二进制文件中,并且没有运行时依赖项。[Tracee](https://github.com/aquasecurity/tracee) 就采用了这种方法。
## 构建
目前您会发现以下 GNU Makefile 规则:
| Makefile 规则 | 描述 |
|--------------------------|-----------------------------------|
| all | 构建 libbpfgo(动态) |
| clean | 清理整个目录树 |
| selftest | 构建所有自测(静态) |
| selftest-run | 运行所有自测(静态) |
* 动态链接的 libbpf(来自操作系统的 libbpf)
| Makefile 规则 | 描述 |
|--------------------------|-----------------------------------|
| libbpfgo-dynamic | 构建动态 libbpfgo(libbpf) |
| libbpfgo-dynamic-test | 使用动态 libbpfgo 进行 'go test' |
| selftest-dynamic | 使用动态 libbpfgo 构建测试 |
| selftest-dynamic-run | 使用动态 libbpfgo 运行测试 |
* 静态编译(libbpf 子模块)
| Makefile 规则 | 描述 |
|--------------------------|-----------------------------------|
| libbpfgo-static | 构建静态 libbpfgo(libbpf) |
| libbpfgo-static-test | 使用静态 libbpfgo 进行 'go test' |
| selftest-static | 使用静态 libbpfgo 构建测试 |
| selftest-static-run | 使用静态 libbpfgo 运行测试 |
* 示例
```
$ make libbpfgo-static => libbpfgo statically linked with libbpf
$ make -C selftest/perfbuffers => single selftest build (static libbpf)
$ make -C selftest/perfbuffers run-dynamic => single selftest run (dynamic libbpf)
$ make selftest-static-run => will build & run all static selftests
```
## 概念
libbpfgo 试图通过抽象 C 的技术细节,让 Go 开发者能够自然地使用它。例如,它会将低级别的返回码转换为 Go 的 `error`,围绕 Go 的 `struct` 组织功能,并使用 `channel` 让您消费事件。
在较高级别上,这是使用该库的典型工作流程:
1. 将您的 bpf 程序编译为对象文件。
2. 初始化一个 `Module` 结构体——这是围绕您编译好的对象文件构建的 BPF 功能单元。
3. 使用 `BPFProg` 结构体从对象文件加载 bpf 程序。
4. 使用 `BPFProg` 的关联函数将 `BPFProg` 附加到系统设施,例如附加到“raw tracepoints”或“kprobes”。
5. 通过 `BPFMap` 结构体及其关联方法实例化和操作 BPF Maps。
6. 使用 `RingBuffer` 结构体及其关联对象,实例化和操作 Perf Buffer,用于将事件从您的 BPF 程序传递到驱动的用户空间程序。
## 示例
```
// initializing
import bpf "github.com/aquasecurity/libbpfgo"
...
bpfModule := bpf.NewModuleFromFile(bpfObjectPath)
bpfModule.BPFLoadObject()
// maps
mymap, _ := bpfModule.GetMap("mymap")
mymap.Update(key, value)
// ring buffer
rb, _ := bpfModule.InitRingBuffer("events", eventsChannel, buffSize)
rb.Poll(300)
e := <-eventsChannel
```
## 发布
libbpfgo 尚未制定定期发布的时间表。目前还没有进行过主要版本发布,但对于所有主要版本号相同的版本,我们将保持 API 的向后兼容性。在准备发布时会创建里程碑。
- __主要版本__ 会在破坏向后兼容性或完成重要里程碑(例如达到与 libbpf 的 API 同步)时发布。
- __次要版本__ 会结合对 libbpf API 的新支持进行发布。
- __修订版本__ 会结合重要的个别或一组错误修复进行发布。
- __libbpf 支持编号__ 表示为确保 libbpfgo 兼容性而必须链接的 _最低_ libbpf 版本。例如,`v0.2.1-libbpf-0.4.0` 表示 libbpfgo 的 0.2.1 版本需要 v0.4.0 或更新版本的 libbpf。
*注意*:某些发行版可能对其 libbpf 包进行了本地修改,其版本可能包含与上游版本不同的向后移植和/或修复。在这些情况下,我们建议以静态编译的方式使用 libbpfgo。
## 了解更多
请查看我们的 github 里程碑以了解项目路线图。总体目标是在 Go 中尽可能无缝地完整实现/公开 libbpf 的 API。
- [如何使用 libbpfgo 构建 eBPF 程序](https://blog.aquasec.com/libbpf-ebpf-programs)。
- [selftests](./selftest) 是使用 libbpfgo 的小型程序,可能是很好的使用示例。
- [tracee-ebpf](https://github.com/aquasecurity/tracee/tree/main/cmd/tracee-ebpf) 是本项目的一个稳健使用者。
- 欢迎通过创建新的[讨论](https://github.com/aquasecurity/libbpfgo/discussions)来提问,我们很乐意提供帮助。标签:CGO, Docker镜像, EVTX分析, Go语言, libbpf, 底层开发, 日志审计, 程序破解, 追踪