eBPF/XDP adalah layer pertahanan paling bawah di jarsWAF — beroperasi di L3 (network layer) sebelum TCP stack kernel. XDP program di-load ke interface via
aya-rsruntime, dan menggunakan BLOCKLIST map (HashMap<u32, u8>) yang di-populate oleh agent secara dinamis dari threat intel feeds. Catatan ini mendokumentasikan setup, attachment, dan E2E verification XDP drop via veth pair + namespace.
eBPF/XDP Layer — Network-Level BLOCK via XDP_DROP
Daftar Isi
- 1. eBPF Architecture
- 2. eBPF Binary Analysis
- 3. Path Bug Fix
- 4. XDP Attachment Verification
- 5. E2E XDP Drop Test
- 6. Limitations
- 7. Mitigation & Recommendations
1. eBPF Architecture
jarsWAF menggunakan dua program eBPF:
┌──────────────────────────────────────────────────┐
│ Userspace │
│ ┌──────────┐ ┌──────────────┐ │
│ │ Controller│ │ Agent │ │
│ │ (gRPC) │ │ (Pingora) │ │
│ └──────────┘ └──────┬───────┘ │
│ │ │
│ ┌───────────▼───────────┐ │
│ │ XDPManager │ │
│ │ - load Ebpf::load() │ │
│ │ - attach Xdp::attach()│ │
│ │ - block_ip() │ │
│ │ - unblock_ip() │ │
│ └───────────┬───────────┘ │
│ │ libbpf syscall │
├────────────────────────────────┼──────────────────┤
│ Kernel Space │ │
│ ┌────────────▼───────────┐ │
│ │ XDP Program │ │
│ │ (attached to veth0) │ │
│ │ │ │
│ Packet in ──────►│ ethhdr → Ipv4? │ │
│ │ └─ yes → IP src in │ │
│ │ BLOCKLIST? │ │
│ │ ├─ yes ──► │ │
│ │ │ XDP_DROP │ │
│ │ └─ no ────► │ │
│ │ XDP_PASS │ │
│ └──────────────────────────┘ │
│ │
│ ┌──────────────────────────┐ │
│ │ kprobe / RASP │ │
│ │ sys_execve → ring buffer │ │
│ └──────────────────────────┘ │
└─────────────────────────────────────────────────────┘
eBPF Program Objects
| Aspek | Detail |
|---|---|
| Runtime | aya-rs (aya 0.12+) — pure Rust eBPF library |
| Compiler | rustc via bpfel-unknown-none target |
| Mode | XdpMode::Generic (SKB-based, compatible with veth) |
| Map Type | HashMap<u32, u8> — key=IPv4 (u32 BE), value=block flag |
| Max Entries | 10,240 IP addresses |
2. eBPF Binary Analysis
$ readelf -a jarswaf-ebpf/target/bpfel-unknown-none/release/jarswaf-ebpf2 programs:
| Program | Type | Size | Section | Nama |
|---|---|---|---|---|
| XDP | xdp | 216 bytes | .text | jarswaf_ebpf |
| kprobe | kprobe | 288 bytes | .text | jarswaf_rasp_exec |
2 maps:
| Map | Type | Key | Value | Max | Koneksi |
|---|---|---|---|---|---|
BLOCKLIST | HashMap | u32 (BE) | u8 | 10,240 | XDP drop decision |
RASP_EVENTS | PerfEventArray | — | ExecveEvent | ring | kprobe → userspace |
Relocations:
xdp: referencesBLOCKLISTmap viaR_BPF_64_64relocationkprobe: referencesRASP_EVENTSmap +memsethelper call
Source Logic
File: jarswaf-ebpf/src/main.rs
fn try_jarswaf_ebpf(ctx: XdpContext) -> Result<u32, ()> {
// 1. Parse Ethernet header
let ethhdr = unsafe { ptr_at::<EthHdr>(&ctx, 0)? };
// 2. Skip non-IPv4
if ethhdr.ether_type != ETH_P_IP {
return Ok(XDP_PASS);
}
// 3. Parse IPv4 header
let ipv4hdr = unsafe { ptr_at::<Ipv4Hdr>(&ctx, EthHdr::LEN)? };
let source_ip = u32::from_be(ipv4hdr.src_addr);
// 4. Check blocklist
let blocklist = HashMap::<u32, u8>::try_from(&*BLOCKLIST)?;
match blocklist.get(&source_ip, 0) {
Some(_) => Ok(XDP_DROP), // DROP at network layer
None => Ok(XDP_PASS), // Forward
}
}Kprobe Source Logic
fn try_jarswaf_rasp_exec(ctx: TracePointContext) -> Result<u32, ()> {
// Monitor execve syscall → detect process injection
// Sends event to RASP_EVENTS PerfEventArray
// (Not yet tested in this session)
}3. Path Bug Fix
Sebelum fix:
// src/xdp.rs:33
match Ebpf::load_file("target/bpfel-unknown-none/release/jarswaf-ebpf") {Error:
WARN: Failed to load eBPF object.
Error 2: FileError { path: "target/bpfel-unknown-none/release/jarswaf-ebpf",
error: Os { code: 2, kind: NotFound } }
Sesudah fix:
// src/xdp.rs:33
match Ebpf::load_file("jarswaf-ebpf/target/bpfel-unknown-none/release/jarswaf-ebpf") {Root cause: Di development (non-Docker), eBPF Cargo workspace menghasilkan binary di jarswaf-ebpf/target/... — relative path dari project root. Tapi xdp.rs nyari di target/... yang adalah root target Docker container.
Kenapa gak kena sebelumnya? Karena fitur XDP di-agent bersifat opsional — kalau path gak ketemu, warn! + skip. Gak ada hard error atau crash.
4. XDP Attachment Verification
CAP_BPF Grant
Karena loading eBPF butuh CAP_BPF dan CAP_NET_ADMIN, agent binary perlu capabilities:
sudo setcap cap_bpf,cap_net_admin+ep target/debug/agent
sudo setcap cap_bpf,cap_net_admin+ep target/debug/controllerBuild Agent & Load
$ cargo run --bin agent
INFO: "Attaching eBPF XDP to interface: veth0"
INFO: "XDP program successfully attached to interface: veth0"Verify via bpftool
$ sudo bpftool net
xdp:
veth0(3) driver id 185driver id 185 = driver mode — XDP di-attach langsung ke veth driver, bukan generic SKB mode.
BLOCKLIST Auto-Population
Agent otomatis populate BLOCKLIST dari threat intel feeds (Spamhaus DROP list, FireHOL, Tor exit nodes):
$ process log | grep "added to XDP blocklist"
INFO: "IP 207.45.56.0 added to XDP blocklist"
INFO: "IP 208.75.88.0 added to XDP blocklist"
INFO: "IP 209.17.192.0 added to XDP blocklist"
... 300+ IPs loaded ...
5. E2E XDP Drop Test
Setup
# Create veth pair + namespace
sudo ip netns add testns
sudo ip link add veth0 type veth peer name veth1 netns testns
sudo ip addr add 10.0.0.1/24 dev veth0
sudo ip netns exec testns ip addr add 10.0.0.2/24 dev veth1
# Start agent with xdp_interface = "veth0"Test Flow
Step 1: Verify connectivity (baseline)
namespace → ping 10.0.0.1 → 2/2 ✅
Step 2: Inject IP ke XDP BLOCKLIST via bpftool
sudo bpftool map update id 33 key 0x0a 0x00 0x00 0x02 value 0x01
(key = 10.0.0.2 in network byte order)
Step 3: Verify XDP DROP
namespace → ping 10.0.0.1 → 0/2 (100% loss) 🔥🔥
Step 4: Recovery
sudo bpftool map delete id 33 key 0x0a 0x00 0x00 0x02
namespace → ping 10.0.0.1 → 1/1 ✅
Hasil
Before (no blocklist):
3 packets transmitted, 3 received, 0% packet loss
After (10.0.0.2 in BLOCKLIST):
2 packets transmitted, 0 received, 100% packet loss ← XDP_DROP!
After (removed from BLOCKLIST):
1 packets transmitted, 1 received, 0% packet loss ← Recovery OK
Key Finding
XDP program melakukan DROP di L3 — sebelum TCP stack, sebelum iptables, sebelum semua L7 processing. Ini artinya:
| Layer | Sebelum XDP | Sesudah XDP |
|---|---|---|
| NIC driver rx queue | ✅ | ✅ |
| XDP hook | — | DROP here |
| SKB allocation | ✅ | ❌ (saved) |
| TCP/IP stack | ✅ | ❌ (saved) |
| iptables/nftables | ✅ | ❌ (saved) |
| Application (WAF) | ✅ | ❌ (saved) |
Ini extreme efficiency — attacker yang IP-nya sudah dikenal gak perlu consume CPU WAF sama sekali.
6. Limitations
XDP Tidak Bekerja di WiFi
Wireless interface (iwlwifi, ath, Broadcom) tidak support XDP karena driver tidak memiliki native XDP hook. Testing hanya bisa via:
| Method | Dapat? | Keterangan |
|---|---|---|
| veth pair (namespace) | ✅ | XdpMode::Generic |
| VM with virtio NIC | ✅ | Driver native XDP |
| Loopback (lo) | ✅ | Generic mode |
| Real Ethernet (mlx5, i40e, ixgbe) | ✅ | Driver mode tercepat |
| WiFi (wlp2s0) | ❌ | Driver tidak support |
BLOCKLIST Hanya Exact Match
BLOCKLIST map adalah HashMap<u32, u8> — exact IP match, bukan CIDR. IP 10.0.0.2 adalah entry berbeda dengan 10.0.0.0/24 subnet. Jika threat intel feeds memasukkan subnet (CIDR), hanya IP pertama yang di-block.
Ini limitasi structural di eBPF — HashMap gak support prefix lookup. Solusi: gunakan LPMTrie (Longest Prefix Match Trie) map type.
kprobe / RASP Belum Diuji
Program jarswaf_rasp_exec sudah tercompile tapi belum di-test karena:
- Butuh
CAP_SYS_ADMINuntuk kprobe attach - kprobe butuh
/proc/kallsymsyang bisa di-restrict
7. Mitigation & Recommendations
Immediate Fix Sudah di-Apply
| Fix | File | Status |
|---|---|---|
Path eBPF target/ → jarswaf-ebpf/target/ | src/xdp.rs:33 | ✅ |
Config xdp_interface di config.toml | config.toml | ✅ |
Recommended Improvements
| # | Improvement | Impact |
|---|---|---|
| 1 | LPMTrie map untuk CIDR support di XDP BLOCKLIST | Block full subnet, bukan per-IP |
| 2 | XDP program update tanpa restart agent | Map pinning via bpffs |
| 3 | kprobe testing di VM dengan virtio NIC | Validasi RASP layer |
| 4 | Re-attach on interface change | Auto-detect interface down/up |
| 5 | XDP statistics (packets dropped vs passed) | Grafana metrics |
References
src/xdp.rs— XdpManager implementationjarswaf-ebpf/src/main.rs— eBPF program source- aya-rs — Rust eBPF library
- XDP Project — eXpress Data Path
- Cilium BPF and XDP Reference Guide
- kernel.org: XDP documentation
- Fedora Wiki: BPF
Koneksi ke Vault
| Catatan | Koneksi |
|---|---|
| sql-comment-injection-waf-bypass | L7 rule bypass testing — complement XDP at L3 |
| waf-reverse-proxy-deepdive | WAF architecture overview |
| purple-team-osi-killchain | Purple team killchain — L3 defense |
| web-hacking-exploitation | Web app exploitation — XDP tidak relevan di L3 |