Skip to content

evertramos/ezy-shield

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

CI CodeQL Go 1.24+ License: AGPL-3.0

EzyShield

Intrusion blocking for Linux servers β€” fail2ban, a decade later.

EzyShield watches your server logs, detects attacking IPs, and bans them with escalating penalties: locally via nftables and at the edge via Cloudflare. A deterministic rule engine scores every event offline and always works; AI is consulted only for the ambiguous cases, so decisions stay cheap and the tool runs fully offline if you never configure a provider. It ships as a single static Go binary β€” no Python, no Java, no runtime to install.

Status: pre-alpha. The pipeline, rule engine, nftables + Cloudflare enforcement, AI providers, and notifiers work today. Run in dry-run (the default) and please report bugs via issues. Interfaces may still change before 1.0.


Why EzyShield

fail2ban EzyShield
Bans local firewall, per-jail bantime strike-based escalation + local and edge (Cloudflare)
Detection regex filters rule engine + signatures, optional AI for ambiguous traffic
Lockout safety manual ignoreip anti-lockout: your SSH session + admin CIDRs auto-allowlisted before every rule write
Default behavior enforces immediately dry-run by default β€” observe before you arm it
Runtime Python single static binary, no dependencies

fail2ban is battle-tested and great at what it does β€” EzyShield aims one layer higher: escalation, edge enforcement, AI-assisted scoring, and guardrails that make it hard to ban yourself. You can even run EzyShield as the brain and keep fail2ban for enforcement.


How it works

logs (SSH, Nginx)
        β”‚
        β–Ό
   [ Collector ]   ── tail file / journald
        β”‚
        β–Ό
    [ Parser ]     ── structured event (IP, method, status, ...)
        β”‚
        β–Ό
   [ Enricher ]    ── GeoIP / ASN / reputation
        β”‚
        β–Ό
  [ Rule Engine ]  ── offline scoring (always runs)
        β”‚
        β”œβ”€β”€(ambiguous only)──▢ [ AI Analyzer ] ── Anthropic / OpenAI-compatible / Ollama
        β”‚
        β–Ό
 [ Decision Engine ] ── strikes + TTL escalation + policy
        β”‚
        β”œβ”€β”€β–Ά [ Enforcer ] ── nftables (local) / Cloudflare (edge)
        └──▢ [ Notifier ] ── Telegram / Email / Slack / Discord / webhook

The whole path from parser to decision is side-effect-free and tested against fixture logs. Firewall changes only happen through a small privilege-separated helper (ezyshield-enforcer) that holds CAP_NET_ADMIN and accepts a fixed, minimal verb set β€” the main daemon can never run arbitrary firewall commands.

Strike escalation (configurable)

Strike Ban duration
1 5 minutes
2 1 hour
3 24 hours
4 7 days
5 permanent

Strike history is kept forever in SQLite, so a repeat offender from last month still escalates today.


Features (today)

  • Escalating bans β€” short first ban, permanent after repeated offences
  • Local enforcement β€” nftables, via a privilege-separated enforcer helper
  • Edge enforcement β€” push IP bans to a Cloudflare list
  • SSH + Nginx parsers with fuzz-tested, panic-safe parsing of hostile input
  • Deterministic rule engine β€” thresholds + scanner signatures; works with zero AI configured
  • AI-assisted decisions (optional) β€” Anthropic, any OpenAI-compatible endpoint, or local Ollama, with provider failover, a token budget, and verdict caching
  • Prompt-injection defense β€” log lines are treated as data, never instructions; AI output is schema-validated and clamped by policy (it can only suggest within limits)
  • Anti-lockout β€” active SSH peer + admin CIDRs auto-allowlisted before any rule write; allowlist always wins
  • Dry-run by default β€” nothing is enforced until you set armed: true
  • Ban rate limit β€” max_bans_per_minute (default 30) so a bad rule or poisoned feed can't ban the internet
  • Notifications β€” Telegram, Email (SMTP), Slack, Discord, generic webhook
  • Service & port discovery β€” ezyshield scan inventories what's actually listening on the host
  • Audit trail β€” every action recorded in SQLite; export to JSON/CSV
  • Scriptable β€” --json on commands; unix-socket control, no TCP port ever

Install

From a release (when available)

curl -sfL https://get.ezyshield.com | sudo sh

The installer fetches the latest signed binaries (ezyshield and ezyshield-enforcer) and verifies checksums.

From source (works today)

git clone https://github.com/evertramos/ezy-shield.git
cd ezy-shield
go build -o ezyshield ./cmd/ezyshield
go build -o ezyshield-enforcer ./cmd/ezyshield-enforcer
sudo mv ezyshield ezyshield-enforcer /usr/local/bin/

Requires Go 1.24+ and Linux with nftables for local enforcement.

Then:

sudo ezyshield init      # create config under /etc/ezyshield
sudo ezyshield doctor    # validate config, permissions, and dependencies

Naming: the binary is ezyshield and behaves exactly as ezy shield would in the wider ezy tool family β€” ezyshield init ≑ ezy shield init.


Basic usage

# Run the pipeline (dry-run until you set armed: true in policy.yaml)
sudo ezyshield watch

# Inspect the running daemon
ezyshield status

# Manual ban / unban
sudo ezyshield ban 203.0.113.42
sudo ezyshield unban 203.0.113.42

# Permanently allow an IP or CIDR
sudo ezyshield allow 198.51.100.0/24

# See active bans / allowlist / recent events
ezyshield list

# Test a notification channel without waiting for a real event
sudo ezyshield test-notify telegram

# See what's listening on this host
sudo ezyshield scan

Configuration

File Purpose
/etc/ezyshield/config.yaml Log sources, enforcement backends, AI providers, notifications
/etc/ezyshield/policy.yaml Score thresholds, strike table, allowlists, rate limits
/etc/ezyshield/rules.yaml Detection rules

Secrets (API tokens, SMTP passwords) are never stored in YAML β€” reference them as env:VARNAME or via systemd LoadCredential=. Inline secret values are rejected when the config loads, and ezyshield doctor warns on bad file permissions.

Minimal config.yaml:

data_dir: /var/lib/ezyshield

collectors:
  - kind: journald
    unit: sshd
  - kind: file
    path: /var/log/nginx/access.log

enforce:
  nftables:
    table: inet ezyshield
    set: blocked

notify:
  telegram:
    bot_token: env:EZYSHIELD_TELEGRAM_BOT_TOKEN
    chat_ids: ["-1001234567890"]

Start in dry-run (armed: false in policy.yaml), watch what it would block, then arm it. The full setup walkthrough β€” collectors, AI, notifications, custom rules β€” is in docs/QUICKSTART.md.


Roadmap

Built today: SSH/Nginx detection, rule engine, nftables bans, Cloudflare edge (IP lists), Anthropic/OpenAI/Ollama providers, Telegram/Email/Slack/Discord/ webhook notifications, dry-run, anti-lockout, audit log.

Planned (not yet shipped β€” see issues):

  • More edge backends: Bunny, AWS WAF; ASN- and country-level blocking
  • More local backends: iptables, ufw, firewalld
  • More log sources: Apache, Caddy, Traefik, container logs
  • Localhost-only dashboard (SSH-tunneled, like kubectl proxy)
  • Community module/plugin system
  • Host sensor: reverse-shell and egress-anomaly detection
  • Reputation feeds, more notifiers (ntfy, Pushover, WhatsApp/SMS)

Security

EzyShield is a root-capable security daemon and is built accordingly: privilege separation for firewall writes, unix-socket control (no listening TCP port), a localhost-only dashboard plan, anti-lockout, action rate limiting, and secrets kept out of config and logs. Every change goes through a mandatory security review.

Found a vulnerability? Please follow SECURITY.md β€” do not open a public issue for security reports.


Contributing

Contributions are welcome. Read CONTRIBUTING.md first; a CLA is required. Every PR ships code + tests + doc updates together, and CI (lint, tests, CodeQL, fuzz, security gates) must be green to merge.


❀️ Sponsors

EzyShield is free and open source, and always will be (AGPL-3.0). If it keeps your servers safer, consider sponsoring β€” it funds focused time to build this in the open, independently.

β†’ Become a sponsor


License

EzyShield is released under AGPL-3.0 β€” see LICENSE.

About

πŸ›‘οΈAI-assisted fail2ban alternative for Linux. Detects attacking IPs in your logs and bans them with escalating strikes β€” locally via nftables and at the Cloudflare edge. Dry-run by default. Self-hosted, AGPL-3.0.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Contributors

Languages