v2.2.0 Source Available Go Linux

From a single VPS
to Kubernetes —
one binary, zero overhead

Stream-based security event multiprocessing engine for any HTTP server — and far beyond

Eight behavioural detectors analyse every HTTP access log in real time and route confirmed attackers to any output — Fail2Ban, Cloudflare WAF, MikroTik RouterOS, or your own exec+JSON sink in any language. Bare-metal, Docker Compose, or Kubernetes DaemonSet.

↓ Install View on GitHub

Every request. Every threat. Any output.

nginx / Apache / Traefik / Caddy / HAProxy / LiteSpeed access.log
Profile (log format · field mapping · server type)
TailReader × N streams (inotify · logrotate-aware)
Parser (ngx_http_realip · CF-Connecting-IP · XFF chain)
Whitelist (IP · CIDR · UA · bot DNS verify)
Tracker (per-IP state · ring buffer · rate counters)
Scorer (8 detectors · linear decay)
threats.log / Named Channel Switch
Executor → Fail2Ban · Cloudflare WAF · MikroTik · nginx blocklist · exec+JSON
8
Behavioural detectors
3
Topologies · bare-metal · Docker · K8s
11
Verified bot families
5
Native outputs · Fail2Ban · CF WAF · MikroTik · nginx · exec+JSON
5
Architectures · amd64 · arm64 · arm · riscv64 · 386
~16 MB
Single binary · arm64 ready

Any server. Any proxy. Real attacker IP.

Six servers supported natively — nginx works without any config. Every other server enables with a single profile line. Works behind any proxy or Cloudflare — always scores the real attacker, never the CDN or load balancer.

6
Server profiles
1
Line of config
0
Regex to write
Zero config
nginx
default parser

nginx combined log format works out of the box — no profile needed.

One line
Apache
profile: "apache"

Standard CLF — no server-side changes required.

One line
Traefik
profile: "traefik"

Default access log (CLF) — no configuration needed.

One line
LiteSpeed / OpenLiteSpeed
profile: "litespeed"

Apache CLF by default — no server-side changes required.

Plugin
Caddy
profile: "caddy"

Requires xcaddy + transform-encoder plugin for CLF output.

rsyslog
HAProxy
profile: "haproxy-http"

Requires option httplog in haproxy.cfg + rsyslog to write to file.

Behind a proxy? Real IP always reaches the detector.
Cloudflare
Traefik · Caddy · HAProxy · nginx
your server
ArxSentinel
XFF chain unwrapped CF-Connecting-IP ngx_http_realip trusted proxy CIDR real attacker · always

8 detectors, one score

Each detector adds points to an IP's score. Score decays linearly over the observation window — no false bans from old traffic.

Probe

Requests to sensitive paths: /.env, /.git/config, /.aws/credentials, /wp-config.php, /phpinfo.php, admin panels, backup archives and 30+ others. Active reconnaissance attempts trigger immediately on the first request.

+25 per request

Rate anomaly

More than 100 requests per 60 seconds from a single IP. Catches DDoS probes, aggressive vulnerability scanners, credential stuffing bursts and scraping tools trying to stay under static limits.

+25

Suspicious User-Agent

Case-insensitive substring match against built-in lists: scanners (Nuclei, sqlmap...), grabbers (Scrapy, HTTrack...) and automation clients (python-requests, curl...). Extend via config easily.

+15 to +40

Bruteforce

More than 60% of responses are 404 with at least 10 requests. Typical signature of path-enumeration tools (dirbuster, gobuster, ffuf) blindly traversing wordlists. min_requests prevents false positives.

+30

Sequential crawler

Five or more sequentially numbered URLs in a row — /page/1, /page/2, /article/100... Characteristic of automated content scrapers dumping entire site sections at machine speed.

+20

No-asset bot

Loads pages but requests CSS, JS or images on fewer than 10% of hits — with at least 3 page views. Real browsers fetch resources; markup-only scrapers skip static assets entirely.

+20

URL overflow / WAF bypass

URLs longer than 2048 characters, or containing known WAF evasion keywords: bypass, shell, cmd, eval, exec... Targets buffer overflows and code injections.

+30

Bad Bot Blocklist

Matches User-Agent (and optionally Referer) against a community-maintained blocklist of ~685 known bad bots — scrapers, SEO crawlers, spam bots, vulnerability probes. Updated daily. Powered by nginx-ultimate-bad-bot-blocker by Mitchell Krog.

+60

~16 MB. Runs anywhere.

~16 MB
Binary size · arm64
~25 MB
RAM · Pi 3B config
>20k
Log lines/sec · Pi 3B
0
Runtime dependencies
Enterprise threats.
Even on Raspberry Pi hardware.
Pure Go binary — no JVM, no Python runtime, no memory bloat. Runs natively on Raspberry Pi 3B (ARM Cortex-A53): ~25 MB RAM, 22k+ log lines/sec — 20× faster than any real Pi workload.

No black box. Deterministic scoring — every ban has a reason you can read in structured JSON logs.
YAML config SIGHUP reload JSON logs Prometheus metrics arm64 native Raspberry Pi 3B ready systemd unit

Install in 3 steps

The package handles everything: binary, systemd unit, Fail2Ban config, and system user.

# Works on Debian, Ubuntu, Fedora, RHEL, AlmaLinux, Rocky Linux, Arch Linux
# Auto-detects your distro and architecture (amd64 / arm64)
curl -fsSL https://raw.githubusercontent.com/mr-addams/arxsentinel/main/scripts/get.sh | sudo bash

The script downloads the correct package from GitHub Releases, installs it with your package manager, checks for fail2ban, auto-detects your access.log path, and starts the service.

# Requires Go 1.26+
git clone https://github.com/mr-addams/arxsentinel
cd arxsentinel
sudo ./scripts/install.sh
sudo systemctl enable --now arxsentinel
# Docker — distroless image (~12 MB), runs as uid 65532, amd64 + arm64
docker run -d \
  -v /var/log/nginx/access.log:/var/log/nginx/access.log:ro \
  -v /var/log/arxsentinel:/var/log/arxsentinel \
  -p 127.0.0.1:9117:9117 \
  ghcr.io/mr-addams/arxsentinel:latest

Prometheus metrics available at :9117/metrics immediately after start. For Docker Compose and Kubernetes (Helm DaemonSet) setup — see the full guides: README.docker.md · Kubernetes (Helm) README

After installation: open /etc/arxsentinel/config.yaml and set your log path. nginx works without any profile. For Apache, Traefik, Caddy, HAProxy or LiteSpeed — set parser.profile to the server name. Config reloads on SIGHUP — no restart needed.

Ban at the layer that fits your stack

Cloudflare WAF

Add threat IPs to a Cloudflare IP List and ban them at the network edge — no iptables, no host firewall. Batch operations, async polling, automatic TTL expiry and cross-instance dedup.

nginx

Write banned IPs to a plain blocklist file with TTL auto-expiry and atomic writes. arxsentinel only writes the file; you include it into nginx however suits you. Optional reload command.

MikroTik RouterOS v7

Manage a RouterOS firewall address-list over the REST API. TTL-based auto-unban, safe removal of only arxsentinel-owned entries, works on CHR and ARM-based routers.

One process. Any topology.

Custom log format

Not using a built-in profile? Define your own regex with named capture groups, or switch to JSON log parsing — both work without recompilation. Any format that captures IP, timestamp, method, path, status and bytes maps to the full detection pipeline.

Multi-stream & pipeline routing

Watch multiple log files in one process. Within each stream, define independent pipelines — each with its own detectors, sources, sinks and IP state. Share IP state between pipelines via tracker_group for correlated multi-log analysis.

Server profiles

Ship-ready profiles for popular servers. Override field positions, date formats and delimiter rules per log source without touching core logic.

Docker Compose sidecar

Deploy alongside any containerised HTTP server via a shared log volume — no changes to your app container. Ready-to-use docker-compose.yml and config in deploy/examples/docker/. Prometheus metrics exposed on :9117 for scraping.

Kubernetes DaemonSet

One pod per node reads host access logs via hostPath. Helm chart included with values reference and Prometheus Operator integration. Sidecar topology also supported for managed clusters without host log access.

Offline config validation

Run `arxsentinel validate` to check your whole config before deploy. A topology-aware validator models the real data flow and catches broken wiring using static plugin manifests — no live traffic needed.

Pluggable queue backends

Buffer executor events through an in-memory, file-based (bbolt) or Redis queue — pick per executor to fit bare-metal, single-host or multi-replica Kubernetes setups.

Named Channel Switch

Route threat events between independent pipelines by name — one pipeline can detect while another enforces, fully decoupled.

Legitimate traffic is never banned

Automatic verification

Googlebot, Bingbot, Yandex, DuckDuckBot, GPTBot and 6 others are verified via reverse + forward DNS. Legitimate crawlers are never scored. Fakes get a penalty instead. Trusted crawlers can be matched by User-Agent only (`ua_only`, no DNS) and given per-bot detector exemptions (`exempt_detectors`) so legitimate automation is never penalised.

Custom exclusions

Add your office IPs, VPN subnets (CIDR), monitoring services, SEO tools by User-Agent substring, or URL paths. Changes apply instantly on SIGHUP.

Live reload

All config changes — whitelist, detector scores, thresholds — apply instantly on SIGHUP. No restart. IP state and DNS cache are preserved.

Cloudflare support

Detectors always score the real attacker — never Cloudflare or your load balancer. Supports CF-Connecting-IP, X-Forwarded-For chains, and trusted proxy CIDR ranges out of the box.

Works with your stack

Read from any log source. Write threats to any destination. Fail2Ban remains the default — now one option among many.

Inputs

nginx Apache Traefik Caddy HAProxy LiteSpeed any log file stdin pipe syslog receiver HTTP (push/pull)

Outputs

Fail2Ban Cloudflare WAF MikroTik RouterOS nginx blocklist exec+JSON stdout JSON Grafana Loki (soon) Splunk HEC (soon) Datadog (soon) Telegram (soon)
type: file  ·  path: /var/log/nginx/access.log type: syslog  ·  addr: udp://0.0.0.0:5514  ·  no shared volume type: http  ·  protocol: plain|cloudflare|firehose|pubsub|loki|otlp|azure|splunk|ndjson

What's coming in v2.x

NEXT

Alert sinks

Push threats to Telegram, Slack and PagerDuty — with built-in deduplication and rate-limiting so a burst never floods your channel.

PLANNED

AWS WAF executor

Push threat IPs directly into AWS WAF IP set rules. Integrates with existing WAF rule groups — no Lambda or custom infrastructure required.