
bcc/bpftraceで書く、初めてのeBPFプログラム|Hello, Kernel World!
日々のシステム運用業務において、「もっと手軽に、そして深くシステムの動きを把握したい」と感じることはありませんか?
カーネルの再コンパイルやモジュールのロードといった煩雑な手順なしに、システムの挙動をリアルタイムで観測し、分析できたら、運用はどれだけ効率的になるでしょうか。
この記事では、そのような課題を解決する革新的な技術「eBPF」について、実際に手を動かしながら学べるチュートリアルをご紹介します!
この記事を読み終える頃には、eBPFの強力なフロントエンドであるbcc
とbpftrace
を使いこなし、「特定のファイルが開かれたことを通知する」「新しいプロセスが生成された瞬間を捉える」といった、実践的なプログラムを自分の手で書けるようになるはずです。ぜひご覧下さい!
eBPFとは
eBPF(extended Berkeley Packet Filter)とは、Linuxカーネル内でサンドボックス化されたプログラムを実行可能にする技術です。
これにより、OSのコア部分に手を加えることなく、ネットワーキング、セキュリティ、そしてオブザーバビリティ(可観測性)を飛躍的に向上させることができます。
eBPFの心強い味方、bccとbpftrace!
eBPFのプログラムは本来、特定のバイトコードで記述する必要があり、習得には相当な労力を要します。
しかし、bcc
やbpftrace
といった高レベルなフレームワークの登場により、私たちはもっと身近な言語でeBPFの力を引き出すことができるようになりました。
このチュートリアルでは、これら2つのツールを使い、それぞれの特徴を活かしたeBPFプログラムを作成していきます。
【ハンズオン1】bccとPythonで新規プロセス生成をトレースする
最初のステップとして、
のPythonラッパーを使い、システム上で新しいプロセスが生成されるたびにその情報を出力するプログラムを作成してみましょう。bcc
これは、意図しないプロセスの起動を監視するなど、セキュリティやリソース管理の第一歩となる実践的な例です。
環境準備
まず、
をインストールする必要があります。bcc
bcc
のGitHubリポジトリには、各種ディストリビューション向けの詳細なインストール手順が記載されています。
Ubuntuを例にとると、以下のコマンドで必要なパッケージを導入できます。
bash
sudo apt-get update
sudo apt-get install -y bpfcc-tools linux-headers-$(uname -r)
“Hello, New Process!” プログラム
以下のPythonスクリプトを作成し、new_process_tracer.py
として保存してください。
python
from bcc import BPF
# 1. eBPFプログラムをC言語で記述
bpf_program = """
int kprobe__sys_clone(void *ctx) {
bpf_trace_printk("New process created!\\n");
return 0;
}
"""
# 2. BPFオブジェクトを初期化
b = BPF(text=bpf_program)
# 3. トレース結果を読み取って出力
print("Tracing new process creation... Ctrl+C to end.")
b.trace_print()
コード解説
eBPFプログラム
C言語の文字列としてeBPFのロジックを記述します。
kprobe__sys_clone
という関数名が重要です。kprobe__
という接頭辞は、カーネル関数sys_clone
(プロセスの生成を担うシステムコール)の実行開始時にこの関数をフックすることをbcc
に伝えます。bpf_trace_printk
は、カーネルのトレース用バッファにメッセージを書き込むためのヘルパー関数です。
BPFオブジェクトの初期化
BPF(text=bpf_program)
という一行で、bcc
はC言語のコードをeBPFバイトコードにコンパイルし、検証を経てカーネルにロードするまでの一連の処理を自動的に行ってくれます。
トレース結果の出力
b.trace_print()
は、bpf_trace_printk
によって書き込まれたメッセージを継続的に読み込み、標準出力に表示する便利な関数です。
実行してみる
管理者権限でこのスクリプトを実行します。
bash
sudo python3 new_process_tracer.py
別のターミナルを開いてls
やdate
といった任意のコマンドを実行してみてください。元のターミナルに「New process created!」というメッセージがリアルタイムで表示されるはずです。
これで、あなたはカーネルのイベントを捉える最初のeBPFプログラムを動かすことができました。
【ハンズオン2】bpftraceでファイルオープンを監視する
次に、bpftrace
を使い、より手軽にシステムの挙動を観察してみましょう。ここでは、/etc/passwd
ファイルが開かれた際に、どのプロセスがそれを行ったかを表示するワンライナーを作成します。これは、重要な設定ファイルへのアクセスを監視するセキュリティ監査の基本です。
環境準備
bpftrace
もbcc
と同様にパッケージマネージャからインストールできます。
bash
sudo apt-get install -y bpftrace
ファイルオープンを監視するワンライナー
以下のコマンドをターミナルで直接実行してください。
bash
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_openat /strcmp(args->filename, "/etc/passwd") == 0/ { printf("Process %s opened /etc/passwd\\n", comm); }'
コマンド解説
実行してみる
このコマンドを実行した状態で、別のターミナルからcat /etc/passwd
やless /etc/passwd
などを実行すると、コマンドを実行したプロセス名(cat
やless
)がリアルタイムで表示されることが確認できます。
このように、bpftrace
を使えば、複雑なコンパイル手順なしに、アイデアを即座に試すことが可能です。
まとめ
この記事では、eBPFの世界への第一歩として、bcc
とbpftrace
という2つの強力なツールを使ったハンズオンチュートリアルを紹介しました。
とPythonを使い、新規プロセス生成をトレースするプログラムを作成しました。bcc
を使い、特定のファイルへのアクセスを監視するワンライナーを実行しました。bpftrace
これで、カーネルのイベントをフックし、システムの深層で何が起きているかを可視化する基本的なスキルが学習できました。これは、日々の運用業務におけるパフォーマンス分析、トラブルシューティング、セキュリティ監視の質を大きく向上させる力となります。
今日作成したプログラムを拡張して、より詳細な情報(例えば、プロセスIDや実行ユーザーなど)を取得してみるのも良いでしょう。あるいは、
のGitHubリポジトリにある豊富なワンライナーやツール例を探求し、あなたの課題解決に役立つものがないか探してみるのも面白いかもしれません。 bpftrace
この記事が参考になれば幸いです!