IDS / IPS

AiFw ships an in-kernel intrusion detection / prevention engine that consumes three rule formats — Suricata-compatible, Sigma, and YARA — and runs in one of three modes: Disabled, IDS (alert-only), or IPS (inline drop). Behavioural AI detectors live alongside the rule engine and are opt-in. No Snort, no separate package install, no second daemon to babysit.

Quickstart

Open the Web UI and go to IDS → Settings. Pick a mode and an interface. Apply.

Mode Behaviour
Disabled Engine off, no inspection
IDS Inspect and log alerts; never block
IPS Inspect, alert, and drop matching packets inline

From the API:

curl -X PUT https://aifw.local/api/v1/ids/config \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "ids",
    "interfaces": ["em0"],
    "home_net": ["10.0.0.0/8", "192.168.0.0/16"],
    "external_net": ["!$HOME_NET"],
    "alert_retention_days": 30,
    "eve_log_enabled": true
  }'

curl -X POST https://aifw.local/api/v1/ids/reload \
  -H "Authorization: Bearer $TOKEN"

Rule formats

Suricata-compatible. The native format. AiFw parses Suricata 7.x syntax directly — alert, drop, pass, plus the usual content, pcre, flow, threshold, and metadata keywords. Existing Suricata rulesets drop in unchanged.

Sigma. YAML detection rules originally designed for log events. AiFw maps the detection section to network flow fields, so a Sigma rule that targets HTTP request URIs or DNS query names will fire on matching traffic. Sigma rules always alert — they never drop, regardless of mode.

YARA. Byte-pattern rules used for malware signatures. Useful inside reassembled HTTP / SMTP / FTP payloads. Run alongside Suricata rules in the same engine pass.

ET Open integration

The seed ruleset is ET Open from Emerging Threats:

https://rules.emergingthreats.net/open/suricata-7.0/emerging-all.rules

Auto-update runs every 24 hours by default (configurable per ruleset via update_interval_hours). The engine fetches, parses, diffs against the live set, and reloads in place — no daemon restart. ET Open is shipped disabled-by-default; flip enabled on the ruleset to turn it on.

Add additional rulesets (Abuse.ch, ET Pro, custom feeds) via POST /api/v1/ids/rulesets. Each ruleset gets its own URL, format (suricata / sigma / yara), enable flag, and update cadence.

AI threat detection

Status: opt-in / experimental. The aifw-ai crate is a work in progress, disabled by default, and not yet production-ready. The Threats page in the UI marks this as WIP. See the README for the current framing.

Five behavioural detectors run on flow features extracted from conntrack:

Detector Trigger heuristic
Port scan ≥ 15 unique destination ports with ≥ 60% failed connection ratio
DDoS / SYN flood > 100 SYNs with > 80% failure ratio, or sustained > 50 conn/sec
Brute force ≥ 10 connections to ≤ 5 ports with ≥ 70% failure ratio
C2 beacon ≥ 5 connections to ≤ 2 destinations with low duration variance and small payloads
DNS tunneling > 50 DNS queries with DNS / total connection ratio > 80%

Thresholds are tuneable per-detector at construction time. Detectors emit Threat records with a 0..1 score, evidence string, and per-metric breakdown that the API surfaces alongside Suricata alerts.

Alert management

Every match — rule-driven or AI-detected — lands in the alerts table with severity, signature, source / destination, payload excerpt, and timestamp.

curl https://aifw.local/api/v1/ids/alerts?limit=50 \
  -H "Authorization: Bearer $TOKEN"

curl -X PUT https://aifw.local/api/v1/ids/alerts/{id}/acknowledge \
  -H "Authorization: Bearer $TOKEN"

curl -X PUT https://aifw.local/api/v1/ids/alerts/{id}/classify \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"classification": "false_positive", "notes": "internal scanner"}'

Acknowledged alerts stay in the timeline for audit but drop out of the unread counter. Classification (true_positive, false_positive, benign) feeds back into UI filters.

Suppressions

Suppress noisy rules without disabling them. Three scopes:

  • By source IP — ignore matches originating from a given address.
  • By destination IP — ignore matches to a given address.
  • Per-rule — ignore a specific signature ID entirely.
curl -X POST https://aifw.local/api/v1/ids/suppressions \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rule_sid": 2008581, "src_ip": "10.0.5.42"}'

Suppressions are paginated: GET /api/v1/ids/suppressions?limit=50&offset=0.

API endpoints

Method Endpoint Description
GET /api/v1/ids/config Current engine config
PUT /api/v1/ids/config Update mode, interfaces, networks, retention
POST /api/v1/ids/reload Hot-reload rules without dropping flows
GET /api/v1/ids/stats Engine counters, packets, drops, memory
GET /api/v1/ids/alerts Paginated alert feed
DELETE /api/v1/ids/alerts Purge alerts (filtered)
GET /api/v1/ids/alerts/{id} One alert with full payload
PUT /api/v1/ids/alerts/{id}/acknowledge Mark as read
PUT /api/v1/ids/alerts/{id}/classify Set classification + notes
GET /api/v1/ids/alerts/buffer-stats Live alert ring-buffer stats
GET /api/v1/ids/rulesets List configured rulesets
POST /api/v1/ids/rulesets Add a new ruleset URL
PUT / DELETE /api/v1/ids/rulesets/{id} Update / remove a ruleset
GET /api/v1/ids/rules List parsed rules
GET /api/v1/ids/rules/search Full-text search rules
GET / PUT /api/v1/ids/rules/{id} Inspect or override a single rule
GET / POST /api/v1/ids/suppressions List / create suppressions
DELETE /api/v1/ids/suppressions/{id} Drop a suppression

See also

Last updated: