$ Normal: z > 3.0 OR rate > 5 × mean → anomaly
Error surge: z > 2.0 OR rate > 3 × mean → anomaly (tighter)
Normal: z > 3.0 OR rate > 5 × mean → anomaly
Error surge: z > 2.0 OR rate > 3 × mean → anomaly (tighter)
Normal: z > 3.0 OR rate > 5 × mean → anomaly
Error surge: z > 2.0 OR rate > 3 × mean → anomaly (tighter)
-weight: 500;">git clone https://github.com/Trojanhorse7/hng-anomaly-detector
cd hng-anomaly-detector
cp .env.example .env
# Set SLACK_WEBHOOK_URL in .env
-weight: 500;">docker compose build && -weight: 500;">docker compose up -d
-weight: 500;">git clone https://github.com/Trojanhorse7/hng-anomaly-detector
cd hng-anomaly-detector
cp .env.example .env
# Set SLACK_WEBHOOK_URL in .env
-weight: 500;">docker compose build && -weight: 500;">docker compose up -d
-weight: 500;">git clone https://github.com/Trojanhorse7/hng-anomaly-detector
cd hng-anomaly-detector
cp .env.example .env
# Set SLACK_WEBHOOK_URL in .env
-weight: 500;">docker compose build && -weight: 500;">docker compose up -d - Nextcloud — the upstream kefaslungu/hng-nextcloud image, unmodified.
- Nginx — reverse proxy in front of Nextcloud, configured to write JSON-formatted access logs (not the default combined format). This is critical — structured logs let the detector parse fields reliably instead of regex-guessing.
- Detector — a Python 3.12 container that tails the shared log volume, runs the detection logic, calls Slack, and executes iptables commands on the host.
- Shared volume — a named Docker volume (HNG-nginx-logs) that Nginx writes to and the detector reads from. - effective_mean — average requests per second
- effective_std — standard deviation of per-second counts - Z-score > threshold (default 3.0) — the current rate is more than 3 standard deviations above the baseline mean
- Rate > multiplier × baseline mean (default 5×) — the current rate is more than 5 times the average - Adds an iptables -I INPUT -s <IP> -j DROP rule — the IP is immediately blocked at the kernel level, before Nginx even sees the packets.
- Sends a Slack notification with the IP, the detection condition (z-score or rate multiplier), the current rate, and the baseline stats.
- Writes a structured audit log entry with all the same details plus the ban duration. - BASELINE_RECALC — every 60 seconds, with source (hourly vs full), mean, std
- BAN — IP, condition, rate, baseline stats, duration
- UNBAN — IP, reason, historical ban count - Uptime, event count, CPU/memory
- Current global RPS and baseline effective_mean / effective_std
- List of currently banned IPs with tier info
- Top 10 source IPs by request count in the current window - Per-IP baselines — currently all IPs are compared against the global baseline. High-traffic legitimate IPs (like a CDN edge) could benefit from their own rolling stats.
- HTTPS on the dashboard — right now it's plain HTTP on 8080. A reverse proxy with TLS would be better for production.
- Prometheus/Grafana — the audit log works, but a proper time-series database would make baseline visualization trivial.
- IPv6 — the current implementation only handles IPv4 in iptables rules.