# fortify-xdp A high-performance XDP (eXpress Data Path) firewall written in Rust with a real-time TUI monitoring interface. ## Features - **High-performance packet filtering** via eBPF/XDP attached at the earliest ingress point - **Instant blocklist** — dynamically ban/unban IPs via CLI with immediate effect (no restart) - **Custom exact-match rules** — filter on IPv4 src/dst IP, protocol, and ports with Drop/Pass/Log actions - **IP range dropping** — CIDR-based blocks (e.g. `192.168.0.0/16`) using an LPM trie - **Rate limiting** — both flow-based (5-tuple) and IP-based token-bucket rate limits - **Temporary bans** — auto-ban IPs or flows that exceed rate limits for a configurable duration - **Logging system** — stream matched events to userspace via a BPF ring buffer - **Real-time monitoring** — terminal UI showing live counters, active rules, blocklist, and recent hits ## Architecture ``` xdp-firewall/ Userspace CLI + TUI (aya, clap, ratatui, tokio) xdp-firewall-ebpf/ eBPF/XDP kernel program (aya-ebpf) xdp-firewall-common/ Shared types between user/kernel space xtask/ Build helper for eBPF compilation scripts/setup-veth.sh Virtual veth pair for safe local testing ``` ### eBPF Maps | Map | Type | Purpose | |-----|------|---------| | `BLOCKLIST` | `HashMap` | IP → expiry timestamp | | `IP_RANGES` | `LpmTrie` | CIDR prefix → action | | `RULES` | `HashMap` | Exact-match rules | | `RATE_LIMIT_STATE` | `HashMap` | Token bucket state | | `RATE_LIMIT_CONFIG` | `HashMap` | Global rate limit config | | `STATS` | `HashMap` | Per-rule packet/byte counters | | `GLOBAL_STATS` | `Array` | Aggregated counters | | `EVENTS` | `RingBuf` | Event stream to userspace | ### Packet Flow 1. Parse Ethernet → IPv4 → TCP/UDP headers 2. **Blocklist check** → `XDP_DROP` if IP is banned and not expired 3. **IP range check** → `XDP_DROP` if source IP matches a CIDR range with drop action 4. **Rate limit check** → token bucket; if exceeded, drop and optionally temp-ban 5. **Rule check** → exact-match lookup; apply Drop/Pass/Log 6. **Default** → `XDP_PASS` ## Prerequisites - Linux kernel with BPF and XDP support - Rust toolchain (stable + nightly for eBPF) - `bpf-linker` - `clang` / `llvm` - Root privileges for loading XDP programs and creating BPF maps Install nightly and `bpf-linker`: ```bash rustup toolchain install nightly rustup component add rust-src --toolchain nightly cargo install bpf-linker ``` ## Build ```bash cargo run -p xtask -- build-ebpf cargo build --release -p xdp-firewall ``` ## Quick Start Create a virtual `veth` pair for safe local testing: ```bash sudo ./scripts/setup-veth.sh ``` This creates `veth0` (host, `10.200.1.1`) and `veth1` (in `testns`, `10.200.1.2`). Load the XDP firewall on `veth0`: ```bash sudo ./target/release/xdp-firewall load --iface veth0 ``` ## CLI Usage ### Blocklist ```bash sudo ./target/release/xdp-firewall block --iface veth0 --ip 10.200.1.2 sudo ./target/release/xdp-firewall unblock --iface veth0 --ip 10.200.1.2 ``` Block with a temporary duration (seconds): ```bash sudo ./target/release/xdp-firewall block --iface veth0 --ip 10.200.1.2 --duration 300 ``` ### Rules Add a rule to drop UDP traffic to port 9999: ```bash sudo ./target/release/xdp-firewall add-rule \ --iface veth0 \ --src-ip 0.0.0.0 \ --dst-ip 10.200.1.1 \ --proto 17 \ --src-port 0 \ --dst-port 9999 \ --action drop ``` List active rules with live hit counts: ```bash sudo ./target/release/xdp-firewall list-rules --iface veth0 ``` Delete a rule by ID: ```bash sudo ./target/release/xdp-firewall del-rule --iface veth0 --id 0 ``` Use `0.0.0.0` for wildcard IPs and `0` for wildcard ports/protocols. ### IP Ranges ```bash sudo ./target/release/xdp-firewall add-range --iface veth0 --cidr 192.168.0.0/16 --action drop sudo ./target/release/xdp-firewall del-range --iface veth0 --cidr 192.168.0.0/16 ``` ### Rate Limiting Set an IP-based rate limit of 100 pps with burst 200; temp-ban after 10 violations for 60 seconds: ```bash sudo ./target/release/xdp-firewall set-ratelimit \ --iface veth0 \ --rate 100 \ --burst 200 \ --ban-threshold 10 \ --ban-duration 60 \ --mode ip ``` Use `--mode flow` for 5-tuple flow-based rate limiting. ### Monitor (TUI) ```bash sudo ./target/release/xdp-firewall monitor --iface veth0 ``` **Keybindings** | Key | Action | |-----|--------| | `Tab` | Switch panes (Rules → Blocklist → Logs) | | `↑` / `↓` | Navigate lists | | `b` | Block IP dialog | | `u` | Unblock selected IP | | `a` | Add rule dialog | | `d` | Delete selected rule | | `q` | Quit | ### Unload ```bash sudo ./target/release/xdp-firewall unload --iface veth0 ``` ## Development The project uses a Cargo workspace. The eBPF crate is compiled with nightly using `bpf-linker`: ```bash # Build eBPF only cargo run -p xtask -- build-ebpf # Build userspace only cargo build --release -p xdp-firewall ``` ## License MIT