Skip to content

Commit 6a4c753

Browse files
docs: add README.md
Signed-off-by: saiaunghlyanhtet <saiaunghlyanhtet2003@gmail.com>
1 parent 37d54f9 commit 6a4c753

1 file changed

Lines changed: 285 additions & 0 deletions

File tree

README.md

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
# Firebee
2+
3+
An eBPF-based network firewall for Linux that uses XDP (eXpress Data Path) for high-performance ingress packet filtering and TC-BPF (Traffic Control) for egress filtering. Firebee provides a declarative policy file format, a CLI for rule management, and a real-time terminal UI (TUI) for monitoring traffic.
4+
5+
## Features
6+
7+
- **XDP ingress filtering** — Drops or allows packets at the earliest point in the network stack, before the kernel allocates an `sk_buff`, for near line-rate performance.
8+
- **TC-BPF egress filtering** — Filters outgoing traffic using the Linux Traffic Control subsystem.
9+
- **IPv4 and IPv6 support** — Rules can target individual IPs or CIDR ranges for both address families.
10+
- **Protocol and port matching** — Filter by TCP, UDP, ICMP, or any protocol, with optional source/destination port constraints.
11+
- **Declarative policy files** — Define rules in YAML or JSON; firebee validates and loads them.
12+
- **Per-rule statistics** — Track packet and byte counts per rule in real time.
13+
- **Terminal UI** — A ratatui-based TUI shows active rules, live packet logs from a BPF ring buffer, and per-rule stats.
14+
- **Pinned BPF maps** — Maps are pinned to `/sys/fs/bpf/firebee/` so rules persist across CLI invocations and multiple tools can interact with the running firewall.
15+
16+
## Prerequisites
17+
18+
- Linux kernel ≥ 5.15 (with BPF and XDP support)
19+
- `clang` and `llvm` (for compiling BPF C programs)
20+
- `libelf-dev`, `libbpf-dev`, `pkg-config`
21+
- Linux headers for your kernel (`linux-headers-$(uname -r)`)
22+
- Rust toolchain (stable)
23+
- Root privileges (or `CAP_BPF` + `CAP_NET_ADMIN`) to load BPF programs
24+
25+
### Install dependencies (Debian/Ubuntu)
26+
27+
```bash
28+
sudo apt-get install -y \
29+
llvm clang libelf-dev libbpf-dev linux-headers-$(uname -r) \
30+
linux-libc-dev build-essential pkg-config
31+
```
32+
33+
## Building
34+
35+
```bash
36+
make build
37+
```
38+
39+
This runs `cargo build --release` (compiles the Rust userspace binary) and `cargo libbpf build` (compiles the BPF C programs into `.bpf.o` object files under `target/bpf/`).
40+
41+
## Architecture
42+
43+
```
44+
┌──────────────────────────────────────────────────────────┐
45+
│ Userspace (Rust) │
46+
│ │
47+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │
48+
│ │ CLI │ │ Policy │ │ State │ │ TUI │ │
49+
│ │ (clap) │ │ Parser & │ │ Manager │ │(ratatui)│ │
50+
│ │ │ │Validator │ │ │ │ │ │
51+
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬────┘ │
52+
│ │ │ │ │ │
53+
│ └──────────────┴─────┬───────┴──────────────┘ │
54+
│ │ │
55+
│ ┌───────▼────────┐ │
56+
│ │ BPF Loader │ │
57+
│ │ & Maps API │ │
58+
│ └───────┬────────┘ │
59+
└────────────────────────────┼─────────────────────────────┘
60+
│ libbpf-rs
61+
┌─────────▼──────────┐
62+
│ Pinned BPF Maps │
63+
│ /sys/fs/bpf/firebee│
64+
└─────────┬──────────┘
65+
66+
┌────────────────┼────────────────┐
67+
│ │ │
68+
┌────────▼──────┐ ┌─────▼──────┐ ┌──────▼───────┐
69+
│ XDP Program │ │ TC Egress │ │ Ring Buffer │
70+
│ (ingress) │ │ Program │ │ (log_events)│
71+
│ firebee.bpf.c│ │firebee_ │ │ │
72+
│ │ │egress.bpf.c│ │ │
73+
└───────────────┘ └────────────┘ └──────────────┘
74+
Kernel space (eBPF)
75+
```
76+
77+
### Major Components
78+
79+
#### 1. CLI (`src/main.rs`)
80+
81+
The entry point. Uses [clap](https://docs.rs/clap) to expose these subcommands:
82+
83+
| Command | Description |
84+
|---------|------------|
85+
| `run <interface>` | Attach the XDP/TC programs to a network interface and optionally load a policy file. |
86+
| `ui` | Launch the terminal UI to monitor an already-running firewall. |
87+
| `add --policy <file>` | Parse and load rules from a YAML/JSON policy file into the running firewall. |
88+
| `get rule [name]` | Print one or all active rules (YAML or JSON output). |
89+
| `delete rule <name>` | Remove a rule by name. |
90+
| `stats show` | Display per-rule packet/byte statistics. |
91+
| `stats reset` | Reset all counters to zero. |
92+
93+
#### 2. BPF Programs (`src/bpf/`)
94+
95+
- **`firebee.bpf.c`** — The XDP program (`xdp_firewall`). Attached to a network interface, it inspects every incoming packet: parses Ethernet/IP/IPv6 headers, extracts protocol and ports, iterates through the rules array map to find a match (with CIDR, protocol, port, and direction checks), logs the decision to a ring buffer, and returns `XDP_DROP` or `XDP_PASS`.
96+
- **`firebee_egress.bpf.c`** — The TC-BPF program (`tc_egress_firewall`). Attached via the Traffic Control egress hook, it performs the same matching logic on outgoing packets, returning `TC_ACT_SHOT` (drop) or `TC_ACT_OK` (pass).
97+
- **`firebee_common.h`** — Shared struct definitions (`rule_entry`, `rule_entry_v6`, `rule_metadata`, `log_event`, `rule_stats`) used by both kernel and userspace.
98+
- **`firebee_helpers.h`** — BPF helper functions for port extraction, rule matching, and IPv6 prefix comparison.
99+
- **`firebee_test.bpf.c`** — Kernel-side BPF unit tests using Cilium-style `CHECK`/`TEST` macros.
100+
101+
BPF maps used:
102+
103+
| Map | Type | Purpose |
104+
|-----|------|---------|
105+
| `rules_map` | Array | IPv4 rule entries for fast iteration |
106+
| `rules_map_v6` | Array | IPv6 rule entries |
107+
| `rule_metadata_map` | Hash | Human-readable metadata (name, description) keyed by index |
108+
| `rule_stats_map` | Array | Per-rule packet/byte counters |
109+
| `log_events` | Ring Buffer | Real-time packet log events sent to userspace |
110+
111+
#### 3. BPF Userspace Layer (`src/bpf_user/`)
112+
113+
- **`loader.rs`**`BpfLoader` opens the compiled `.bpf.o` files, pins all maps to `/sys/fs/bpf/firebee/`, attaches the XDP program to the given interface, and optionally loads the TC egress program.
114+
- **`maps.rs`**`BpfMaps` provides a safe Rust API over the pinned BPF maps: add/remove/list rules, read/write metadata, get/reset statistics, and interact with both IPv4 and IPv6 rule maps.
115+
- **`handler.rs`**`BpfHandler` runs the event loop: listens for commands (add rule, remove rule, unload) and polls the ring buffer for log events.
116+
117+
#### 4. Policy Engine (`src/policy/`)
118+
119+
- **`parser.rs`** — Reads a `.yaml`/`.yml` or `.json` file, deserialises it into a `PolicyFile` containing a list of `PolicyRule` structs. Supports IPv4, IPv6, CIDR notation, protocol, direction, and port fields.
120+
- **`validator.rs`** — Validates the parsed policy: checks for non-empty rules, unique names, valid IP addresses, valid actions (`allow`/`pass`/`accept`/`drop`/`deny`/`block`), and valid protocols/directions.
121+
122+
#### 5. State Manager (`src/state.rs`)
123+
124+
`RulesState` bridges the policy layer and the BPF maps. It converts `PolicyRule` objects into kernel-level `Rule` structs and calls the maps API to add, get, delete, or list rules.
125+
126+
#### 6. Terminal UI (`src/ui/`)
127+
128+
Built with [ratatui](https://docs.rs/ratatui) and [crossterm](https://docs.rs/crossterm):
129+
130+
- **`app.rs`** — Application state: active rules, log buffer, per-rule stats, input mode.
131+
- **`widgets.rs`** — Renders a rules table (name, IP, protocol, direction, ports, action, stats, description), a scrolling log pane, and help text.
132+
- **`events.rs`** — Keyboard event handling: `Q` to quit, `A` to add a rule interactively, `U` to unload the firewall (with confirmation).
133+
134+
## Usage
135+
136+
All commands require root privileges.
137+
138+
### Start the firewall on an interface
139+
140+
```bash
141+
sudo ./target/release/firebee run eth0
142+
```
143+
144+
Optionally load a policy file at startup:
145+
146+
```bash
147+
sudo ./target/release/firebee run eth0 --policy example-policy.yaml
148+
```
149+
150+
### Add rules from a policy file to a running firewall
151+
152+
```bash
153+
sudo ./target/release/firebee add --policy example-policy.yaml
154+
```
155+
156+
To attach to a new interface and load rules in one step:
157+
158+
```bash
159+
sudo ./target/release/firebee add --policy example-policy.yaml --interface eth0 --attach
160+
```
161+
162+
### Launch the TUI
163+
164+
```bash
165+
sudo ./target/release/firebee ui
166+
```
167+
168+
This connects to the already-running firewall's pinned maps and shows live rules, stats, and packet logs.
169+
170+
### Query active rules
171+
172+
```bash
173+
# List all rules (YAML output)
174+
sudo ./target/release/firebee get rule
175+
176+
# Get a specific rule in JSON
177+
sudo ./target/release/firebee get rule block_suspicious_ip --output json
178+
```
179+
180+
### Delete a rule
181+
182+
```bash
183+
sudo ./target/release/firebee delete rule block_suspicious_ip
184+
```
185+
186+
### View and reset statistics
187+
188+
```bash
189+
# Show per-rule stats
190+
sudo ./target/release/firebee stats show
191+
192+
# Reset all counters
193+
sudo ./target/release/firebee stats reset
194+
```
195+
196+
### Cleanup
197+
198+
To fully detach all BPF programs and remove pinned maps:
199+
200+
```bash
201+
sudo ./cleanup.sh
202+
```
203+
204+
## Policy File Format
205+
206+
Rules are defined in YAML (recommended) or JSON. See [POLICY.md](POLICY.md) for the full specification.
207+
208+
### Example (YAML)
209+
210+
```yaml
211+
rules:
212+
- name: block_suspicious_ip
213+
ip: 192.168.1.100
214+
action: drop
215+
protocol: any
216+
direction: ingress
217+
description: Block known malicious IP address
218+
219+
- name: allow_dns_queries
220+
ip: 8.8.8.8
221+
action: allow
222+
protocol: udp
223+
dst_port: 53
224+
direction: both
225+
description: Allow DNS queries to Google DNS
226+
227+
- name: block_ssh_from_subnet
228+
ip: 192.168.100.0/24
229+
action: drop
230+
protocol: tcp
231+
dst_port: 22
232+
direction: ingress
233+
description: Block SSH access from entire subnet
234+
```
235+
236+
### Example (IPv6)
237+
238+
```yaml
239+
rules:
240+
- name: block_google_ipv6_dns_icmp
241+
ip: 2001:4860:4860::8888/128
242+
action: drop
243+
direction: ingress
244+
protocol: icmp
245+
description: Block ICMPv6 from Google IPv6 DNS
246+
247+
- name: allow_cloudflare_ipv6_https
248+
ip: 2606:4700::/32
249+
action: allow
250+
direction: ingress
251+
protocol: tcp
252+
src_port: 443
253+
description: Allow HTTPS from Cloudflare IPv6
254+
```
255+
256+
### Rule Fields
257+
258+
| Field | Required | Default | Values |
259+
|-------|----------|---------|--------|
260+
| `name` | yes | — | Unique identifier |
261+
| `ip` | yes | — | IPv4/IPv6 address or CIDR (e.g. `10.0.0.0/8`, `2001:db8::/32`) |
262+
| `action` | yes | — | `allow` / `pass` / `accept` / `drop` / `deny` / `block` |
263+
| `protocol` | no | `any` | `tcp` / `udp` / `icmp` / `any` |
264+
| `direction` | no | `ingress` | `ingress` / `egress` / `both` |
265+
| `src_port` | no | any | Source port number |
266+
| `dst_port` | no | any | Destination port number |
267+
| `description` | no | — | Human-readable description |
268+
269+
## Testing
270+
271+
```bash
272+
# Run userspace unit tests
273+
make test
274+
275+
# Run BPF kernel-side tests (requires root)
276+
sudo make run_bpf_tests
277+
278+
# Run all tests
279+
sudo make test_all
280+
```
281+
282+
283+
## License
284+
285+
The license will be added in the future.

0 commit comments

Comments
 (0)