Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
gobee — BPFプログラムをCではなくGoで書きましょう。gobeeはGoのサブセットをBPF Cにトランスパイルし、型付きcilium/ebpfバインディングを生成します。 | Kitploit
ツール/GitHubGitHub/boratanrikulu/gobee
静的分析コード分析スクリプトと自動化DevSecOpsユーティリティとフレームワークバイナリ解析
GitHubboratanrikulu/gobee

gobee

BPFプログラムをCではなくGoで書きましょう。gobeeはGoのサブセットをBPF Cにトランスパイルし、型付きcilium/ebpfバインディングを生成します。

リポジトリを見る
345414ヶ月前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

gobee

BPFプログラムをCではなくGoで書きましょう。 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 は両方のファイルに加えて、verifierエラーをGoの行にマッピングするためのソースマップ(events.bpf.c.map)と、型付きバインディングファイル(bpf/events_bindings.go)を生成します。これによりユーザー空間ドライバは、文字列で型付けされたcoll.Programs["..."]ルックアップの代わりに、objs.Events、objs.AttachOnExec()と書き、ringbufペイロードを直接bpf.Event(上で見たのと同じ構造体がGoでも再公開されたもの)にデコードできます。

Cコードは意図的に読みやすくしています。gobeeが変なものを出力したら、それを目で確認できます。tracepoint + kprobe + XDPを1つのバイナリにまとめる方法は、example/sysmon/を参照してください。

比較

gobeeC + clang + bpf2goAya (Rust)bpftraceBCC
カーネル側言語GoサブセットCRustDSLC
ユーザー空間統合型付きGoバインディング + cilium/ebpfbpf2goaya-runtimeなしpython
CO-RE✅ clang経由✅✅ LLVM経由✅✅
ヘルパー網羅性200の型付きGoラッパーフル(Cで記述)フル限定フル(Cで記述)
Verifierエラー → ソース✅ Go file:line:col❌ 生のC✅ Rust file:line❌部分的
ロード時のカーネルバージョンゲート✅ bpfvet経由手動手動該当なしランタイム
ツールチェーン依存Go + clangclang + bpf2gorustc + LLVMbpftracepython + bcc
生成成果物.bpf.o + Goバイナリ.bpf.o + Goバイナリ.bpf.o + RustバイナリJITJIT

すでにC / libbpfのワークフローを使っている場合、gobeeはそれを丸ごと置き換えようとするものではありません。カーネル側、ユーザー空間側、ビルドパイプラインをすべて1つのGoモジュールにまとめたい場合のためのものです。

現在サポートされているもの

完全なマトリクス(Goサブセット、文、式、すべてのヘルパー、すべてのマップ型、すべてのディレクティブ)はdocs/status.mdを参照してください。早見:

対象対応状況
プログラムタイプ (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 ストレージ、devmap/cpumap/xskmap
BPFヘルパーlibbpf v1.5.0ヘッダーから自動生成された約200の型付きGoスタブ。example/helloworld/とexample/sysmon/で使用されているものは実カーネルCIでテスト済みですが、残りは未検証です。スタブがカーネルのシグネチャと一致しない場合はissueを報告してください
CO-RE✅ 自動検出。カーネル内部の構造体フィールドにはBPF_CORE_READ(task_struct、sock、inode)。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 -gからclangが生成するBTFには正しいリロケーションが含まれます。clang自体の実行はあなたの責任です(サンプルのMakefileに標準的な呼び出し方が示されています)
ユーザー定義ヘルパー✅ //bpf:sectionを持たないトップレベルGo関数は、static __always_inline C関数として出力されます
型付きGoバインディング✅ Load<Stem>、Close、プログラムごとのAttach<Name>、AttachAllに加え、カーネル側の構造体型と定数がGoで再公開されます
カーネルバージョンゲート✅ ロード時にbpfvetが実行されます。不透明なEINVALの代わりに、bpf program needs kernel >= 5.8, host is 5.4というメッセージで即座に失敗します
Verifierエラー → Goソース✅ Load<Stem>内で自動的に注釈付けされます。gobee diagnoseへの手動パイプは不要で、にマーカーが付いて返ってきます

gobeeが行うこと

  • GoサブセットをBPF Cにトランスパイルします(入力に対して先にgo/typesを実行するため、誤用はfile:line:colで表面化します)。
  • .bpf.cの隣に型付き<Stem>_bindings.goを生成します: 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、verifierフレンドリーなコード生成を無償で提供します。それを再実装するのは数年かかるだけで、得るものは何もありません。
  • cilium/ebpfを置き換えること。 生成されるバインディングはその上に成り立っています。
  • BPFを隠すこと。 GoサブセットはBPF Cのイディオムと1:1で対応します。BPFを知っているなら、gobeeは薄い糖衣です。知らなければ、マニュアルは依然として必読です。
  • clangを実行すること。 コンパイル、埋め込み、ロードはユーザーが所有します。bpf2goと同じパターンです。

なぜ直接BPFを生成せずトランスパイルするのか

gc(Goコンパイラ)には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 package, importable from anywhere in your project
│   ├── embed_amd64.go        # //go:embed bin/x86/your.bpf.o
│   ├── embed_arm64.go
│   ├── your_bindings.go      # generated by gobee
│   ├── bin/{x86,arm64}/your.bpf.o
│   └── src/                  # not a Go package; clang lives here
│       ├── your.go           # //go:build ignore: BPF source
│       ├── your.bpf.c        # generated
│       ├── Makefile          # clang per arch
│       └── vmlinux.h         # vendored BTF dump
├── main.go                   # imports yourproject/bpf
└── Makefile

この分割により、bpf/はクリーンでインポート可能なGoパッケージとして保たれます(Goは非cgoパッケージ内の.cファイルを拒否します)。カーネルソースとclangの生成物は、1階層下のbpf/src/に置かれます。

例

  • example/helloworld/: 標準的なXDPパケットカウンタです。BPFは約40行、ユーザー空間は約80行です。
  • example/sysmon/: XDP、2つのtracepoint、1つのkprobeを1つのバイナリにまとめ、イベント用のringbufを共有します。システムコールごとの型付きコンテキスト、ユーザー定義ヘルパー関数、AttachAllショートカットを示しています。

CI

GitHub Actionsはプッシュのたびに4つのレイヤーを実行します:

  1. go test、go vet、トランスパイラのゴールデンテスト
  2. カバレッジマトリクス: すべてのマップ型と//bpf:sectionの種類について、少なくとも1つの例があること
  3. 精選された各サンプルのclangコンパイルと、その後のbpfvet移植性レポート
  4. 実カーネルでのverifier受け入れテスト: 各.bpf.oに対するebpf.NewCollectionWithOptions(Ubuntu 24.04ランナー、カーネル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 VM内でビルドしてください。
  • 生成物の実行にはarm64またはamd64のLinuxが必要です。

インスピレーション

  • Solod: このパターンが機能することを実証したGo-to-Cトランスパイラ。
  • Aya: gobeeが追い求める使い勝手を備えたRust eBPFフレームワーク。

ライセンス

MIT。 LICENSEを参照してください。

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

ツールをダウンロード
*ebpf.VerifierError
→ counter.go:18:5
ソースマップサイドカー✅ すべての.bpf.cの横に<stem>.bpf.c.mapが書き出されます。オフラインのgobee diagnose利用にも対応します
クロスアーキテクチャ✅ Linux arm64 + amd64