Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
gobee — 用 Go 而非 C 编写你的 BPF 程序。gobee 将 Go 子集转译为 BPF C,并生成类型化的 cilium/ebpf 绑定。 | Kitploit
工具/GitHubGitHub/boratanrikulu/gobee
静态分析代码分析脚本与自动化DevSecOps实用工具与框架二进制分析
GitHubboratanrikulu/gobee

gobee

用 Go 而非 C 编写你的 BPF 程序。gobee 将 Go 子集转译为 BPF C,并生成类型化的 cilium/ebpf 绑定。

查看仓库
345414个月前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

gobee

用Go编写BPF程序,而不是C。 gobee将Go的一个严格子集转译成BPF C,为用户空间生成类型化的Go绑定,并根据正在运行的内核进行加载校验。

Go生态系统拥有可靠的BPF用户空间工具。而内核端总是以"现在用C编写你的程序"结束。Aya通过在rustc中编写一个新的BPF后端,将eBPF带到了Rust。gobee以另一种方式实现:通过转译成C并复用clang成熟的后端。

输入Go文件,输出BPF程序

一个通过ringbuf将每次execve流式传输到用户空间的tracepoint:

你的输入(Go)gobee生成的(BPF C)
root@kitploit:~
//go:build ignore

package main

import "github.com/boratanrikulu/gobee/bpf"

//bpf:license GPL

type Event struct {
    Pid  uint32
    Comm [16]byte
}

var Events = bpf.RingBuf[Event]{
    MaxEntries: 4096,
}

//bpf:section tracepoint/syscalls/sys_enter_execve
func OnExec(ctx *bpf.ExecveEnterCtx) bpf.TpReturn {
    e, ok := Events.Reserve()
    if !ok {
        return bpf.TpOk
    }
    e.Pid = bpf.GetCurrentPid()
    bpf.GetTaskComm(&e.Comm)
    Events.Submit(e)
    return bpf.TpOk
}

func main() {}
root@kitploit:~
// Code generated by gobee. DO NOT EDIT.

#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>

char _license[] SEC("license") = "GPL";

struct Event {
    __u32 Pid;
    __u8 Comm[16];
};

struct {
    __uint(type, BPF_MAP_TYPE_RINGBUF);
    __uint(max_entries, 4096);
} Events SEC(".maps");

SEC("tracepoint/syscalls/sys_enter_execve")
int OnExec(struct trace_event_raw_sys_enter *ctx) {
    struct Event *e = bpf_ringbuf_reserve(
        &Events, sizeof(struct Event), 0);
    if (!e) {
        return 0;
    }
    e->Pid = (__u32)(
        bpf_get_current_pid_tgid() >> 32);
    bpf_get_current_comm(&e->Comm, 16);
    bpf_ringbuf_submit(e, 0);
    return 0;
}

gobee translate --bindings-dir ./bpf ./bpf/src 生成这两个文件,外加一个源代码映射(events.bpf.c.map),使得验证器错误能映射回Go代码行,以及一个类型化的绑定文件(bpf/events_bindings.go),这样用户空间驱动可以写 objs.Events、objs.AttachOnExec(),并直接从ringbuf负载解码为 bpf.Event(与你上面看到的相同结构体,重新发布到Go中),而不是字符串类型的coll.Programs["..."] 查找。

C代码是有意保持可读的。如果gobee生成了奇怪的东西,你可以看到它。关于将tracepoints、kprobes和XDP组合成一个二进制文件的示例,请参见 example/sysmon/。

对比

如果你已经在使用C / libbpf工作流,gobee并不是要完全取代它。它适用于那些希望内核端、用户空间端和构建流水线都放在一个Go模块中的场景。

当前支持的功能

查看 docs/status.md 了解完整矩阵(Go子集、语句、表达式、每个辅助函数、每个映射类型、每个指令)。快速概览:

gobee的功能

  • 将Go子集转译为BPF C(并首先对你的输入运行go/types检查,这样误用在file:line:col处就会暴露)。
  • 生成一个类型化的<Stem>_bindings.go,放在.bpf.c旁边:bpf.LoadCounter(spec)、objs.PerIface.Lookup(...)、objs.AttachAll(ifindex),以及你的内核端结构体类型和常量重新发布到Go中。
  • 自动注释来自LoadAndAssign的*ebpf.VerifierError,包含Go源代码位置,无需手动gobee diagnose管道。
  • 在Load<Stem>内部运行bpfvet,使旧内核以bpf program needs kernel >= 5.8, host is 5.4快速失败。
  • 为libbpf v1.5.0辅助函数集提供约200个类型化Go桩,以及用户定义的辅助函数(生成static __always_inline)。

gobee不会做的事情

  • 不替代clang。 clang的BPF后端为我们免费提供了CO-RE、BTF和验证器友好的代码生成。重新实现它需要数年时间且没有收益。
  • 不替代cilium/ebpf。 生成的绑定构建在其之上。
  • 不隐藏BPF。 Go子集与BPF C惯用法一一映射。如果你了解BPF,gobee是一层薄糖。如果你不了解,文档仍然是必读的。
  • 不为你运行clang。 编译、嵌入和加载仍然是用户的责任。与bpf2go模式相同。

为什么选择转译而不是直接生成BPF

Go编译器gc没有基于LLVM的BPF后端。添加一个是一个多年的编译器项目。rustc构建在LLVM之上,这就是Aya能工作的原因。因此gobee生成C并复用clang的BPF后端,这为我们免费提供了成熟的代码生成、BTF和CO-RE重定位。

快速开始

root@kitploit:~
go install github.com/boratanrikulu/gobee/cmd/gobee@latest

cd example/helloworld
make build                     # gobee translate, clang, go build
sudo ./helloworld eth0

你需要具有BPF目标的clang。在Linux上,这是发行版包;在macOS上,brew install llvm。转译器本身是纯Go的,可以运行在任何地方。

项目布局(典型)

root@kitploit:~
yourproject/
├── bpf/                      # Go包,可从项目任何位置导入
│   ├── embed_amd64.go        # //go:embed bin/x86/your.bpf.o
│   ├── embed_arm64.go
│   ├── your_bindings.go      # 由gobee生成
│   ├── bin/{x86,arm64}/your.bpf.o
│   └── src/                  # 不是Go包;clang在这里
│       ├── your.go           # //go:build ignore: BPF源代码
│       ├── your.bpf.c        # 生成的文件
│       ├── Makefile          # 按架构的clang命令
│       └── vmlinux.h         # 供应商BTF转储
├── main.go                   # 导入 yourproject/bpf
└── Makefile

这种分离使bpf/成为一个干净的、可导入的Go包(Go拒绝在非cgo包中的.c文件)。内核源代码和clang产物位于bpf/src/下一层。

示例

  • example/helloworld/:经典的XDP数据包计数器,约40行BPF,约80行用户空间。
  • example/sysmon/:XDP、两个tracepoint和一个kprobe在同一个二进制文件中,共享一个ringbuf用于事件。演示了每个系统调用的类型化上下文、用户定义的辅助函数以及AttachAll快捷方式。

CI

GitHub Actions 在每次推送时运行四层:

  1. go test、go vet、转译器快照测试
  2. 覆盖矩阵:每种映射类型和//bpf:section种类至少有一个示例
  3. 对每个精选示例进行clang编译,然后bpfvet可移植性报告
  4. 真实内核验证器接受测试:在每个.bpf.o上运行ebpf.NewCollectionWithOptions(Ubuntu 24.04 runner,内核6.x)

文档

  • docs/design.md:架构和原理
  • docs/go-subset.md:BPF源文件中接受的Go语法
  • docs/directives.md://bpf:*参考
  • docs/status.md:支持矩阵(唯一真实信息源)

工具链

  • gobee二进制文件可以在任何地方构建(纯Go,无需CGO)。
  • 编译.bpf.o需要具有BPF目标的clang。Apple自带的clang不包含该目标;在macOS上使用brew install llvm或在Linux虚拟机内构建。
  • 运行产物需要Linux arm64或amd64。

灵感来源

  • Solod:证明这种模式可行的Go到C转译器。
  • Aya:Rust eBPF框架,其易用性是gobee追求的目标。

许可证

MIT。参见 LICENSE。

Copyright (c) 2026 Bora Tanrikulu <[email protected]>

下载工具
gobeeC + clang + bpf2goAya (Rust)bpftraceBCC
内核端语言Go子集CRustDSLC
用户空间集成类型化Go绑定 + cilium/ebpfbpf2goaya-runtime无python
CO-RE✅ 通过clang✅✅ 通过LLVM✅✅
辅助函数覆盖200个类型化Go包装器完整(写C)完整有限完整(写C)
验证器错误 → 源✅ Go文件:行:列❌ 原始C✅ Rust文件:行❌部分
加载时内核版本门控✅ 通过bpfvet手动手动不适用运行时
工具链依赖Go + clangclang + bpf2gorustc + LLVMbpftracepython + bcc
生成产物.bpf.o + Go二进制.bpf.o + Go二进制.bpf.o + Rust二进制JITJIT
功能面覆盖情况
程序类型(8种)XDP, tracepoint, kprobe / kretprobe, uprobe / uretprobe, sock_ops, TC, cgroup_skb, LSM
映射类型(19种)array, hash, lru_hash, per-CPU变体, bloom_filter, lpm_trie, ringbuf, perf_event_array, prog_array, queue, stack, sk/task/inode storage, devmap/cpumap/xskmap
BPF辅助函数从libbpf v1.5.0头文件自动生成约200个类型化Go桩。由example/helloworld/和example/sysmon/练习的桩已在真实内核CI中测试;其余未验证。如果某个桩与内核签名不匹配,请提交issue
CO-RE✅ 自动检测。对内核内部结构体字段(task_struct, sock, inode)使用BPF_CORE_READ;对UAPI BPF上下文结构体(xdp_md, __sk_buff, bpf_sock_ops)使用直接的ctx->field。在Linux 6.x(Ubuntu 24.04 CI)上经过测试;较老的内核尚未纳入CI矩阵
BTF就绪输出✅ 生成的C包含vmlinux.h,并对内核内部字段读取使用BPF_CORE_READ,因此clang通过clang -g生成的BTF携带正确的重定位。clang本身仍由你负责(示例Makefile展示了规范调用)
用户定义辅助函数✅ 没有//bpf:section的顶层Go函数被生成为static __always_inline C函数
类型化Go绑定✅ Load<Stem>, Close, 每个程序的 Attach<Name>, AttachAll,以及你的内核端结构体类型和常量重新发布到Go中
内核版本门控✅ bpfvet 在加载时运行。以明确的bpf program needs kernel >= 5.8, host is 5.4快速失败,而不是模糊的EINVAL
验证器错误 → Go源代码✅ 自动注释在Load<Stem>内部。无需手动管道到gobee diagnose;*ebpf.VerifierError返回带有→ counter.go:18:5标记的错误
源代码映射侧车✅ 每个.bpf.c旁边生成<stem>.bpf.c.map,也用于离线gobee diagnose
跨架构✅ Linux arm64 + amd64