
Jailerは、eBPFベースのプロセス隔離システムであり、Linuxに強制アクセス制御(MAC)を提供します。BPF task_storageマップを使用してプロセスを追跡し、ファイルアクセス、ネットワーク操作、プロセス実行に対するロールベースのポリシーを適用します。
警告: このプロジェクトは活発に開発中であり、本番環境での使用には適していません。API、ポリシー形式、および動作は予告なく変更される可能性があります。テストおよび実験のみに使用してください。
注記: これは独立した実装であり、Meta のソリューションと同じプロジェクトではありません。BpfJailer は機能的に類似しており、Meta の Liam Wisehart、Justin Ngai、Carl El Khoury、Mansee Chadha によるオリジナルのアイデアと設計に触発されていますが、これは独立して開発された別のコードベースです。この作業にインスピレーションを与えたビジョンと基礎的概念に感謝の意を表します。
Jailer は、Linux に強制アクセス制御 (MAC) を提供する eBPF ベースのプロセスジェイルシステムです。BPF の task_storage マップを使用してプロセスを追跡し、ファイルアクセス、ネットワーク操作、およびプロセス実行に対してロールベースのポリシーを適用します。
| 機能 | ステータス | 説明 |
|---|---|---|
| プロセス追跡 | ✅ 動作中 | task_storage BPF マップを使用してプロセスを追跡 |
| ソケット登録 | ✅ 動作中 | プロセスは Unix ソケット API を介して登録 |
| ロールベースポリシー | ✅ 動作中 | 制限付きおよび許可的なロール |
| ファイルアクセス制御 | ✅ 動作中 | ファイルオープン操作のブロック/許可 |
| ジェイル継承 | ✅ 動作中 | 子プロセスは親のジェイルを継承 |
| ネットワーク制御 | ✅ 動作中 | ソケットの bind/connect のブロック/許可 |
| ポート/プロトコルフィルタリング | ✅ 動作中 | ポートごとの TCP/UDP 許可/拒否ルール |
| Exec 制御 | ✅ 動作中 | プロセス実行のブロック/許可 |
| パスマッチング | ✅ 動作中 | キャッシュ無効化を伴う dentry ウォーキング |
| 署名付きバイナリ | 🚧 スタブ | バイナリ署名検証 (未実装) |
| 代替登録 | ✅ 動作中 | 実行ファイル、cgroup、または xattr による自動登録 |
| デーモンレスモード | ✅ 動作中 | ブートストラップバイナリが起動初期にプログラムをピン留め |
| 監査イベント | ✅ 動作中 | systemd-journald 統合用の perf バッファ |

BPF_MAP_TYPE_TASK_STORAGE サポート用)# Check current kernel config
zcat /proc/config.gz 2>/dev/null || cat /boot/config-$(uname -r)
必須オプション:
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_LSM=y
CONFIG_DEBUG_INFO_BTF=y
BPF LSM はカーネルの起動パラメータで有効化する必要があります:
# Check if BPF LSM is active
cat /sys/kernel/security/lsm
# Should include "bpf" in the list
# If not, add to kernel boot parameters:
# Edit /etc/default/grub and add to GRUB_CMDLINE_LINUX:
# lsm=lockdown,capability,landlock,yama,apparmor,bpf
# Then update grub and reboot:
sudo update-grub
sudo reboot
Ubuntu/Debian システムでは、以下も使用できます:
# Create a script to enable BPF LSM
cat > /tmp/enable_bpf_lsm.sh << 'EOF'
#!/bin/bash
GRUB_FILE="/etc/default/grub"
if grep -q "lsm=" "$GRUB_FILE"; then
sudo sed -i 's/lsm=[^""]*/lsm=lockdown,capability,landlock,yama,apparmor,bpf/' "$GRUB_FILE"
else
sudo sed -i 's/GRUB_CMDLINE_LINUX="\(.*\)"/GRUB_CMDLINE_LINUX="\1 lsm=lockdown,capability,landlock,yama,apparmor,bpf"/' "$GRUB_FILE"
fi
sudo update-grub
echo "BPF LSM enabled. Please reboot."
EOF
chmod +x /tmp/enable_bpf_lsm.sh
sudo /tmp/enable_bpf_lsm.sh
ビルド済みの tarball が x86_64 と aarch64 向けに公開されており、glibc 2.31 に対してビルドされているため、ビルドに使用されたディストリビューションよりも古いディストリビューションでも動作します。
curl -fsSL https://github.com/gen0sec/jailer/raw/main/install.sh | sudo sh
スクリプトは何かをインストールする前にSHA256を検証します。すべての成果物は GPG署名もされています。来歴を確認するには、まずリリースキーをインポートしてください:
curl -fsSL https://github.com/gen0sec/jailer/releases/download/v0.1.1/bpfjailer-signing-key.asc | gpg --import
手動でインストールする場合は、リリースページからお使いのアーキテクチャ用のtarballをダウンロードし、以下を実行してください:
tar xzf bpfjailer-*-linux-gnu.tar.gz && cd bpfjailer-*-linux-gnu
sudo install -Dm0755 bpfjailer-bootstrap /usr/sbin/bpfjailer-bootstrap
sudo install -Dm0755 bpfjailer-daemon /usr/sbin/bpfjailer-daemon
sudo install -Dm0644 bpfjailer.bpf.o /usr/lib/bpfjailer/bpfjailer.bpf.o
sudo install -Dm0644 policy.json /etc/bpfjailer/policy.json
sudo install -Dm0644 bpfjailer-*.service /etc/systemd/system/
sudo systemctl daemon-reload
次に、インストールモードで説明されている2つのモードのいずれかを有効にします。
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install build dependencies (Ubuntu/Debian)
sudo apt-get install -y clang llvm libelf-dev linux-headers-$(uname -r)
# Install BPF target for Rust
rustup target add bpfel-unknown-none
cd jailer
# Build BPF programs
cd bpfjailer-bpf && cargo build --release && cd ..
# Build daemon and client
cargo build --release
# Run as root (loads config/policy.json if present)
sudo RUST_LOG=info ./target/release/bpfjailer-daemon
予想される出力:
[INFO] BpfJailer daemon starting...
[INFO] Loading BpfJailer eBPF programs with libbpf-rs...
[INFO] ✓ pending_enrollments map available for enrollment
[INFO] ✓ network_rules map available for port/protocol filtering
[INFO] ✓ task_storage map created successfully
[INFO] ✓ Program task_alloc attached
[INFO] ✓ Program file_open attached
[INFO] ✓ Program socket_bind attached
[INFO] ✓ Program socket_connect attached
[INFO] ✓ Program bprm_check_security attached
[INFO] Initialized with default roles: restricted (1), permissive (2)
[INFO] Loaded policy from config/policy.json
[INFO] Loaded 5 roles
[INFO] Enrollment server listening on /run/bpfjailer/enrollment.sock
# Run vulnerability tests WITHOUT jailing (shows attacks succeed)
sudo python3 tests/vulnerable_apps/run_tests.py
# Run vulnerability tests WITH restricted role (shows attacks blocked)
sudo python3 tests/vulnerable_apps/run_tests.py --role 1
# Run specific test
sudo python3 tests/vulnerable_apps/run_tests.py --role 1 --test path
# List available tests and roles
sudo python3 tests/vulnerable_apps/run_tests.py --list
制限されたロールでの出力例:
============================================================
TEST: Path Traversal / Arbitrary File Read
============================================================
Attempting to read /etc/passwd via path traversal...
BLOCKED - Permission denied (BpfJailer blocked file access)
============================================================
TEST: Command Injection
============================================================
Attempting command injection...
BLOCKED - Permission denied (BpfJailer blocked exec)
============================================================
TEST: Reverse Shell / Data Exfiltration
============================================================
Test 1: Reverse shell connection to 127.0.0.1:4444
BLOCKED - Permission denied (BpfJailer blocked connect)
| テスト | 脆弱性 | 緩和策 |
|---|---|---|
path_traversal | ../ による任意ファイル読み取り | restricted, isolated |
command_injection | シェルコマンド実行 | restricted, webserver, isolated |
reverse_shell | 攻撃者へのアウトバウンド接続 | restricted, isolated |
ssrf | 内部サービス/クラウドメタデータへのアクセス | restricted, isolated |
arbitrary_write | 機密パスへの書き込み | restricted |
crypto_miner | ダウンロード + 実行 + プールへの接続 | restricted, webserver |
privilege_escalation | shadow の読み取り、sudoers への書き込み | restricted |
#!/usr/bin/env python3
import socket
import json
import os
# Connect to daemon
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect("/run/bpfjailer/enrollment.sock")
# Enroll with restricted role (ID 1)
request = {"Enroll": {"pod_id": 1, "role_id": 1}}
sock.send((json.dumps(request) + "\n").encode())
response = sock.recv(4096).decode()
print(f"Enrollment: {response}")
sock.close()
# Try to read a file (should be blocked)
try:
open("/etc/passwd").read()
print("File access: ALLOWED")
except PermissionError:
print("File access: BLOCKED")
BpfJailerはJSONポリシーファイルからロールを読み込みます。デーモンは以下の順序でポリシーファイルを検索します:
$BPFJAILER_POLICY 環境変数/etc/bpfjailer/policy.jsonconfig/policy.json(作業ディレクトリからの相対パス)