[Feature Proposal] Native integration with Suricata (IDS/IPS) via Hestia Firewall CLI

Hi everyone,

I’ve been running a setup combining Suricata (IDS/IPS) with HestiaCP on a production host to inspect web traffic in real time and automatically mitigate attacks using Hestia’s native firewall mechanisms.

While Fail2ban works great for reactive log parsing (SSH, auth failures, etc.), Suricata takes server protection a step further by analyzing packet payloads in real time (L7 inspection, malicious user-agents, known web exploits, automated scanners).

The Idea:

Allow optional integration/installation of Suricata alongside HestiaCP.

Use Suricata’s eve.json alert output or an inline mechanism to trigger v-add-firewall-ban / IPSet dynamically.

Give administrators a unified view of blocked threat actors directly inside the HestiaCP Firewall Web UI.

Why it adds value:

Real-time mitigation: Stops active exploit attempts before they fill up Nginx/Apache error logs.

Native compatibility: Leverages Hestia’s existing IPSet and iptables chains without interfering with default firewall rules.

Low overhead: Running Suricata with standard rulesets (like Emerging Threats Open) provides strong baseline security for multi-tenant web hosts.

Has the team ever considered offering Suricata as an optional security service during installation, or providing an official hook/bridge between eve.json alerts and Hestia’s firewall CLI?

Would love to hear your thoughts on this!

Yes, it would be great if they implemented Suricata in Hestia.

I use it differently, with a different topology Suricata, but a WAF (ModSecurity-OWASP, Comodo-WAF, etc.) would also be welcome, or any integrated solution that updates alongside HestiaCP (meaning we wouldn’t have to create manual configurations that might break upon the next version update).

What solutions do others use, besides Cloudflare or CrowdSec?

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)

  1. 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)

  2. 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).

  1. 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.

  1. 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.

I agree, it would be great to include it in Hestia. The main problem is that Suricata doesn’t provide a repository with packages for the versions supported by Hestia (Debian 12 and 13, and Ubuntu 22.04, 24.04 and 26.04). This means we would have to use the packages provided by each distribution, but the versions differ across distributions, which is a big problem. We could also compile Suricata ourselves and provide the packages, but that would be a major headache.

Regarding ModSecurity, it’s the same situation. We would need to compile our own Nginx version with support for the ModSecurity connector and also compile the ModSecurity library, and honestly, I don’t think that’s going to happen.