Skip to content

Latest commit

 

History

History
176 lines (129 loc) · 4.8 KB

File metadata and controls

176 lines (129 loc) · 4.8 KB

zentinel-agent-denylist

IP and pattern-based blocking agent for Zentinel reverse proxy.

Features

  • Block requests by client IP address or CIDR range
  • Allow-list IPs and CIDR ranges that take precedence over deny rules (enables default-deny setups)
  • Block requests by URL path prefix
  • Block requests by User-Agent pattern
  • Real-time blocking with no restart required
  • Configurable via CLI or config file

Installation

Using Bundle (Recommended)

# Install just this agent
zentinel bundle install denylist

# Or install all bundled agents
zentinel bundle install

The bundle command downloads the correct binary for your platform and places it in the standard location. See the bundle documentation for details.

Using Cargo

zentinel-agent-denylist is not published on crates.io, so cargo install zentinel-agent-denylist does not work. Install straight from the repository instead:

cargo install --git https://github.com/zentinelproxy/zentinel-agent-denylist

This builds and installs the zentinel-denylist-agent binary.

Prebuilt Binaries

Each release ships binaries for linux-x86_64, linux-aarch64, and darwin-aarch64:

VERSION=0.3.0
PLATFORM=linux-x86_64   # or linux-aarch64, darwin-aarch64
curl -fsSL -o zentinel-denylist-agent.tar.gz \
  "https://github.com/zentinelproxy/zentinel-agent-denylist/releases/download/v${VERSION}/zentinel-denylist-agent-${VERSION}-${PLATFORM}.tar.gz"
tar -xzf zentinel-denylist-agent.tar.gz
sudo install -m 0755 zentinel-denylist-agent /usr/local/bin/

From Source

git clone https://github.com/zentinelproxy/zentinel-agent-denylist
cd zentinel-agent-denylist
cargo build --release

Usage

zentinel-denylist-agent --socket /var/run/zentinel/denylist.sock \
  --block-ips "192.168.1.100,10.0.0.1" \
  --block-paths "/admin,/wp-admin" \
  --block-user-agents "bot,scanner"

Command Line Options

Option Environment Variable Description Default
--socket AGENT_SOCKET Unix socket path /tmp/zentinel-denylist.sock
--block-ips - Comma-separated IPs or CIDR ranges to block -
--allow-ips - Comma-separated IPs or CIDR ranges to allow (take precedence over --block-ips) -
--block-paths - Comma-separated path prefixes to block -
--block-user-agents - Comma-separated User-Agent patterns to block -
--verbose RUST_LOG Enable verbose logging false

IP Matching Semantics

  • Entries may be plain addresses (192.168.1.100, 2001:db8::1) or CIDR ranges (192.168.0.0/24, 2001:db8::/32).
  • Allow entries are checked first: an IP matching any --allow-ips entry is never blocked by an IP rule, even if it also matches a --block-ips entry.
  • IPv4 and IPv6 are matched independently — 0.0.0.0/0 covers all of IPv4 only; add ::/0 to also cover IPv6.
  • Path and User-Agent deny rules are evaluated separately and are not bypassed by --allow-ips.

Configuration

Zentinel Proxy Configuration

Add to your Zentinel config.kdl:

agents {
    agent "denylist" {
        type "custom"
        transport "unix_socket" {
            path "/var/run/zentinel/denylist.sock"
        }
        events "request_headers"
        timeout-ms 10
        failure-mode "open"
    }
}

routes {
    route "all" {
        matches { path-prefix "/" }
        upstream "backend"
        agents "denylist"
    }
}

Response

When a request is blocked, the agent returns:

  • HTTP 403 Forbidden
  • Body with the block reason

Example Scenarios

Block known bad IPs

zentinel-denylist-agent \
  --block-ips "1.2.3.4,5.6.7.8,192.168.0.0/24"

Deny everything except an allowlist

Because allow entries take precedence over deny entries, a default-deny setup is a matter of blocking both address families entirely and allowing only the IPs or ranges that should get through:

zentinel-denylist-agent \
  --block-ips "0.0.0.0/0,::/0" \
  --allow-ips "203.0.113.10,198.51.100.0/24"

The same works through dynamic configuration pushed by the proxy (on_configure), using the keys block-ips and allow-ips:

{
  "block-ips": ["0.0.0.0/0", "::/0"],
  "allow-ips": ["203.0.113.10", "198.51.100.0/24"]
}

Block admin paths

zentinel-denylist-agent \
  --block-paths "/admin,/wp-admin,/.env,/.git"

Block malicious bots

zentinel-denylist-agent \
  --block-user-agents "sqlmap,nikto,nessus,acunetix"

Development

# Run with debug logging
RUST_LOG=debug cargo run -- --socket /tmp/test.sock --block-ips "127.0.0.1"

# Run tests
cargo test

License

Apache-2.0