
Jailer는 Linux를 위한 강제 접근 제어(MAC)를 제공하는 eBPF 기반 프로세스 격리 시스템입니다. 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를 통해 프로세스 등록 |
| 역할 기반 정책 | ✅ 작동 | 제한 및 허용 역할 |
| 파일 접근 제어 | ✅ 작동 | 파일 열기 작업 차단/허용 |
| Jail 상속 | ✅ 작동 | 자식 프로세스가 부모의 jail 상속 |
| 네트워크 제어 | ✅ 작동 | 소켓 바인드/연결 차단/허용 |
| 포트/프로토콜 필터링 | ✅ 작동 | 포트별 TCP/UDP 허용/거부 규칙 |
| 실행 제어 | ✅ 작동 | 프로세스 실행 차단/허용 |
| 경로 매칭 | ✅ 작동 | 캐시 무효화를 포함한 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
그런 다음 설치 모드에 설명된 두 가지 모드 중 하나를 활성화하십시오.
# 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 (작업 디렉터리 기준 상대 경로)