ESC
> PressHaven alpha
Home › Docs ›Detection › Suricata Network IDS

Suricata Network IDS

Network-based detection using Suricata intrusion detection system

Overview

Suricata rules are specifically designed to detect attack patterns targeting the WordPress honeypot, organized by CVE and OWASP WSTG categories. SIDs range from 1000001 to 1000070+. The individual signatures, with their scores and provenance, are catalogued alongside every other rule on the Pattern Database page, which is generated from the same patterns/patterns.json the dashboard uses.

Passive Network evidence Signatures see what the application layer cannot: scanners, payloads split across requests and protocol-level abuse. eve.json alerts
Scoring Severity-graded Alert severity maps to a deterministic delta, capped at 100 and never reducing an existing score. +10 / +25 / +50
Hygiene Private IP filter RFC1918 and loopback sources are discarded at ingestion so container hops never poison reputation. is_private_ip()

Rule Anatomy

Rules are grouped by the WSTG category they exercise. A rule carries a stable SID, a severity, and a signature that becomes the human-readable reason string when an alert fires.

alert http any any -> $HOME_NET any (
  msg:"HONEYPOT CVE-2023-28121 WooCommerce Payments auth bypass";
  flow:to_server,established;
  http.uri; content:"/wp-json/wp/v2/users";
  http.header; content:"X-WCPAY-PLATFORM-CHECKOUT-USER";
  classtype:attempted-admin;
  sid:1000001; rev:1;
)
  • msg becomes suricata: <signature> in the stored reason.
  • severity determines the score delta; the rule metadata stays human-auditable.
  • sid is allocated from the project range and never reused after publication.

OWASP WSTG Category Index

  • WSTG-INFO – Information Gathering (SIDs 1000017-1000020, 1000049)
  • WSTG-CONF – Configuration Management (SIDs 1000019-1000020)
  • WSTG-IDNT – Identity Management (SID 1000018)
  • WSTG-ATHN – Authentication Testing (SID 1000017)
  • WSTG-AUTHZ – Authorization / Access Control (SIDs 1000001-1000008)
  • WSTG-INPV – Input Validation (SIDs 1000011-1000016, 1000026-1000041)
  • WSTG-SESS – Session Management (SID 1000017)

SID Allocation Summary

RangePurpose
1000001-1000016CVE-specific detection rules
1000017-1000025General WordPress attack patterns + plugin detection
1000026-1000029SQL injection generic patterns (WSTG-INPV-05)
1000030-1000032XSS patterns (WSTG-INPV-02)
1000033-1000035Command injection (WSTG-INPV-12)
1000036-1000038Directory traversal (WSTG-INPV-01)
1000039-1000041File inclusion wrappers (WSTG-INPV-11)
1000042-1000048Malicious user-agent strings (WSTG-INFO-02)
1000049-1000052Scanning and reconnaissance probes
1000053-1000055Suspicious file uploads
1000056-1000057Rate limiting and DoS detection
1000058-1000060Honeypot specific rules
1000061-1000063Session management integration
1000064-1000066Zero-day and generic attack patterns
1000067-1000068API abuse detection
1000069-1000070Custom malware and backdoor detection

Suricata Integration Details

suricata_rules.lua holds the pure, testable pieces of the Suricata alert pipeline. It parses one eve.json line into an alert record (or nil for non-alert event types — flow, netflow, http, dns, tls) and turns an alert into a risk-score delta and human-readable reason string.

FunctionPurpose
is_alert_line(line)Cheap pre-check — substring search for "event_type":"alert" to skip full JSON decode
extract_alert(decoded)Extracts alert record from decoded eve.json. Returns nil for non-alert or malformed events.
severity_to_score(severity)Maps Suricata severity (1=high → +50, 2=medium → +25, default → +10)
next_score(prev, severity)Applies delta to running score, capped at 100. Never decreases on its own.
decayed_score(entry, time, half_life, cfg)Time-decayed view of stored raw_score. Escalation-aware: repeat offenders decay slower; permaflagged never decay.
build_reason(alert)Builds "suricata: " + alert.signature
is_private_ip(ip)Filters RFC1918/loopback so container-internal hops never pollute threat_ips

init_worker.lua runs the reader every 30 seconds in worker 0 and stores the results as one JSON value under the threat_ips Redis key, mirrored into the threat_intel shared dict; scores are decayed when read, using the shared escalation-aware decay. Resume position and per-cycle limits are on Lua Internals.

Known Caveats

  • Same-host (loopback) testing: Suricata runs with network_mode: host and interface "any", so it sees every hop. In same-host test setups, Suricata's src_ip may be a container-internal address that never correlates with nginx's remote_addr. Stage 6 IP reputation gating never fires locally from Suricata alerts. For genuine external traffic, Docker DNAT-based port publishing preserves source IP.
  • Private IP filtering: is_private_ip() filters RFC1918/loopback src_ip values at ingestion time.
  • fast.log vs eve.json: Previous fast.log regex parser had 8 capture groups into 7 variables — Lua silently drops excess, shifting all fields. Now uses structured eve.json.