🐝

eBPFトラフィ���クリダイレクト — カーネルでの宛先すり替え

Keploy、Cilium、Istioがアプリコード修正なしに���ラフィックを制御する原理

まずeBPFとは

eBPF(extended Berkeley Packet Filter)はLinuxカーネル内でユーザーが書いたプログラムを実行できる技術だ。カーネルコードを直接修正せずにカーネルの動作を拡張できる。

ネットワークパケット処理、syscall追跡、セキュリティポリシー適用に使われる。核心は「カーネル内で動く」こと。ユーザースペースより遥かにオーバーヘッドが少ない。

connect() syscallとeBPFフック

アプリがDBに接続する時に内部で起きること:

1. アプリコード:db.connect("postgres://localhost:5432")
2. ラ���ブラリ(pg、psycopg2):socket() → connect() syscall呼び出し
3. カーネル:TCP SYN → SYN-ACK → ACK(3ウェイハンドシェイ��)
4. PostgreSQLワイヤプロトコル通��開始

eBPFは2〜3の間にフックをかける。connect() syscallが実行される時点で宛先アドレスを確認し、必要なら別のアドレスにすり替える

アプリから見ればpostgres:5432に接続した。実際のTCPパケットは127.0.0.1:16789(プロキシ)に行く。アプリはこの事実を知らない。

eBPFプログラムタイプ別フックポイント

SockOps(BPF_PROG_TYPE_SOCK_OPS) — TCPイベント(接続確立、切断等)を監視。cgroupに付着して特定コンテナのTCPイベントだけ選別可能。

connect4/connect6(BPF_CGROUP_INET4_CONNECT) — connect() syscall進入時点で宛先IP:Portを直接修正。Keployが使うコアフックがこれ。

TC(Traffic Control) — ネットワークインターフェースに付着。パケット単位でフィルタリング/リダイレクト。CiliumがPod間トラフィック制御に使用。

XDP(eXpress Data Path) — NICでパケットがカーネルネットワークスタックに入る前に処理。最速だが制約も大きい。

自分で確認する方法

# 1. connect() syscall追跡
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_connect {
  printf("%s[%d] → connect()\n", comm, pid);
}'

# 2. TCP接続先の確認
sudo bpftrace -e 'kprobe:tcp_v4_connect {
  printf("%s → %s:%d\n", comm,
    ntop(((struct sockaddr_in *)arg1)->sin_addr.s_addr),
    ntohs(((struct sockaddr_in *)arg1)->sin_port));
}'

Keployを起動した状態でアプリを実行すると、connect()の宛先がpostgres:5432��はなく127.0.0.1:プロキシポートに変わるのが見える。

Keployで簡単テスト

curl -O -L https://keploy.io/install.sh && source install.sh
keploy record -c "docker compose up" --container-name my-app
keploy test -c "docker compose up" --container-name my-app

macOSではDocker Desktop上でのみ動作。eBPFはLinuxカーネル機能なので。

動作フロー

1

eBPFプログラムがカーネルにロード — connect4フックでconnect() syscallを傍受

2

アプリがconnect(postgres:5432)呼び出し → eBPFが宛先をプロキシ(127.0.0.1:proxyPort)に修正

3

プロキシが本来の宛先に中継しながら録画(録画)または録画済み応答を返却(再生)

4

アプリは宛先変更を知らない — カーネルレベル透過リダイレクト

ユースケース

Keploy — connect4フックでDB/APIトラフィックをプロキシにリダイレクト、テスト自動生成 Cilium — TCフックでKubernetes Pod間トラフィック制御。iptables置換 Istio ambient — eBPFでサイドカーなしのサービスメッシュ実装 Beyla — XDP/TCでHTTP/gRPC/SQLを自動検知、OpenTelemetryメトリクス収集