Skip to content

muratdemirci/warden

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Warden

Warden

Rust 1.70+ License: MIT Platform Tests

A lightweight, high-performance network security tool built in Rust.
Captures live network traffic, filters packets against whitelist/blacklist rules,
evaluates a composable condition DSL, and takes actions (block, log, alert) in real time.


Features

  • Real-time packet capture via libpcap
  • Whitelist / Blacklist with CIDR, port, and protocol support
  • Composable rule engine with AND / OR / NOT conditions
  • IP blocking via iptables (Linux) or pf (macOS)
  • Block deduplication and alert rate limiting
  • Live monitor mode (tcpdump-style packet viewer)
  • Structured logging (JSON) to stdout and/or file
  • YAML configuration with validation
  • Async pipeline (Tokio) with zero-copy packet parsing

Requirements

  • Rust 1.70+
  • libpcap (libpcap-dev on Linux, included in Xcode CLI tools on macOS)
  • Root/sudo for packet capture

Installation

Prerequisites

libpcap must be installed before building:

# Ubuntu / Debian
sudo apt install libpcap-dev

# Fedora / RHEL
sudo dnf install libpcap-devel

# macOS (included with Xcode CLI tools)
xcode-select --install

Build from source

git clone https://github.com/muratdemirci/warden.git
cd warden
cargo build --release

The binary will be at target/release/warden.

Option 1: Run directly from the project directory

No installation needed. Use the full path to the binary:

sudo ./target/release/warden --monitor -i en0
sudo ./target/release/warden -i en0 --dry-run

Option 2: Install via cargo

This installs the binary to ~/.cargo/bin/, which is typically already in your PATH:

cargo install --path .
sudo warden --monitor -i en0

To uninstall later: cargo uninstall warden

Option 3: Install system-wide

Copy the binary to a system directory so all users can run it:

cargo build --release
sudo cp target/release/warden /usr/local/bin/

Now warden works from anywhere:

sudo warden --monitor -i en0

To uninstall later: sudo rm /usr/local/bin/warden

Verify installation

warden --version
warden --validate
warden --list-interfaces

Quick Start

# 1. List available network interfaces
sudo warden --list-interfaces

# 2. Validate your config
warden --validate

# 3. Monitor live traffic (no rules, just watch packets)
sudo warden --monitor -i en0

# 4. Run with full pipeline (filter + rules + actions)
sudo warden -i en0

# 5. Dry run (log actions without executing firewall commands)
sudo warden -i en0 --dry-run

Monitor Mode

Monitor mode prints every captured packet to stdout in a table format, bypassing all filter and rule logic. Useful for inspecting traffic before writing rules.

# Watch all traffic on en0
sudo warden --monitor -i en0

# Watch only TCP traffic
sudo warden --monitor -i en0 -f "tcp"

# Watch only HTTPS, limit to 20 packets
sudo warden --monitor -i en0 -f "tcp port 443" --monitor-count 20

# Watch DNS traffic
sudo warden --monitor -i en0 -f "udp port 53" --monitor-count 10

Output:

monitoring en0 — press Ctrl-C to stop

#      PROTO SOURCE                DESTINATION           TTL   LEN    FLAGS
------------------------------------------------------------------------------------------
1      TCP   192.168.0.101:55432   142.250.187.206:443   64    66     [SA]
2      TCP   192.168.0.101:55432   142.250.187.206:443   64    54     [A]
3      UDP   192.168.0.101:53045   192.168.0.1:53        64    72
4      TCP   142.250.187.206:443   192.168.0.101:55432   112   1452   [A]
5      TCP   192.168.0.101:55432   142.250.187.206:443   64    54     [A]

captured 5 packets, stopping.

─── monitor summary ───
  IPv4 packets: 5
  non-IPv4 skipped: 3

Columns: packet number, protocol (TCP/UDP/ICMP), source IP:port, destination IP:port, TTL, frame length in bytes, TCP flags (S=SYN, A=ACK, F=FIN, R=RST, P=PSH, U=URG).

Configuration

Warden uses a YAML config file (default: config.yaml).

Minimal config

interface: en0

Full example

interface: eth0

filter:
  whitelist:
    - "127.0.0.1"
    - ip: "192.168.1.0/24"

  blacklist:
    - "10.0.0.66"
    - ip: "0.0.0.0/0"
      port: 22
      protocol: "tcp"
    - ip: "172.16.0.0/12"
      protocol: "udp"

rules:
  # Block SSH from untrusted sources
  - name: "block untrusted ssh"
    priority: 10
    condition:
      all:
        - protocol: "tcp"
        - dst_port: 22
        - not:
            src_ip: "192.168.1.0/24"
    action: block

  # Alert on SYN scans to well-known ports
  - name: "syn scan alert"
    priority: 20
    condition:
      all:
        - protocol: "tcp"
        - tcp_flags: ["syn"]
        - dst_port: "1-1023"
    action: alert

  # Log HTTP/HTTPS traffic
  - name: "log web traffic"
    priority: 50
    condition:
      all:
        - protocol: "tcp"
        - any:
            - dst_port: 80
            - dst_port: 443
    action: log

logging:
  level: "info"
  json: false
  # file: "logs/warden.log"

Filter entries

Filters run before rules for fast early-exit. Whitelist takes priority over blacklist.

# Bare IP string
- "192.168.1.1"

# CIDR notation
- ip: "10.0.0.0/8"

# IP + port + protocol
- ip: "0.0.0.0/0"
  port: 22
  protocol: "tcp"

Rule conditions

Conditions are composable with all (AND), any (OR), and not (NOT):

Condition Example Description
src_ip src_ip: "10.0.0.0/8" Source IP or CIDR
dst_ip dst_ip: "192.168.1.1" Destination IP or CIDR
src_port src_port: 53 Source port (single or range)
dst_port dst_port: "1024-65535" Destination port (single or range)
protocol protocol: "tcp" tcp, udp, or icmp
tcp_flags tcp_flags: ["syn", "ack"] Required TCP flags
all all: [...] All children must match
any any: [...] At least one child must match
not not: { src_ip: "..." } Invert the child condition

Actions

Action Description
block Adds a firewall rule to drop traffic from the source IP
log Logs the packet with full metadata
alert Logs a warning (rate-limited per rule+IP, 60s cooldown)

Logging

logging:
  level: "info" # error, warn, info, debug, trace
  json: false # true = JSON output to stdout
  file: "logs/warden.log" # optional, always JSON

Override with RUST_LOG env var for module-level filtering:

RUST_LOG=warden=debug,pcap=warn sudo warden -i en0

CLI Reference

warden [OPTIONS]

Options:
  -c, --config <PATH>              Config file [default: config.yaml]
  -i, --interface <NAME>           Network interface
  -f, --bpf-filter <EXPR>          BPF filter (e.g., "tcp port 80")
  -v, --verbose                    Force DEBUG log level
      --dry-run                    Log actions without executing them
      --list-interfaces            List network interfaces and exit
      --validate                   Validate config and exit
      --stats-interval <N>         Stats reporting interval [default: 10000]
      --monitor                    Live packet monitor mode
      --monitor-count <N>          Max packets in monitor mode [default: 0]
  -h, --help                       Print help
  -V, --version                    Print version

Project Structure

warden/
├── src/
│   ├── main.rs            # CLI, async pipeline orchestration
│   ├── net.rs             # Shared IpNet (CIDR matching)
│   ├── capture/mod.rs     # pcap packet capture
│   ├── parser/mod.rs      # Ethernet/IPv4/TCP/UDP frame parsing
│   ├── filter/mod.rs      # Compiled whitelist/blacklist
│   ├── rules/mod.rs       # Composable condition DSL engine
│   ├── actions/mod.rs     # Block/Log/Alert with dedup + rate limiting
│   ├── config/mod.rs      # YAML config loader + validation
│   └── logger/mod.rs      # Structured logging (stdout + file)
├── config.yaml
├── Cargo.toml
└── docs/
    └── DESIGN.md

How It Works

[Network Interface]
        |
  Capture Task (pcap, blocking thread)
        |
   mpsc channel (4096 buffer)
        |
  Processing Task (async)
        |
   Parse ──> Filter ──> Rules ──> Actions ──> Log
  1. Capture — pcap runs in a dedicated blocking thread, raw packets are sent over an async mpsc channel.
  2. Parse — zero-copy parsing of Ethernet + IPv4 + TCP/UDP headers. Non-IPv4 frames are counted and skipped.
  3. Filter — pre-compiled CIDR bitmasks for O(1) matching per entry. Whitelist hit = skip blacklist entirely.
  4. Rules — composable condition tree evaluated in priority order. First match wins.
  5. Actions — block (with dedup), log, or alert (with 60s rate limiting per rule+IP).

Running Tests

cargo test

License

MIT

Releases

No releases published

Packages

 
 
 

Contributors

Languages