Hi @ghoste — fully agree. A WAF layer (ModSecurity/OWASP, Comodo, etc.) or an IDS/IPS bridge that survives Hestia upgrades would be a huge
win. We’ve been running exactly this kind of integration in production for a few months, so I wanted to share how we wired it today and what
a native Hestia integration could look like.
────────────────────────────────────────
Our topology (simplified)
Internet → edge router/NAT → Hestia host (multi-tenant web/mail)
↓
Suricata (IDS, af-packet on public NIC)
↓
fast.log / eve.json
↓
Fail2ban (custom Suricata jails)
↓
Hestia action: v-add-firewall-ban → IPSet/iptables (WEB chain)
↓
Visible in HestiaCP → Firewall → Banned IPs
Suricata runs on the same host as Hestia (not inside a random container), inspecting traffic destined to the public IP(s) of the panel/web
stack. Alerts are exported to Wazuh/SIEM separately via eve-alerts.json; enforcement stays local via Hestia’s firewall CLI.
────────────────────────────────────────
What we implemented (works today, no Hestia core patches)
-
Suricata (IDS mode)
• Suricata 8.0.6, af-packet capture on the public interface
• Rules: bundled suricata.rules (ET-style community ruleset)
• Outputs:
• eve.json — full telemetry
• eve-alerts.json — alert-only stream (forwarded to Wazuh)
• fast.log — human-readable alerts (this is what we ban from)
-
Fail2ban as the “bridge” (key design choice)
Hestia already ships a native Fail2ban action:
/etc/fail2ban/action.d/hestia.conf
actionban = /usr/local/hestia/bin/v-add-firewall-ban
actionunban = /usr/local/hestia/bin/v-delete-firewall-ban
So instead of writing a custom eve.json tailer, we added two jails that parse fast.log by Suricata priority:
/etc/fail2ban/filter.d/suricata-critical.conf
failregex = ^.[Priority: 1].{(?:TCP|UDP|ICMP|ICMPv6)} (?::\d+)? → (?:OUR_PUBLIC_IP|OUR_LAN_IP)(?::\d+)?$
/etc/fail2ban/filter.d/suricata-high.conf
failregex = ^.[Priority: 2].{(?:TCP|UDP|ICMP|ICMPv6)} (?::\d+)? → (?:OUR_PUBLIC_IP|OUR_LAN_IP)(?::\d+)?$
Jail config (excerpt):
[suricata-critical]
enabled = true
filter = suricata-critical
logpath = /var/log/suricata/fast.log
maxretry = 1
findtime = 5m
bantime = 24h
bantime.increment = true
bantime.maxtime = 7d
action = hestia[name=WEB]
ignoreip = 127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 <admin_ips> <cf_ranges>
[suricata-high]
enabled = true
filter = suricata-high
logpath = /var/log/suricata/fast.log
maxretry = 2
findtime = 5m
action = hestia[name=WEB]
Result: banned IPs land in Hestia’s WEB chain and show up in the panel (v-list-firewall-ban). In our environment we currently have ~58
active bans sourced from Suricata alerts (scanners, exploit probes, aggressive crawlers).
- Why Fail2ban instead of direct eve.json → v-add-firewall-ban?
• Reuses Hestia’s existing, supported enforcement path
• Built-in rate limiting (maxretry, findtime, escalating bantime)
• Easy ignoreip for admin IPs, monitoring, CDN ranges
• Survives Hestia upgrades better than patching core
• fast.log regex is simpler and cheaper than JSON streaming at high volume
Direct eve.json integration is still valid for richer metadata (rule SID, signature name, HTTP host, etc.) — we use that path for SIEM, not
for blocking.
- Ops lessons (important for multi-tenant hosts)
• eve.json grows fast — we added aggressive logrotate (size 200M, rotate 2, copytruncate) after it reached 62 GB on a busy host
• Forward eve-alerts.json to Wazuh/SIEM; keep full eve.json local with retention
• Tune ignoreip carefully (CDN, office IPs, health checks)
• Start with Priority 1 only, then add Priority 2 after false-positive review
────────────────────────────────────────
What native Hestia integration could look like
Building on what already exists (hestia.conf Fail2ban action + firewall CLI), a first-class integration could be:
┌──────────────┬───────────────────────────────────────────────────────────────────────────┐
│ Layer │ Native Hestia feature │
├──────────────┼───────────────────────────────────────────────────────────────────────────┤
│ Install │ Optional v-add-sys-suricata or installer checkbox (“Enable Suricata IDS”) │
├──────────────┼───────────────────────────────────────────────────────────────────────────┤
│ Config │ UI toggle: IDS vs IPS, interface, HOME_NET auto-detect │
├──────────────┼───────────────────────────────────────────────────────────────────────────┤
│ Enforcement │ Ship official Fail2ban filters + jail templates (not manual edits) │
├──────────────┼───────────────────────────────────────────────────────────────────────────┤
│ Firewall UI │ Show ban source (suricata-critical, suricata-high, ssh, exim, …) │
├──────────────┼───────────────────────────────────────────────────────────────────────────┤
│ Tuning │ Panel fields: maxretry, bantime, ignoreip, severity threshold │
├──────────────┼───────────────────────────────────────────────────────────────────────────┤
│ Logs │ Built-in logrotate profile for /var/log/suricata/*.json │
├──────────────┼───────────────────────────────────────────────────────────────────────────┤
│ SIEM │ Optional template for Wazuh/OSSEC localfile on eve-alerts.json │
├──────────────┼───────────────────────────────────────────────────────────────────────────┤
│ WAF (future) │ ModSecurity/Nginx template per web domain — complementary to Suricata │
└──────────────┴───────────────────────────────────────────────────────────────────────────┘
Minimal viable native hook (no UI yet):
Already works today if Fail2ban jails are configured:
/usr/local/hestia/bin/v-add-firewall-ban WEB
/usr/local/hestia/bin/v-list-firewall-ban
A thin official wrapper could tail alerts and call the same CLI, with metadata stored for the panel.
────────────────────────────────────────
Compared to Cloudflare / CrowdSec
• Cloudflare: great edge WAF, but doesn’t replace origin-side L7 inspection of raw traffic hitting the server
• CrowdSec: excellent community blocklists + bouncer model — complementary; we still want local signature-based IDS for exploits Fail2ban
never sees in auth logs
• Suricata + Hestia firewall: real-time payload inspection and enforcement through the same IPSet chains Hestia already manages
────────────────────────────────────────
Bottom line
We proved the model works in production:
Suricata detects → Fail2ban decides → Hestia bans → panel shows it.
The missing piece isn’t the CLI (v-add-firewall-ban already does the job) — it’s packaging, UI, log retention defaults, and upgrade-safe
templates so admins don’t hand-craft configs that break on the next Hestia release.
Happy to share more details (filter tuning, false-positive handling, IPS vs IDS trade-offs) if the team wants to explore this as an optional
security module.