

libbpfgo 使用示例:搭建开发环境以及编写第一个 ebpf 程序
source link: https://mozillazg.com/2022/05/ebpf-libbpfgo-develop-env-and-hello-world.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

搭建开发环境¶
为了简单起见,我这里使用 vagrant 搭建虚拟机开发环境:
- 安装 vagrant-env 插件:
$ vagrant plugin install vagrant-env
- clone 示例代码仓库:
$ mkdir -p $GOPATH/src/github.com/mozillazg && \
cd $GOPATH/src/github.com/mozillazg && \
git clone https://github.com/mozillazg/hello-libbpfgo.git && \
cd hello-libbpfgo && \
git submodule update --init --recursive
- 配置 .env 文件(用于将本机的 GOPATH 挂载到虚拟机中):
# 修改 .env 文件,将 GOPATH 的值修改为本机对应的路径
$ cp .env.example .env
- 启动虚拟机:
$ vagrant up
- 等虚拟机就位后,进入虚拟机:
$ vagrant ssh
编写示例程序¶
这里使用 hello-libbpfgo 中 01-hello-world 目录下的示例程序为例简单介绍一下示例程序。
main.ebpf.c:
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
SEC("kprobe/do_sys_openat2")
int kprobe__do_sys_openat2(struct pt_regs *ctx)
{
char file_name[256];
bpf_probe_read(file_name, sizeof(file_name), PT_REGS_PARM2(ctx));
char fmt[] = "open file %s\n";
bpf_trace_printk(fmt, sizeof(fmt), &file_name);
return 0;
}
main.ebpf.c 这个程序比较简单,就是hook do_sys_openat2 这个内核函数的调用, 将函数调用参数中的 filename 信息给记录下来。
主要看一下,怎么在 go 程序中使用 libbpfgo 调用这个 ebpf 程序:
main.go:
package main
import (
"fmt"
"time"
bpf "github.com/aquasecurity/libbpfgo"
)
func main() {
bpfModule, err := bpf.NewModuleFromFile("main.bpf.o")
if err != nil {
panic(err)
}
defer bpfModule.Close()
if err := bpfModule.BPFLoadObject(); err != nil {
panic(err)
}
prog, err := bpfModule.GetProgram("kprobe__do_sys_openat2")
if err != nil {
panic(err)
}
if _, err := prog.AttachKprobe("do_sys_openat2"); err != nil {
panic(err)
}
for {
fmt.Println("Waiting...")
time.Sleep(10 * time.Second)
}
}
从上面的 go 程序中可以看到,使用 libbpfgo 调用 ebpf 程序主要有四个步骤:
- 通过 bpf.NewModuleFromFile 方法读取编译好的 .o 文件
- 使用 bpfModule.BPFLoadObject() 加载读取的 .o 文件中对象信息
- 使用 bpfModule.GetProgram 获取 ebpf 程序中对应的 hook 函数
- 如果这个函数是个 kprobe hook 函数,那么就调用 prog.AttachKprobe 把它 attach 到对应的内核函数hook中。
下面编译程序然后看一下对应的效果:
$ vagrant ssh
$ cd $GOPATH/src/github.com/mozillazg/hello-libbpfgo/01-hello-world && \
make
$ sudo ./main-static
另开一个终端,查看 ebpf 中打印的信息:
$ vagrant ssh
$ sudo cat /sys/kernel/debug/tracing/trace_pipe
runc:[2:INIT]-100616 [000] d... 5527.233315: bpf_trace_printk: open file /proc/self/fd
runc:[2:INIT]-100616 [000] d... 5527.233641: bpf_trace_printk: open file /proc/self/status
runc:[2:INIT]-100616 [000] d... 5527.233802: bpf_trace_printk: open file /etc/passwd
runc:[2:INIT]-100616 [000] d... 5527.233829: bpf_trace_printk: open file /etc/group
更多信息,详见 https://github.com/mozillazg/hello-libbpfgo/tree/master/01-hello-world
Recommend
-
13
Angular入门,开发环境搭建,使用Angular CLI创建你的第一个Angular项目 ...
-
7
使用 CLion 搭建 istio-proxy (envoy) 开发环境 本文介绍如何使用 CLion 来阅读和开发 istio-proxy (envoy) 的代码。 Envoy
-
5
前言¶ gobpf 使用示例系列记录使用 gobpf 编写 eBPF 程序的一些例子。
-
6
SSM整合_年轻人的第一个增删改查_基础环境搭建 - 蔚然丶丶 - 博客园 SSM整合_年轻人的第一个增删改查_基础环境搭建 ...
-
37
前言¶ 本文简单记录一下如何编写一个使用 ringbuf map 传递数据的 ebpf 程序,...
-
10
前言¶ 大多数基于 ebpf 技术的程序都有需要在 ebpf 程序中获取相应事件发生时...
-
27
前言¶ 本文简单记录一下如何编写一个使用 perfbuf map 传递数据的 ebpf 程序,...
-
8
前言¶ 记录一下如何在 libbpfgo 程序中使用 ebpf map(ebpf map 本身的资料可以...
-
6
1.1 Python是什么 Python的创始人为吉多·范罗苏姆。1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承。之所以选中Python作为程序的名字,是因为他是BBC电视剧——蒙提...
-
6
最近新开源了一个 eBPF 相关的项目: mozillazg/libbpfgo-tools 。 这个项目的目标是使用 libbpfgo 重写/移植...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK