Free · open source · self-hosted

fail2ban is great at counting.
It can't read.

ai-watchdog is a small script that hands your Nginx logs to a language model every few minutes, and lets fail2ban-client act on what it finds — catching crafted exploit attempts and stealthy scanners that never trip a regex.

tail -f /var/log/ai-watchdog.log

The problem

Regex rules only catch what you already thought of

Static jails match known patterns in known places. A one-off, hand-crafted probe against an endpoint nobody's fingerprinted yet just looks like a 404 — until a model reads the whole request in context.

Regex-only jails

  • Match fixed strings and known bad user agents
  • Blind to novel or obfuscated payloads
  • Ban on rate, not on intent
  • No sense of "this looks like reconnaissance"

ai-watchdog + fail2ban

  • Reads flagged requests in context, not just as strings
  • Classifies BAN / IGNORE / UNBAN with a reason in the log
  • Sits on top of your existing jails — nothing to migrate
  • Enforcement still happens in nftables, at the kernel

Architecture

One more jail, driven by a model instead of a pattern file

The ai-watchdog fail2ban jail holds no filter and no regex — it exists only to hold the ban action. Everything upstream of it is where the actual thinking happens.

01
Read new Nginx log lines (inode + offset tracked — never re-reads)
02
Pre-filter for exploit signatures LFI / RCE / SQLi / SSRF / scanner UAs
03
Send candidate IPs to a hosted LLM rate-limited, temp=0, one-word answer
04
fail2ban-client bans / unbans this script never touches the firewall itself
05
nftables drops the traffic kernel-level, same as any other jail

What's inside

Small on purpose

One script, one timer, one jail. No dashboard, no database, no service to keep patched beyond what you already run.

[rate]

Sliding-window rate limiter

Every retry counts against the budget, so a backoff loop can't quietly blow through your provider's per-minute cap.

[timer]

systemd timer, not cron

A oneshot service on a 5-minute timer, with the log tailer tracking file offsets so restarts never reprocess old lines.

[hardened]

Locked-down service unit

NoNewPrivileges, ProtectSystem=strict — write access limited to its own state and log directories.

[report]

One status command

fail2ban-report.sh prints every active jail — not just this one — with bans, failure counts, and totals.

[portable]

Any OpenAI-compatible API

Ships pointed at a free-tier hosted model, but it's two constants away from any provider that speaks the chat completions format.

[honest]

Never writes firewall rules directly

Every ban goes through fail2ban-client. If you trust fail2ban already, you're not adding a new attack surface.

Install

Running in about 10 minutes

Full step-by-step instructions — jail config, systemd units, log rotation, and a verification checklist — are in the README. Here's the shape of it:

quickstart.sh
# 1. clone and place the script
$ git clone https://github.com/YOUR_GITHUB_USER/ai-watchdog.git && cd ai-watchdog
$ sudo cp watchdog.py /opt/ai-watchdog/
 
# 2. isolated venv + one dependency
$ sudo python3 -m venv /opt/ai-watchdog/venv
$ sudo /opt/ai-watchdog/venv/bin/pip install openai
 
# 3. drop in your API key, add the jail, enable the timer
$ sudo systemctl enable --now ai-watchdog.timer
Debian 13 / Ubuntu 24.04 LTS Python 3.10+ fail2ban + nftables OpenAI-compatible API key

If you outgrow the jail

Want to see what it's banning, not just watch the log scroll by?

ai-watchdog is deliberately headless — it's a jail, not a product. If you want a dashboard over the same Nginx traffic — trend charts, a top-adversary table, per-incident drill-down, and audit-ready reports — that's a different tool built for that job.

  • SOC 2 / NIST CSF–style reports, generated on demand
  • Top-adversary attribution and trend charts, not just log lines
  • Local Ollama or your choice of cloud model — nothing locked in
  • Copy-pasteable firewall commands — still never applied automatically
Look at the Report Agent ↗
DetectionSame log source
OutputDashboard + reports
EnforcementYou click "copy"
AI backendLocal or cloud, your choice

FAQ

Before you install it

Does this replace fail2ban?

No. It adds one more jail alongside whatever jails you already run. All of fail2ban's existing logic keeps working exactly as it does today.

Does it ever touch nftables or iptables directly?

No. Every ban and unban goes through fail2ban-client. If fail2ban is already something you trust with your firewall, this doesn't change that trust boundary.

What happens if the AI provider is unreachable?

Candidate IPs are logged and skipped for that cycle — nothing is banned or unbanned without a decision from the model. The script retries with backoff before giving up on a given sweep.

Does log data leave my server?

Flagged request lines are sent to whichever OpenAI-compatible API you configure. Review that provider's data-handling terms if your logs may contain sensitive request data.